this patch focuses on giving wagic a more defined turn structure.
This commit is contained in:
@@ -11,6 +11,7 @@ GamePhase PhaseRing::phaseStrToInt(string s)
|
||||
if (s.compare("upkeep") == 0) return MTG_PHASE_UPKEEP;
|
||||
if (s.compare("draw") == 0) return MTG_PHASE_DRAW;
|
||||
if (s.compare("firstmain") == 0) return MTG_PHASE_FIRSTMAIN;
|
||||
if (s.compare("mainphase") == 0) return MTG_PHASE_FIRSTMAIN;
|
||||
if (s.compare("combatbegin") == 0) return MTG_PHASE_COMBATBEGIN;
|
||||
if (s.compare("combatbegins") == 0) return MTG_PHASE_COMBATBEGIN;
|
||||
if (s.compare("combatattackers") == 0) return MTG_PHASE_COMBATATTACKERS;
|
||||
@@ -23,8 +24,25 @@ GamePhase PhaseRing::phaseStrToInt(string s)
|
||||
if (s.compare("end") == 0) return MTG_PHASE_ENDOFTURN;
|
||||
if (s.compare("cleanup") == 0) return MTG_PHASE_CLEANUP;
|
||||
DebugTrace("PHASERING: Unknown Phase name: " << s);
|
||||
return MTG_PHASE_INVALID;//was returning first main...why would we return something that is not == s?
|
||||
}
|
||||
|
||||
return MTG_PHASE_FIRSTMAIN;
|
||||
string PhaseRing::phaseIntToStr(int id)
|
||||
{
|
||||
if (id == MTG_PHASE_UNTAP) return "untap";
|
||||
if (id == MTG_PHASE_UPKEEP) return "upkeep";
|
||||
if (id == MTG_PHASE_DRAW) return "draw";
|
||||
if (id == MTG_PHASE_FIRSTMAIN) return "firstmain";
|
||||
if (id == MTG_PHASE_COMBATBEGIN) return "combatbegins";
|
||||
if (id == MTG_PHASE_COMBATATTACKERS) return "combatattackers";
|
||||
if (id == MTG_PHASE_COMBATBLOCKERS) return "combatblockers";
|
||||
if (id == MTG_PHASE_COMBATDAMAGE) return "combatdamage";
|
||||
if (id == MTG_PHASE_COMBATEND) return "combatends";
|
||||
if (id == MTG_PHASE_SECONDMAIN) return "secondmain";
|
||||
if (id == MTG_PHASE_ENDOFTURN) return "endofturn";
|
||||
if (id == MTG_PHASE_CLEANUP) return "cleanup";
|
||||
DebugTrace("PHASERING: Unknown Phase id:%i " << id);
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Creates a New phase ring with the default rules */
|
||||
@@ -33,6 +51,7 @@ PhaseRing::PhaseRing(GameObserver* observer)
|
||||
{
|
||||
for (int i = 0; i < observer->getPlayersNumber(); i++)
|
||||
{
|
||||
list<Phase*>turnRing;//this is temporary;
|
||||
if(observer->players[i]->phaseRing.size())
|
||||
{
|
||||
addPhase(NEW Phase(MTG_PHASE_BEFORE_BEGIN, observer->players[i]));
|
||||
@@ -42,8 +61,9 @@ PhaseRing::PhaseRing(GameObserver* observer)
|
||||
GamePhase customOrder = phaseStrToInt(customRing[k]);
|
||||
Phase * phase = NEW Phase(customOrder, observer->players[i]);
|
||||
addPhase(phase);
|
||||
turnRing.push_back(phase);
|
||||
}
|
||||
addPhase( NEW Phase(MTG_PHASE_AFTER_EOT, observer->players[i]));
|
||||
addPhase( NEW Phase(MTG_PHASE_AFTER_EOT, observer->players[i]));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -51,10 +71,42 @@ PhaseRing::PhaseRing(GameObserver* observer)
|
||||
{
|
||||
Phase * phase = NEW Phase((GamePhase)j, observer->players[i]);
|
||||
addPhase(phase);
|
||||
turnRing.push_back(phase);
|
||||
}
|
||||
}
|
||||
observer->gameTurn.push_back(turnRing);
|
||||
//push back the complete turn of a player for easy refference.
|
||||
//since they are pushed back per player you can denote that gameTurn[playerid] is the exact turn for that player.
|
||||
}
|
||||
current = ring.begin();
|
||||
turn = currentTurn();
|
||||
current = turn.begin();
|
||||
}
|
||||
|
||||
list<Phase*> PhaseRing::currentTurn()
|
||||
{
|
||||
list<Phase*> temp = observer->gameTurn[observer->currentPlayer->getId()];
|
||||
list<Phase *>::iterator tempiter;
|
||||
currentTurnList.clear();
|
||||
for (tempiter = temp.begin(); tempiter != temp.end(); tempiter++)
|
||||
{
|
||||
Phase * currentIter = *tempiter;
|
||||
currentTurnList.push_back(currentIter);
|
||||
}
|
||||
return currentTurnList;
|
||||
}
|
||||
|
||||
list<Phase*> PhaseRing::nextTurn()
|
||||
{
|
||||
list<Phase*> temp = observer->gameTurn[observer->nextTurnsPlayer()->getId()];
|
||||
list<Phase*>::iterator tempiter;
|
||||
Phase * currentIter = NULL;
|
||||
nextTurnList.clear();
|
||||
for (tempiter = temp.begin(); tempiter != temp.end(); tempiter++)
|
||||
{
|
||||
currentIter = *tempiter;
|
||||
nextTurnList.push_back(currentIter);
|
||||
}
|
||||
return nextTurnList;
|
||||
}
|
||||
|
||||
PhaseRing::~PhaseRing()
|
||||
@@ -65,6 +117,11 @@ PhaseRing::~PhaseRing()
|
||||
Phase * currentPhase = *it;
|
||||
delete (currentPhase);
|
||||
}
|
||||
for (it = extraPhases.begin();it != extraPhases.end();it++)
|
||||
{
|
||||
Phase * currentPhase = *it;
|
||||
SAFE_DELETE(currentPhase);
|
||||
}
|
||||
}
|
||||
|
||||
//Tells if next phase will be another Damage phase rather than combat ends
|
||||
@@ -93,9 +150,10 @@ const char * PhaseRing::phaseName(int id)
|
||||
|
||||
Phase * PhaseRing::getCurrentPhase()
|
||||
{
|
||||
if (current == ring.end())
|
||||
if (current == turn.end())
|
||||
{
|
||||
current = ring.begin();
|
||||
turn = nextTurn();
|
||||
current = turn.begin();
|
||||
}
|
||||
return *current;
|
||||
}
|
||||
@@ -103,28 +161,60 @@ Phase * PhaseRing::getCurrentPhase()
|
||||
Phase * PhaseRing::forward(bool sendEvents)
|
||||
{
|
||||
Phase * cPhaseOld = *current;
|
||||
if (current != ring.end()) current++;
|
||||
if (current == ring.end()) current = ring.begin();
|
||||
|
||||
//the following is a present event before change
|
||||
//if we need to remove a phase before it changes the game
|
||||
//needs to be aware of what phase we're coming from and going to
|
||||
//before we actually increment the phase iter. {
|
||||
bool notEnd = false;
|
||||
size_t turnSteps = turn.size();
|
||||
if (current != turn.end())
|
||||
{
|
||||
current++;
|
||||
if(current == turn.end())
|
||||
current--;
|
||||
else
|
||||
notEnd = true;
|
||||
}
|
||||
//Warn the layers about the current phase before changing
|
||||
WEvent * e = NEW WEventPhasePreChange(cPhaseOld,*current);
|
||||
observer->receiveEvent(e);
|
||||
if(notEnd)
|
||||
{
|
||||
current--;
|
||||
}
|
||||
size_t turnStepsNow = turn.size();
|
||||
if(turnSteps != turnStepsNow)
|
||||
return forward(sendEvents);
|
||||
if (current != turn.end())
|
||||
current++;
|
||||
if (current == turn.end())
|
||||
{
|
||||
turn = nextTurn();
|
||||
current = turn.begin();
|
||||
}
|
||||
if (sendEvents)
|
||||
{
|
||||
//Warn the layers about the phase Change
|
||||
WEvent * e = NEW WEventPhaseChange(cPhaseOld, *current);
|
||||
observer->receiveEvent(e);
|
||||
}
|
||||
|
||||
return *current;
|
||||
}
|
||||
|
||||
Phase * PhaseRing::goToPhase(int id, Player * player, bool sendEvents)
|
||||
{
|
||||
Phase * currentPhase = *current;
|
||||
while (currentPhase->id != id || currentPhase->player != player)
|
||||
Phase * currentPhase = getCurrentPhase();
|
||||
while (currentPhase->id != id)
|
||||
{ //Dangerous, risk for inifinte loop !
|
||||
|
||||
DebugTrace("PhasingRing: goToPhase called, current phase is " << phaseName(currentPhase->id));
|
||||
|
||||
currentPhase = forward(sendEvents);
|
||||
if(id == MTG_PHASE_INVALID)
|
||||
{
|
||||
DebugTrace("stopping on this phase becuase goToPhase was told to go a phase that doesn't exist:" << phaseName(currentPhase->id));
|
||||
break;
|
||||
}
|
||||
if(currentPhase->player == player && currentPhase->id == id)
|
||||
break;
|
||||
}
|
||||
return currentPhase;
|
||||
}
|
||||
@@ -135,41 +225,149 @@ int PhaseRing::addPhase(Phase * phase)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int PhaseRing::addPhaseBefore(GamePhase id, Player* player, int after_id, Player * after_player, int allOccurences)
|
||||
int PhaseRing::addCombatAfter(Player* player, int after_id, bool withMain)
|
||||
{
|
||||
int result = 0;
|
||||
list<Phase *>::iterator it;
|
||||
for (it = ring.begin(); it != ring.end(); it++)
|
||||
Phase * beforeLeaving;
|
||||
for (it = turn.begin(); it != turn.end(); it++)
|
||||
{
|
||||
Phase * currentPhase = *it;
|
||||
if (currentPhase->id == after_id && currentPhase->player == after_player)
|
||||
if (currentPhase->id == after_id)
|
||||
{
|
||||
result++;
|
||||
ring.insert(it, NEW Phase(id, player));
|
||||
if (!allOccurences) return 1;
|
||||
beforeLeaving = currentPhase;
|
||||
it++;
|
||||
Phase * addPhase = NULL;
|
||||
list<Phase *>::iterator findP;
|
||||
for(findP = ring.begin();findP != ring.end();findP++)
|
||||
{
|
||||
addPhase = *findP;
|
||||
Phase * toAdd = NULL;
|
||||
bool add = false;
|
||||
if(addPhase->player == player)
|
||||
{
|
||||
switch(addPhase->id)
|
||||
{
|
||||
case MTG_PHASE_COMBATEND:
|
||||
{
|
||||
toAdd = NEW Phase(*addPhase);
|
||||
toAdd->isExtra = true;
|
||||
turn.insert(it, toAdd);
|
||||
extraPhases.push_back(toAdd);
|
||||
observer->combatStep = BLOCKERS;
|
||||
if(withMain)
|
||||
{
|
||||
toAdd = NEW Phase(*getPhase(MTG_PHASE_SECONDMAIN));
|
||||
toAdd->isExtra = true;
|
||||
extraPhases.push_back(toAdd);
|
||||
turn.insert(it, toAdd);
|
||||
}
|
||||
Phase * check = getCurrentPhase();
|
||||
bool checking = false;
|
||||
if(check != beforeLeaving)
|
||||
checking = true;
|
||||
while(checking)
|
||||
{
|
||||
current--;//put us back to where we were.
|
||||
check = getCurrentPhase();
|
||||
if(check == beforeLeaving)
|
||||
{
|
||||
checking = false;
|
||||
current++; //now move to the next phase, which will be the added phases.
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case MTG_PHASE_COMBATDAMAGE:
|
||||
toAdd = NEW Phase(*addPhase);
|
||||
add = true;
|
||||
break;
|
||||
case MTG_PHASE_COMBATBLOCKERS:
|
||||
toAdd = NEW Phase(*addPhase);
|
||||
add = true;
|
||||
break;
|
||||
case MTG_PHASE_COMBATATTACKERS:
|
||||
toAdd = NEW Phase(*addPhase);
|
||||
add = true;
|
||||
break;
|
||||
case MTG_PHASE_COMBATBEGIN:
|
||||
toAdd = NEW Phase(*addPhase);
|
||||
add = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(add)
|
||||
{
|
||||
toAdd->isExtra = true;
|
||||
turn.insert(it, toAdd);
|
||||
extraPhases.push_back(toAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
int PhaseRing::removePhase(int id, Player * player, int allOccurences)
|
||||
|
||||
Phase * PhaseRing::getPhase(int _id)
|
||||
{
|
||||
int result = 0;
|
||||
list<Phase *>::iterator it = ring.begin();
|
||||
while (it != ring.end())
|
||||
list<Phase *>::iterator it;
|
||||
for (it = turn.begin(); it != turn.end(); it++)
|
||||
{
|
||||
Phase * currentPhase = *it;
|
||||
if (currentPhase->id == id && currentPhase->player == player)
|
||||
if (currentPhase->id == _id)
|
||||
{
|
||||
if (current == it) current++; //Avoid our cursor to get invalidated
|
||||
it = ring.erase(it);
|
||||
delete (currentPhase);
|
||||
result++;
|
||||
if (!allOccurences) return 1;
|
||||
return currentPhase;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int PhaseRing::addPhaseAfter(GamePhase id, Player* player, int after_id)
|
||||
{
|
||||
list<Phase *>::iterator it;
|
||||
for (it = turn.begin(); it != turn.end(); it++)
|
||||
{
|
||||
Phase * currentPhase = *it;
|
||||
if (currentPhase->id == after_id)
|
||||
{
|
||||
it++;
|
||||
Phase * addPhase = NULL;
|
||||
list<Phase *>::iterator findP;
|
||||
for(findP = ring.begin();findP != ring.end();findP++)
|
||||
{
|
||||
addPhase = *findP;
|
||||
if(addPhase->id == id && addPhase->player == player)
|
||||
{
|
||||
Phase * toAdd = NEW Phase(*addPhase);
|
||||
toAdd->isExtra = true;
|
||||
turn.insert(it, toAdd);
|
||||
extraPhases.push_back(toAdd);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PhaseRing::removePhase(int id)
|
||||
{
|
||||
list<Phase *>::iterator it = turn.begin();
|
||||
while (it != turn.end())
|
||||
{
|
||||
Phase * currentPhase = *it;
|
||||
if (currentPhase->id == id)
|
||||
{
|
||||
if (current == it)
|
||||
current++; //Avoid our cursor to get invalidated
|
||||
turn.erase(it);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user