diff --git a/projects/mtg/include/AllAbilities.h b/projects/mtg/include/AllAbilities.h index 56d9bbb2f..4b44c8539 100644 --- a/projects/mtg/include/AllAbilities.h +++ b/projects/mtg/include/AllAbilities.h @@ -607,6 +607,35 @@ public: } }; +class TrplayerInitiative: public Trigger +{ +public: + bool thiscontroller, thisopponent; + TrplayerInitiative(GameObserver* observer, int id, MTGCardInstance * source, TargetChooser * tc, bool once = false, bool thiscontroller = false, bool thisopponent = false) : + Trigger(observer, id, source, once, tc), thiscontroller(thiscontroller), thisopponent(thisopponent) + { + } + + int triggerOnEventImpl(WEvent * event) + { + WEventplayerInitiative * e = dynamic_cast (event); + if (!e) return 0; + if (!tc->canTarget(e->player)) return 0; + if(thiscontroller) + if(e->player != source->controller()) + return 0; + if(thisopponent) + if(e->player == source->controller()) + return 0; + return 1; + } + + TrplayerInitiative * clone() const + { + return NEW TrplayerInitiative(*this); + } +}; + class TrplayerShuffled: public Trigger { public: @@ -4367,6 +4396,18 @@ public: AAAlterMonarch * clone() const; ~AAAlterMonarch(); }; +//Initiative +class AAAlterInitiative: public ActivatedAbilityTP +{ +public: + + AAAlterInitiative(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable * _target, ManaCost * _cost = NULL, + int who = TargetChooser::UNSET); + int resolve(); + const string getMenuText(); + AAAlterInitiative * clone() const; + ~AAAlterInitiative(); +}; //Surveil Offset class AAAlterSurveilOffset: public ActivatedAbilityTP { diff --git a/projects/mtg/include/Player.h b/projects/mtg/include/Player.h index b9409ab66..0a4f31abc 100644 --- a/projects/mtg/include/Player.h +++ b/projects/mtg/include/Player.h @@ -48,6 +48,7 @@ public: int dungeonCompleted; int numOfCommandCast; int monarch; + int initiative; int surveilOffset; int devotionOffset; int lastShuffleTurn; diff --git a/projects/mtg/include/WEvent.h b/projects/mtg/include/WEvent.h index 79d8628ff..236a2fba0 100644 --- a/projects/mtg/include/WEvent.h +++ b/projects/mtg/include/WEvent.h @@ -385,6 +385,14 @@ struct WEventplayerMonarch : public WEvent { virtual Targetable * getTarget(Player * player); }; +//initiative event +struct WEventplayerInitiative : public WEvent { + WEventplayerInitiative(Player * player); + Player * player; + using WEvent::getTarget; + virtual Targetable * getTarget(Player * player); +}; + //shuffle event struct WEventplayerShuffled : public WEvent { WEventplayerShuffled(Player * player); diff --git a/projects/mtg/src/AllAbilities.cpp b/projects/mtg/src/AllAbilities.cpp index 5ad060a2e..f345d8ca0 100644 --- a/projects/mtg/src/AllAbilities.cpp +++ b/projects/mtg/src/AllAbilities.cpp @@ -1370,6 +1370,46 @@ AAAlterMonarch::~AAAlterMonarch() { } +//AA Initiative +AAAlterInitiative::AAAlterInitiative(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable * _target, ManaCost * _cost, + int who) : + ActivatedAbilityTP(observer, _id, _source, _target, _cost, who) +{ +} + +int AAAlterInitiative::resolve() +{ + Damageable * _target = (Damageable *) getTarget(); + if (_target) + { + Player * pTarget = (Player*)_target; + if(pTarget) + { + if(!pTarget->initiative){ + pTarget->initiative = 1; + pTarget->opponent()->initiative = 0; + WEvent * e = NEW WEventplayerInitiative(pTarget); + game->receiveEvent(e); + } + } + } + return 0; +} + +const string AAAlterInitiative::getMenuText() +{ + return _("A player takes the Initiative").c_str(); +} + +AAAlterInitiative * AAAlterInitiative::clone() const +{ + return NEW AAAlterInitiative(*this); +} + +AAAlterInitiative::~AAAlterInitiative() +{ +} + //AA Energy Counters AAAlterEnergy::AAAlterEnergy(GameObserver* observer, int _id, MTGCardInstance * _source, Targetable * _target, int energy, ManaCost * _cost, int who) : diff --git a/projects/mtg/src/MTGAbility.cpp b/projects/mtg/src/MTGAbility.cpp index 2064cae8c..efd8d0fa6 100644 --- a/projects/mtg/src/MTGAbility.cpp +++ b/projects/mtg/src/MTGAbility.cpp @@ -344,6 +344,51 @@ int AbilityFactory::parseCastRestrictions(MTGCardInstance * card, Player * playe if(!count) return 0; } + check = restriction[i].find("exilecast"); + if(check != string::npos) + { + int count = 0; + for(unsigned int k = 0; k < player->game->stack->cardsSeenThisTurn.size(); k++) + { + MTGCardInstance * stackCard = player->game->stack->cardsSeenThisTurn[k]; + if(stackCard->next && stackCard->next == card && (card->previousZone == card->controller()->game->exile||card->previousZone == card->controller()->opponent()->game->exile)) + count++; + if(stackCard == card && (card->previousZone == card->controller()->game->exile||card->previousZone == card->controller()->opponent()->game->exile)) + count++; + } + if(!count) + return 0; + } + check = restriction[i].find("sidecast"); + if(check != string::npos) + { + int count = 0; + for(unsigned int k = 0; k < player->game->stack->cardsSeenThisTurn.size(); k++) + { + MTGCardInstance * stackCard = player->game->stack->cardsSeenThisTurn[k]; + if(stackCard->next && stackCard->next == card && (card->previousZone == card->controller()->game->sideboard||card->previousZone == card->controller()->opponent()->game->sideboard)) + count++; + if(stackCard == card && (card->previousZone == card->controller()->game->sideboard||card->previousZone == card->controller()->opponent()->game->sideboard)) + count++; + } + if(!count) + return 0; + } + check = restriction[i].find("commandzonecast"); + if(check != string::npos) + { + int count = 0; + for(unsigned int k = 0; k < player->game->stack->cardsSeenThisTurn.size(); k++) + { + MTGCardInstance * stackCard = player->game->stack->cardsSeenThisTurn[k]; + if(stackCard->next && stackCard->next == card && (card->previousZone == card->controller()->game->commandzone||card->previousZone == card->controller()->opponent()->game->commandzone)) + count++; + if(stackCard == card && (card->previousZone == card->controller()->game->commandzone||card->previousZone == card->controller()->opponent()->game->commandzone)) + count++; + } + if(!count) + return 0; + } check = restriction[i].find("rebound"); if(check != string::npos) { @@ -1275,6 +1320,14 @@ TriggeredAbility * AbilityFactory::parseTrigger(string s, string, int id, Spell if (TargetChooser * tc = parseSimpleTC(s, "becomesmonarchfoeof", card)) return NEW TrplayerMonarch(observer, id, card, tc, once, false, true); + //takes the initiative - controller of card + if (TargetChooser * tc = parseSimpleTC(s, "takesinitiativeof", card)) + return NEW TrplayerInitiative(observer, id, card, tc, once, true, false); + + //takes the initiative - opponent of card controller + if (TargetChooser * tc = parseSimpleTC(s, "takesinitiativefoeof", card)) + return NEW TrplayerInitiative(observer, id, card, tc, once, false, true); + //shuffled library - controller of card if (TargetChooser * tc = parseSimpleTC(s, "shuffledof", card)) return NEW TrplayerShuffled(observer, id, card, tc, once, true, false); @@ -3912,6 +3965,16 @@ MTGAbility * AbilityFactory::parseMagicLine(string s, int id, Spell * spell, MTG return a; } + //takes the initiative + vector splitInitiative = parseBetween(s, "takesinitiative", " ", false); + if (splitInitiative.size()) + { + Targetable * t = spell ? spell->getNextTarget() : NULL; + MTGAbility * a = NEW AAAlterInitiative(observer, id, card, t, NULL, who); + a->oneShot = 1; + return a; + } + //alter mutation counter on target card with trigger activation vector splitMutated = parseBetween(s, "altermutationcounter:", " ", false); if (splitMutated.size()) diff --git a/projects/mtg/src/Player.cpp b/projects/mtg/src/Player.cpp index 2ae7f23f2..8a748a17c 100644 --- a/projects/mtg/src/Player.cpp +++ b/projects/mtg/src/Player.cpp @@ -40,6 +40,7 @@ Player::Player(GameObserver *observer, string file, string fileSmall, MTGDeck * dungeonCompleted = 0; numOfCommandCast = 0; monarch = 0; + initiative = 0; surveilOffset = 0; devotionOffset = 0; lastShuffleTurn = -1; diff --git a/projects/mtg/src/Rules.cpp b/projects/mtg/src/Rules.cpp index 744193951..8d4fc1c5b 100644 --- a/projects/mtg/src/Rules.cpp +++ b/projects/mtg/src/Rules.cpp @@ -666,6 +666,7 @@ void Rules::initGame(GameObserver *g, bool currentPlayerSet) p->dungeonCompleted = initState.playerData[i].player->dungeonCompleted; p->numOfCommandCast = initState.playerData[i].player->numOfCommandCast; p->monarch = initState.playerData[i].player->monarch; + p->initiative = initState.playerData[i].player->initiative; p->surveilOffset = initState.playerData[i].player->surveilOffset; p->devotionOffset = initState.playerData[i].player->devotionOffset; p->lastChosenName = initState.playerData[i].player->lastChosenName; diff --git a/projects/mtg/src/WEvent.cpp b/projects/mtg/src/WEvent.cpp index 153d0d6cf..3ee93ffd6 100644 --- a/projects/mtg/src/WEvent.cpp +++ b/projects/mtg/src/WEvent.cpp @@ -307,6 +307,11 @@ WEventplayerMonarch::WEventplayerMonarch(Player * player) : { } +WEventplayerInitiative::WEventplayerInitiative(Player * player) : + player(player) +{ +} + WEventplayerShuffled::WEventplayerShuffled(Player * player) : player(player) { @@ -663,6 +668,12 @@ Targetable * WEventplayerMonarch::getTarget(Player * player) return NULL; } +Targetable * WEventplayerInitiative::getTarget(Player * player) +{ + if (player) return player; + return NULL; +} + Targetable * WEventplayerShuffled::getTarget(Player * player) { if (player) return player; diff --git a/projects/mtg/src/WParsedInt.cpp b/projects/mtg/src/WParsedInt.cpp index 6f7f9e320..299edd8ae 100644 --- a/projects/mtg/src/WParsedInt.cpp +++ b/projects/mtg/src/WParsedInt.cpp @@ -1373,6 +1373,10 @@ void WParsedInt::extendedParse(string s, Spell * spell, MTGCardInstance * card) { intValue = (s == "pdungeoncompleted")?card->controller()->dungeonCompleted:card->controller()->opponent()->dungeonCompleted; } + else if (s == "pinitiative" || s == "oinitiative") // Which player has the initiative + { + intValue = (s == "pinitiative")?card->controller()->initiative:card->controller()->opponent()->initiative; + } else if (s == "pwrtotatt" || s == "thstotatt")//count Total Power or toughness of attacking creatures (e.g. Battle Cry Goblin) { intValue = 0;