this patch focuses on giving wagic a more defined turn structure.
This commit is contained in:
@@ -4796,72 +4796,159 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Stasis
|
//remove or add a phase.
|
||||||
class AStasis: public ActivatedAbility
|
class APhaseAlter: public TriggeredAbility
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int paidThisTurn;
|
Targetable * targetPlayerWho;
|
||||||
AStasis(GameObserver* observer, int _id, MTGCardInstance * card) :
|
bool adding;
|
||||||
ActivatedAbility(observer, _id, card, NEW ManaCost(), 0)
|
bool applied;
|
||||||
|
Player * who;
|
||||||
|
string phaseToAlter;
|
||||||
|
int phasetoAlter;
|
||||||
|
string targetingString;
|
||||||
|
string after;
|
||||||
|
bool aNext;
|
||||||
|
APhaseAlter(GameObserver* observer, int _id, MTGCardInstance * card,Targetable * targetPlayer, bool _adding,string _phaseToAlter,string targeting, bool _aNext,string _after = "") :
|
||||||
|
TriggeredAbility(observer, _id, card),targetPlayerWho(targetPlayer),adding(_adding),phaseToAlter(_phaseToAlter),targetingString(targeting),aNext(_aNext),after(_after)
|
||||||
{
|
{
|
||||||
paidThisTurn = 1;
|
applied = false;
|
||||||
getCost()->add(Constants::MTG_COLOR_BLUE, 1);
|
who = NULL;
|
||||||
|
phasetoAlter = PhaseRing::phaseStrToInt(phaseToAlter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Update(float dt)
|
int triggerOnEvent(WEvent * event)
|
||||||
{
|
|
||||||
//Upkeep Cost
|
|
||||||
if (newPhase != currentPhase)
|
|
||||||
{
|
{
|
||||||
if (newPhase == MTG_PHASE_UPKEEP)
|
if(!who)
|
||||||
{
|
{
|
||||||
paidThisTurn = 0;
|
Player * targetedPlayer = dynamic_cast<Player*>(target);
|
||||||
|
if (targetingString.find("targetedplayer") != string::npos && targetedPlayer)
|
||||||
|
{
|
||||||
|
who = targetedPlayer;
|
||||||
|
}
|
||||||
|
if (targetingString.find("controller") != string::npos)
|
||||||
|
who = source->controller();
|
||||||
|
if (targetingString.find("opponent") != string::npos)
|
||||||
|
who = source->controller()->opponent();
|
||||||
|
if (targetingString.find("targetcontroller") != string::npos)
|
||||||
|
who = source->target?source->target->controller():source->controller();
|
||||||
|
if (targetingString.find("owner") != string::npos)
|
||||||
|
who = source->owner;
|
||||||
}
|
}
|
||||||
else if (!paidThisTurn && newPhase > MTG_PHASE_UPKEEP && game->currentPlayer == source->controller())
|
|
||||||
|
if (after == "this")//apply it right now.
|
||||||
{
|
{
|
||||||
game->currentPlayer->game->putInGraveyard(source);
|
if(!applied)
|
||||||
paidThisTurn = 1;
|
if (who == game->currentPlayer)
|
||||||
|
{
|
||||||
|
after = game->phaseRing->phaseIntToStr(game->oldGamePhase);
|
||||||
|
addTheEffect(game->currentPlayer->getId());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//Stasis Effect
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
game->phaseRing->removePhase(MTG_PHASE_UNTAP, game->players[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Parent Class Method Call
|
if (WEventPhasePreChange* pe = dynamic_cast<WEventPhasePreChange*>(event))
|
||||||
ActivatedAbility::Update(dt);
|
{
|
||||||
}
|
if (MTG_PHASE_CLEANUP == pe->to->id)
|
||||||
|
{
|
||||||
int isReactingToClick(MTGCardInstance * card, ManaCost * mana = NULL)
|
if( aNext && applied && who != game->currentPlayer)
|
||||||
{
|
{
|
||||||
return (!paidThisTurn && currentPhase == MTG_PHASE_UPKEEP && ActivatedAbility::isReactingToClick(card, mana));
|
forceDestroy = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if(adding)
|
||||||
|
{
|
||||||
|
if(!applied)
|
||||||
|
if (PhaseRing::phaseStrToInt(after) == pe->to->id && who == game->currentPlayer)
|
||||||
|
{
|
||||||
|
pe->eventChanged = true;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PhaseRing::phaseStrToInt(phaseToAlter) == pe->to->id && who == game->currentPlayer)
|
||||||
|
{
|
||||||
|
pe->eventChanged = true;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int resolve()
|
int resolve()
|
||||||
{
|
{
|
||||||
paidThisTurn = 1;
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
if(who == game->players[i] && game->currentPlayer == game->players[i])
|
||||||
|
{
|
||||||
|
addTheEffect(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
void addTheEffect(int i)
|
||||||
|
{
|
||||||
|
int turnSteps = game->phaseRing->turn.size();
|
||||||
|
if(adding && !applied)
|
||||||
|
{
|
||||||
|
if(phaseToAlter == "combatphases")
|
||||||
|
{
|
||||||
|
game->phaseRing->addCombatAfter(game->players[i], PhaseRing::phaseStrToInt(after));
|
||||||
|
}
|
||||||
|
else if(phaseToAlter == "combatphaseswithmain")
|
||||||
|
{
|
||||||
|
game->phaseRing->addCombatAfter(game->players[i], PhaseRing::phaseStrToInt(after),true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
game->phaseRing->addPhaseAfter(PhaseRing::phaseStrToInt(phaseToAlter), game->players[i], PhaseRing::phaseStrToInt(after));
|
||||||
|
}
|
||||||
|
else if(!adding)
|
||||||
|
game->phaseRing->removePhase(PhaseRing::phaseStrToInt(phaseToAlter));
|
||||||
|
int turnAfterChange = game->phaseRing->turn.size();
|
||||||
|
if(turnSteps != turnAfterChange)
|
||||||
|
applied = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeTheEffect(int i)//readd this!!!!!!!!!!!!!
|
||||||
|
{
|
||||||
|
if(applied)
|
||||||
|
{
|
||||||
|
if(adding)
|
||||||
|
game->phaseRing->removePhase(PhaseRing::phaseStrToInt(phaseToAlter));
|
||||||
|
else
|
||||||
|
game->phaseRing->addPhaseAfter(PhaseRing::phaseStrToInt(phaseToAlter), game->players[i], PhaseRing::phaseStrToInt(after));
|
||||||
|
applied = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int testDestroy()
|
||||||
|
{
|
||||||
|
if(forceDestroy != -1)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int destroy()
|
int destroy()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
game->phaseRing->addPhaseBefore(MTG_PHASE_UNTAP, game->players[i], MTG_PHASE_UPKEEP,
|
if(who == game->players[i] && game->currentPlayer == game->players[i])
|
||||||
game->players[i]);
|
{
|
||||||
|
removeTheEffect(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ostream& toString(ostream& out) const
|
const char * getMenuText()
|
||||||
{
|
{
|
||||||
out << "AStasis ::: paidThisTurn : " << paidThisTurn << " (";
|
return "phase alter";
|
||||||
return ActivatedAbility::toString(out) << ")";
|
|
||||||
}
|
}
|
||||||
AStasis * clone() const
|
|
||||||
|
APhaseAlter * clone() const
|
||||||
{
|
{
|
||||||
return NEW AStasis(*this);
|
return NEW APhaseAlter(*this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ class GameObserver{
|
|||||||
int forceShuffleLibraries();
|
int forceShuffleLibraries();
|
||||||
int targetListIsSet(MTGCardInstance * card);
|
int targetListIsSet(MTGCardInstance * card);
|
||||||
PhaseRing * phaseRing;
|
PhaseRing * phaseRing;
|
||||||
|
vector<list<Phase*> >gameTurn;
|
||||||
int cancelCurrentAction();
|
int cancelCurrentAction();
|
||||||
GamePhase currentGamePhase;
|
GamePhase currentGamePhase;
|
||||||
ExtraCosts * mExtraPayment;
|
ExtraCosts * mExtraPayment;
|
||||||
@@ -118,6 +119,7 @@ class GameObserver{
|
|||||||
Player * currentActionPlayer;
|
Player * currentActionPlayer;
|
||||||
Player * isInterrupting;
|
Player * isInterrupting;
|
||||||
Player * opponent();
|
Player * opponent();
|
||||||
|
Player * nextTurnsPlayer();
|
||||||
Player * currentlyActing();
|
Player * currentlyActing();
|
||||||
GameObserver(WResourceManager* output = 0, JGE* input = 0);
|
GameObserver(WResourceManager* output = 0, JGE* input = 0);
|
||||||
~GameObserver();
|
~GameObserver();
|
||||||
|
|||||||
@@ -29,8 +29,9 @@ class Phase
|
|||||||
public:
|
public:
|
||||||
GamePhase id;
|
GamePhase id;
|
||||||
Player * player;
|
Player * player;
|
||||||
Phase(GamePhase id, Player *player) :
|
bool isExtra;
|
||||||
id(id), player(player)
|
Phase(GamePhase id, Player *player, bool _isExtra = false) :
|
||||||
|
id(id), player(player), isExtra(_isExtra)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@@ -44,16 +45,26 @@ private:
|
|||||||
public:
|
public:
|
||||||
list<Phase *> ring;
|
list<Phase *> ring;
|
||||||
list<Phase *>::iterator current;
|
list<Phase *>::iterator current;
|
||||||
|
list<Phase*>turn;
|
||||||
|
list<Phase*>currentTurnList;
|
||||||
|
list<Phase*>nextTurnList;
|
||||||
|
list<Phase*> currentTurn();
|
||||||
|
list<Phase*> nextTurn();
|
||||||
|
list<Phase*> extraPhases;
|
||||||
Phase * getCurrentPhase();
|
Phase * getCurrentPhase();
|
||||||
Phase * forward(bool sendEvents = true);
|
Phase * forward(bool sendEvents = true);
|
||||||
Phase * goToPhase(int id, Player * player, bool sendEvents = true);
|
Phase * goToPhase(int id, Player * player, bool sendEvents = true);
|
||||||
|
Phase * getPhase(int id);
|
||||||
PhaseRing(GameObserver* observer);
|
PhaseRing(GameObserver* observer);
|
||||||
~PhaseRing();
|
~PhaseRing();
|
||||||
|
void deleteOldTurn();
|
||||||
int addPhase(Phase * phase);
|
int addPhase(Phase * phase);
|
||||||
int addPhaseBefore(GamePhase id, Player* player, int after_id, Player * after_player, int allOccurences = 1);
|
int addCombatAfter(Player* player, int after_id, bool withMain = false);
|
||||||
int removePhase(int id, Player * player, int allOccurences = 1);
|
int addPhaseAfter(GamePhase id, Player* player, int after_id);
|
||||||
|
int removePhase(int id);
|
||||||
const char * phaseName(int id);
|
const char * phaseName(int id);
|
||||||
static GamePhase phaseStrToInt(string s);
|
static GamePhase phaseStrToInt(string s);
|
||||||
|
static string phaseIntToStr(int id);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -127,14 +127,41 @@ Player * GameObserver::opponent()
|
|||||||
return players[index];
|
return players[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Player * GameObserver::nextTurnsPlayer()
|
||||||
|
{
|
||||||
|
int nextTurnsId = 0;
|
||||||
|
if(!players[currentPlayerId]->extraTurn)
|
||||||
|
nextTurnsId = (currentPlayerId + 1) % players.size();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nextTurnsId = currentPlayerId;
|
||||||
|
}
|
||||||
|
if(players[currentPlayerId]->skippingTurn)
|
||||||
|
{
|
||||||
|
nextTurnsId = (currentPlayerId + 1) % players.size();
|
||||||
|
}
|
||||||
|
return players[nextTurnsId];
|
||||||
|
}
|
||||||
|
|
||||||
void GameObserver::nextPlayer()
|
void GameObserver::nextPlayer()
|
||||||
{
|
{
|
||||||
turn++;
|
turn++;
|
||||||
currentPlayerId = (currentPlayerId + 1) % players.size();
|
if(!players[currentPlayerId]->extraTurn)
|
||||||
|
currentPlayerId = (currentPlayerId + 1) % players.size();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
players[currentPlayerId]->extraTurn--;
|
||||||
|
}
|
||||||
|
if(players[currentPlayerId]->skippingTurn)
|
||||||
|
{
|
||||||
|
players[currentPlayerId]->skippingTurn--;
|
||||||
|
currentPlayerId = (currentPlayerId + 1) % players.size();
|
||||||
|
}
|
||||||
currentPlayer = players[currentPlayerId];
|
currentPlayer = players[currentPlayerId];
|
||||||
currentActionPlayer = currentPlayer;
|
currentActionPlayer = currentPlayer;
|
||||||
combatStep = BLOCKERS;
|
combatStep = BLOCKERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameObserver::nextGamePhase()
|
void GameObserver::nextGamePhase()
|
||||||
{
|
{
|
||||||
Phase * cPhaseOld = phaseRing->getCurrentPhase();
|
Phase * cPhaseOld = phaseRing->getCurrentPhase();
|
||||||
@@ -166,9 +193,11 @@ void GameObserver::nextGamePhase()
|
|||||||
|
|
||||||
if (MTG_PHASE_COMBATDAMAGE == currentGamePhase)
|
if (MTG_PHASE_COMBATDAMAGE == currentGamePhase)
|
||||||
nextCombatStep();
|
nextCombatStep();
|
||||||
|
if (MTG_PHASE_COMBATEND == currentGamePhase)
|
||||||
|
combatStep = BLOCKERS;
|
||||||
|
|
||||||
if (currentPlayer != cPhase->player)
|
//if (currentPlayer != cPhase->player)
|
||||||
nextPlayer();
|
// nextPlayer();//depreciated; we call this at EOT step now. unsure what the purpose of this was originally.fix for a bug?
|
||||||
|
|
||||||
//init begin of turn
|
//init begin of turn
|
||||||
if (currentGamePhase == MTG_PHASE_BEFORE_BEGIN)
|
if (currentGamePhase == MTG_PHASE_BEFORE_BEGIN)
|
||||||
@@ -200,6 +229,7 @@ void GameObserver::nextGamePhase()
|
|||||||
mLayers->actionLayer()->Update(0);
|
mLayers->actionLayer()->Update(0);
|
||||||
currentPlayer->lifeLostThisTurn = 0;
|
currentPlayer->lifeLostThisTurn = 0;
|
||||||
currentPlayer->opponent()->lifeLostThisTurn = 0;
|
currentPlayer->opponent()->lifeLostThisTurn = 0;
|
||||||
|
nextPlayer();
|
||||||
return nextGamePhase();
|
return nextGamePhase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,8 +328,28 @@ void GameObserver::userRequestNextGamePhase(bool allowInterrupt, bool log)
|
|||||||
|
|
||||||
void GameObserver::shuffleLibrary(Player* p)
|
void GameObserver::shuffleLibrary(Player* p)
|
||||||
{
|
{
|
||||||
|
if(!p)
|
||||||
|
{
|
||||||
|
DebugTrace("FATAL: No Player To Shuffle");
|
||||||
|
return;
|
||||||
|
}
|
||||||
logAction(p, "shufflelib");
|
logAction(p, "shufflelib");
|
||||||
p->game->library->shuffle();
|
MTGLibrary * library = p->game->library;
|
||||||
|
if(!library)
|
||||||
|
{
|
||||||
|
DebugTrace("FATAL: Player has no zones");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
library->shuffle();
|
||||||
|
|
||||||
|
for(unsigned int k = 0;k < library->placeOnTop.size();k++)
|
||||||
|
{
|
||||||
|
MTGCardInstance * toMove = library->placeOnTop[k];
|
||||||
|
assert(toMove);
|
||||||
|
p->game->putInZone(toMove, p->game->temp, library);
|
||||||
|
}
|
||||||
|
library->placeOnTop.clear();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -569,12 +619,14 @@ void GameObserver::gameStateBasedEffects()
|
|||||||
MTGCardInstance * card = zone->cards[j];
|
MTGCardInstance * card = zone->cards[j];
|
||||||
card->afterDamage();
|
card->afterDamage();
|
||||||
card->mPropertiesChangedSinceLastUpdate = false;
|
card->mPropertiesChangedSinceLastUpdate = false;
|
||||||
|
if(card->hasType(Subtypes::TYPE_PLANESWALKER) && (!card->counters||!card->counters->hasCounter("loyalty",0,0)))
|
||||||
|
players[i]->game->putInGraveyard(card);
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
//Remove auras that don't have a valid target anymore//
|
//Remove auras that don't have a valid target anymore//
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
if (card->target && !isInPlay(card->target) && !card->hasType(Subtypes::TYPE_EQUIPMENT))
|
if ((card->target||card->playerTarget) && !card->hasType(Subtypes::TYPE_EQUIPMENT))
|
||||||
{
|
{
|
||||||
|
if(card->target && !isInPlay(card->target))
|
||||||
players[i]->game->putInGraveyard(card);
|
players[i]->game->putInGraveyard(card);
|
||||||
}
|
}
|
||||||
card->enchanted = false;
|
card->enchanted = false;
|
||||||
@@ -743,6 +795,7 @@ void GameObserver::gameStateBasedEffects()
|
|||||||
c->wasDealtDamage = false;
|
c->wasDealtDamage = false;
|
||||||
c->damageToController = false;
|
c->damageToController = false;
|
||||||
c->damageToOpponent = false;
|
c->damageToOpponent = false;
|
||||||
|
c->isAttacking = NULL;
|
||||||
}
|
}
|
||||||
for (int t = 0; t < nbcards; t++)
|
for (int t = 0; t < nbcards; t++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3408,11 +3408,6 @@ void AbilityFactory::addAbilities(int _id, Spell * spell)
|
|||||||
observer->addObserver(NEW AFastbond(observer, _id, card));
|
observer->addObserver(NEW AFastbond(observer, _id, card));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1225: //Stasis
|
|
||||||
{
|
|
||||||
observer->addObserver(NEW AStasis(observer, _id, card));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1227: //Toughtlace
|
case 1227: //Toughtlace
|
||||||
{
|
{
|
||||||
if (card->target)
|
if (card->target)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ GamePhase PhaseRing::phaseStrToInt(string s)
|
|||||||
if (s.compare("upkeep") == 0) return MTG_PHASE_UPKEEP;
|
if (s.compare("upkeep") == 0) return MTG_PHASE_UPKEEP;
|
||||||
if (s.compare("draw") == 0) return MTG_PHASE_DRAW;
|
if (s.compare("draw") == 0) return MTG_PHASE_DRAW;
|
||||||
if (s.compare("firstmain") == 0) return MTG_PHASE_FIRSTMAIN;
|
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("combatbegin") == 0) return MTG_PHASE_COMBATBEGIN;
|
||||||
if (s.compare("combatbegins") == 0) return MTG_PHASE_COMBATBEGIN;
|
if (s.compare("combatbegins") == 0) return MTG_PHASE_COMBATBEGIN;
|
||||||
if (s.compare("combatattackers") == 0) return MTG_PHASE_COMBATATTACKERS;
|
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("end") == 0) return MTG_PHASE_ENDOFTURN;
|
||||||
if (s.compare("cleanup") == 0) return MTG_PHASE_CLEANUP;
|
if (s.compare("cleanup") == 0) return MTG_PHASE_CLEANUP;
|
||||||
DebugTrace("PHASERING: Unknown Phase name: " << s);
|
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 */
|
/* 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++)
|
for (int i = 0; i < observer->getPlayersNumber(); i++)
|
||||||
{
|
{
|
||||||
|
list<Phase*>turnRing;//this is temporary;
|
||||||
if(observer->players[i]->phaseRing.size())
|
if(observer->players[i]->phaseRing.size())
|
||||||
{
|
{
|
||||||
addPhase(NEW Phase(MTG_PHASE_BEFORE_BEGIN, observer->players[i]));
|
addPhase(NEW Phase(MTG_PHASE_BEFORE_BEGIN, observer->players[i]));
|
||||||
@@ -42,8 +61,9 @@ PhaseRing::PhaseRing(GameObserver* observer)
|
|||||||
GamePhase customOrder = phaseStrToInt(customRing[k]);
|
GamePhase customOrder = phaseStrToInt(customRing[k]);
|
||||||
Phase * phase = NEW Phase(customOrder, observer->players[i]);
|
Phase * phase = NEW Phase(customOrder, observer->players[i]);
|
||||||
addPhase(phase);
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -51,10 +71,42 @@ PhaseRing::PhaseRing(GameObserver* observer)
|
|||||||
{
|
{
|
||||||
Phase * phase = NEW Phase((GamePhase)j, observer->players[i]);
|
Phase * phase = NEW Phase((GamePhase)j, observer->players[i]);
|
||||||
addPhase(phase);
|
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()
|
PhaseRing::~PhaseRing()
|
||||||
@@ -65,6 +117,11 @@ PhaseRing::~PhaseRing()
|
|||||||
Phase * currentPhase = *it;
|
Phase * currentPhase = *it;
|
||||||
delete (currentPhase);
|
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
|
//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()
|
Phase * PhaseRing::getCurrentPhase()
|
||||||
{
|
{
|
||||||
if (current == ring.end())
|
if (current == turn.end())
|
||||||
{
|
{
|
||||||
current = ring.begin();
|
turn = nextTurn();
|
||||||
|
current = turn.begin();
|
||||||
}
|
}
|
||||||
return *current;
|
return *current;
|
||||||
}
|
}
|
||||||
@@ -103,28 +161,60 @@ Phase * PhaseRing::getCurrentPhase()
|
|||||||
Phase * PhaseRing::forward(bool sendEvents)
|
Phase * PhaseRing::forward(bool sendEvents)
|
||||||
{
|
{
|
||||||
Phase * cPhaseOld = *current;
|
Phase * cPhaseOld = *current;
|
||||||
if (current != ring.end()) current++;
|
//the following is a present event before change
|
||||||
if (current == ring.end()) current = ring.begin();
|
//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)
|
if (sendEvents)
|
||||||
{
|
{
|
||||||
//Warn the layers about the phase Change
|
//Warn the layers about the phase Change
|
||||||
WEvent * e = NEW WEventPhaseChange(cPhaseOld, *current);
|
WEvent * e = NEW WEventPhaseChange(cPhaseOld, *current);
|
||||||
observer->receiveEvent(e);
|
observer->receiveEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return *current;
|
return *current;
|
||||||
}
|
}
|
||||||
|
|
||||||
Phase * PhaseRing::goToPhase(int id, Player * player, bool sendEvents)
|
Phase * PhaseRing::goToPhase(int id, Player * player, bool sendEvents)
|
||||||
{
|
{
|
||||||
Phase * currentPhase = *current;
|
Phase * currentPhase = getCurrentPhase();
|
||||||
while (currentPhase->id != id || currentPhase->player != player)
|
while (currentPhase->id != id)
|
||||||
{ //Dangerous, risk for inifinte loop !
|
{ //Dangerous, risk for inifinte loop !
|
||||||
|
|
||||||
DebugTrace("PhasingRing: goToPhase called, current phase is " << phaseName(currentPhase->id));
|
DebugTrace("PhasingRing: goToPhase called, current phase is " << phaseName(currentPhase->id));
|
||||||
|
|
||||||
currentPhase = forward(sendEvents);
|
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;
|
return currentPhase;
|
||||||
}
|
}
|
||||||
@@ -135,41 +225,149 @@ int PhaseRing::addPhase(Phase * phase)
|
|||||||
return 1;
|
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;
|
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;
|
Phase * currentPhase = *it;
|
||||||
if (currentPhase->id == after_id && currentPhase->player == after_player)
|
if (currentPhase->id == after_id)
|
||||||
{
|
{
|
||||||
result++;
|
beforeLeaving = currentPhase;
|
||||||
ring.insert(it, NEW Phase(id, player));
|
it++;
|
||||||
if (!allOccurences) return 1;
|
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;
|
||||||
list<Phase *>::iterator it = ring.begin();
|
for (it = turn.begin(); it != turn.end(); it++)
|
||||||
while (it != ring.end())
|
|
||||||
{
|
{
|
||||||
Phase * currentPhase = *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
|
return currentPhase;
|
||||||
it = ring.erase(it);
|
}
|
||||||
delete (currentPhase);
|
}
|
||||||
result++;
|
return NULL;
|
||||||
if (!allOccurences) return 1;
|
}
|
||||||
|
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user