diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index 1605a69f355..25728de2544 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -464,12 +464,9 @@ public class AbilityUtils { players.remove(game.getPhaseHandler().getPlayerTurn()); val = CardFactoryUtil.playerXCount(players, calcX[1], card); } - else if (hType.startsWith("PropertyYou") && !(ability instanceof SpellAbility)) { - // Related to the controller of the card with ability when the ability is static (or otherwise not a SpellAbility) - // TODO: This doesn't work in situations when the controller of the card is different from the spell caster - // (e.g. opponent's Hollow One exiled by Hostage Taker - cost reduction will not work in this scenario, requires - // a more significant rework). - players.add(card.getController()); + else if (hType.startsWith("PropertyYou") && ability instanceof SpellAbility) { + // Hollow One + players.add(((SpellAbility) ability).getActivatingPlayer()); val = CardFactoryUtil.playerXCount(players, calcX[1], card); } else if (hType.startsWith("Property") && ability instanceof SpellAbility) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/RestartGameEffect.java b/forge-game/src/main/java/forge/game/ability/effects/RestartGameEffect.java index 4641d05d75f..61848eba1f3 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/RestartGameEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/RestartGameEffect.java @@ -70,6 +70,7 @@ public class RestartGameEffect extends SpellAbilityEffect { player.setStartingLife(psc.getStartingLife()); player.setPoisonCounters(0, sa.getHostCard()); + player.resetSpellCastThisGame(); player.setLandsPlayedLastTurn(0); player.resetLandsPlayedThisTurn(); player.resetInvestigatedThisTurn(); diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 0614d86cef8..829f0979785 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -918,6 +918,10 @@ public class CardFactoryUtil { return doXMath(cc.getSurveilThisTurn(), m, c); } + if (sq[0].equals("YouCastThisGame")) { + return doXMath(cc.getSpellsCastThisGame(), m, c); + } + if (sq[0].equals("FirstSpellTotalManaSpent")) { try{ return doXMath(c.getFirstSpellAbility().getTotalManaSpent(), m, c); diff --git a/forge-game/src/main/java/forge/game/cost/CostAdjustment.java b/forge-game/src/main/java/forge/game/cost/CostAdjustment.java index 554a7697404..25c4ca28ca7 100644 --- a/forge-game/src/main/java/forge/game/cost/CostAdjustment.java +++ b/forge-game/src/main/java/forge/game/cost/CostAdjustment.java @@ -381,6 +381,9 @@ public class CostAdjustment { } else if ("Undaunted".equals(amount)) { value = card.getController().getOpponents().size(); } else if (staticAbility.hasParam("Relative")) { + // TODO: update cards with "This spell costs X less to cast...if you..." + // The caster is sa.getActivatingPlayer() + // cards like Hostage Taker can cast spells from other players. value = AbilityUtils.calculateAmount(hostCard, amount, sa); } else { value = AbilityUtils.calculateAmount(hostCard, amount, staticAbility); diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index f03e5a075a7..b7aec94aa23 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -84,6 +84,7 @@ public class Player extends GameEntity implements Comparable { private final Map assignedDamage = Maps.newHashMap(); private final Map assignedCombatDamage = Maps.newHashMap(); private int spellsCastThisTurn = 0; + private int spellsCastThisGame = 0; private int spellsCastLastTurn = 0; private int landsPlayedThisTurn = 0; private int landsPlayedLastTurn = 0; @@ -2209,6 +2210,7 @@ public class Player extends GameEntity implements Comparable { } public final void addSpellCastThisTurn() { spellsCastThisTurn++; + spellsCastThisGame++; achievementTracker.spellsCast++; if (spellsCastThisTurn > achievementTracker.maxStormCount) { achievementTracker.maxStormCount = spellsCastThisTurn; @@ -2220,7 +2222,12 @@ public class Player extends GameEntity implements Comparable { public final void setSpellsCastLastTurn(int num) { spellsCastLastTurn = num; } - + public final int getSpellsCastThisGame() { + return spellsCastThisGame; + } + public final void resetSpellCastThisGame() { + spellsCastThisGame = 0; + } public final int getLifeGainedByTeamThisTurn() { return lifeGainedByTeamThisTurn; } diff --git a/forge-gui/res/cardsfolder/h/hollow_one.txt b/forge-gui/res/cardsfolder/h/hollow_one.txt index feccc64423e..a5899c928f7 100644 --- a/forge-gui/res/cardsfolder/h/hollow_one.txt +++ b/forge-gui/res/cardsfolder/h/hollow_one.txt @@ -2,8 +2,8 @@ Name:Hollow One ManaCost:5 Types:Artifact Creature Golem PT:4/4 -S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ Y | EffectZone$ All | Description$ CARDNAME costs {2} less to cast for each card you've cycled or discarded this turn. +S:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ Y | Relative$ True | EffectZone$ All | Description$ This spell costs {2} less to cast for each card you've cycled or discarded this turn. K:Cycling:2 SVar:Y:PlayerCountPropertyYou$CardsDiscardedThisTurn/Twice SVar:Picture:http://www.wizards.com/global/images/magic/general/hollow_one.jpg -Oracle:Hollow One costs {2} less to cast for each card you've cycled or discarded this turn.\nCycling {2} ({2}, Discard this card: Draw a card.) \ No newline at end of file +Oracle:This spell costs {2} less to cast for each card you've cycled or discarded this turn.\nCycling {2} ({2}, Discard this card: Draw a card.) diff --git a/forge-gui/res/cardsfolder/upcoming/clackbridge_troll.txt b/forge-gui/res/cardsfolder/upcoming/clackbridge_troll.txt new file mode 100644 index 00000000000..8a640e10fc2 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/clackbridge_troll.txt @@ -0,0 +1,13 @@ +Name:Clackbridge Troll +ManaCost:3 B B +Types:Creature Troll +PT:8/8 +K:Haste +K:Trample +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TripleGoat | TriggerDescription$ When CARDNAME enters the battlefield, target opponent creates three 0/1 white Goat creature tokens. +SVar:TripleGoat:DB$ Token | TokenAmount$ 3 | TokenScript$ w_0_1_goat | LegacyImage$ w 0 1 goat eld | ValidTgts$ Opponent | TokenOwner$ Targeted +T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | Execute$ TrigTap | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of combat on your turn, any opponent may sacrifice a creature. If a player does, tap CARDNAME, you gain 3 life, and you draw a card. +SVar:TrigTap:DB$ Tap | Defined$ Self | SubAbility$ DBDraw | UnlessCost$ Sac<1/Creature> | UnlessPayer$ Player.Opponent | UnlessSwitched$ True | UnlessAI$ LifeLE10 | UnlessResolveSubs$ WhenPaid | SubAbility$ DBGainLife +SVar:DBGainLife:DB$ GainLife | LifeAmount$ 3 | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | NumCards$ 1 | Defined$ You +Oracle:Trample, haste\nWhen Clackbridge Troll enters the battlefield, target opponent creates three 0/1 white Goat creature tokens.\nAt the beginning of combat on your turn, any opponent may sacrifice a creature. If a player does, tap Clackbridge Troll, you gain 3 life, and you draw a card. diff --git a/forge-gui/res/cardsfolder/upcoming/dance_of_the_manse.txt b/forge-gui/res/cardsfolder/upcoming/dance_of_the_manse.txt new file mode 100644 index 00000000000..b9d1a86e96f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/dance_of_the_manse.txt @@ -0,0 +1,8 @@ +Name:Dance of the Manse +ManaCost:X W U +Types:Sorcery +A:SP$ ChangeZone | Cost$ X W U | Announce$ X | Origin$ Graveyard | Destination$ Battlefield | ValidTgts$ Artifact.cmcLEX,Enchantment.cmcLEX | TgtPrompt$ Select target artifact or enchantment in your graveyard | TargetMin$ 0 | TargetMax$ X | SubAbility$ DBAnimate | SpellDescription$ Return up to X target artifact and/or non-Aura enchantment cards with converted mana cost X or less from your graveyard to the battlefield. If X is 6 or more, those permanents are 4/4 creatures in addition to their other types. +SVar:DBAnimate:DB$ Animate | Defined$ Targeted | Types$ Creature | Power$ 4 | Toughness$ 4 | Permanent$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ GE6 | References$ X +SVar:X:Count$xPaid +AI:RemoveDeck:All +Oracle:Return up to X target artifact and/or non-Aura enchantment cards each with converted mana cost X or less from your graveyard to the battlefield. If X is 6 or more, those permanents are 4/4 creatures in addition to their other types. diff --git a/forge-gui/res/cardsfolder/upcoming/once_upon_a_time.txt b/forge-gui/res/cardsfolder/upcoming/once_upon_a_time.txt new file mode 100644 index 00000000000..d4a0ca42d5f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/once_upon_a_time.txt @@ -0,0 +1,7 @@ +Name:Once Upon a Time +ManaCost:1 G +Types:Instant +S:Mode$ Continuous | Affected$ Card.Self | EffectZone$ All | CheckSVar$ X | SVarCompare$ EQ0 | MayPlay$ True | MayPlayDontGrantZonePermissions$ True | MayPlayWithoutManaCost$ True | Description$ If this spell is the first spell you've cast this game, you may cast it without paying its mana cost. +SVar:X:Count$YouCastThisGame +A:SP$ Dig | Cost$ 1 G | DigNum$ 5 | ChangeNum$ 1 | Optional$ True | ForceRevealToController$ True | ChangeValid$ Card.Creature,Card.Land | RestRandomOrder$ True | SpellDescription$ Look at the top five cards of your library. You may reveal a creature or land card from among them and put it into your hand. Put the rest on the bottom of your library in a random order. +Oracle:If this spell is the first spell you've cast this game, you may cast it without paying its mana cost.\nLook at the top five cards of your library. You may reveal a creature or land card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.