diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java index ae3a451a74a..bce1ec8a53e 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilCard.java @@ -1576,7 +1576,7 @@ public class ComputerUtilCard { pumped.addChangedCardKeywords(kws, null, false, false, timestamp); Set types = c.getCounters().keySet(); for(CounterType ct : types) { - pumped.addCounterFireNoEvents(ct, c.getCounters(ct), c, true); + pumped.addCounterFireNoEvents(ct, c.getCounters(ct), ai, true); } //Copies tap-state and extra keywords (auras, equipment, etc.) if (c.isTapped()) { diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index 8e063fc4ccb..7a21356b85b 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -168,12 +168,13 @@ public class PlayerControllerAi extends PlayerController { } @Override - public SpellAbility chooseSingleSpellForEffect(java.util.List spells, SpellAbility sa, String title) { + public SpellAbility chooseSingleSpellForEffect(java.util.List spells, SpellAbility sa, String title, + Map params) { ApiType api = sa.getApi(); if (null == api) { throw new InvalidParameterException("SA is not api-based, this is not supported yet"); } - return SpellApiToAi.Converter.get(api).chooseSingleSpellAbility(player, sa, spells); + return SpellApiToAi.Converter.get(api).chooseSingleSpellAbility(player, sa, spells, params); } @Override diff --git a/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java b/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java index be3d906ec92..93168edf512 100644 --- a/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java +++ b/forge-ai/src/main/java/forge/ai/SpellAbilityAi.java @@ -324,7 +324,7 @@ public abstract class SpellAbilityAi { return null; } - public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, List spells) { + public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, List spells, Map params) { System.err.println("Warning: default (ie. inherited from base class) implementation of chooseSingleSpellAbility is used by " + sa.getHostCard().getName() + " for " + this.getClass().getName() + ". Consider declaring an overloaded method"); return spells.get(0); } diff --git a/forge-ai/src/main/java/forge/ai/SpellApiToAi.java b/forge-ai/src/main/java/forge/ai/SpellApiToAi.java index c11bd25aad6..ba1b33e24fe 100644 --- a/forge-ai/src/main/java/forge/ai/SpellApiToAi.java +++ b/forge-ai/src/main/java/forge/ai/SpellApiToAi.java @@ -25,6 +25,7 @@ public enum SpellApiToAi { .put(ApiType.AnimateAll, AnimateAllAi.class) .put(ApiType.Attach, AttachAi.class) .put(ApiType.Ascend, AlwaysPlayAi.class) + .put(ApiType.AssignGroup, AssignGroupAi.class) .put(ApiType.Balance, BalanceAi.class) .put(ApiType.BecomeMonarch, AlwaysPlayAi.class) .put(ApiType.BecomesBlocked, BecomesBlockedAi.class) diff --git a/forge-ai/src/main/java/forge/ai/ability/ActivateAbilityAi.java b/forge-ai/src/main/java/forge/ai/ability/ActivateAbilityAi.java index b71f07080f7..7eba97960da 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ActivateAbilityAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ActivateAbilityAi.java @@ -12,6 +12,7 @@ import forge.game.zone.ZoneType; import forge.util.MyRandom; import java.util.List; +import java.util.Map; public class ActivateAbilityAi extends SpellAbilityAi { @@ -93,7 +94,8 @@ public class ActivateAbilityAi extends SpellAbilityAi { } @Override - public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, List spells) { + public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, List spells, + Map params) { return spells.get(0); } } diff --git a/forge-ai/src/main/java/forge/ai/ability/AssignGroupAi.java b/forge-ai/src/main/java/forge/ai/ability/AssignGroupAi.java new file mode 100644 index 00000000000..691a21904ce --- /dev/null +++ b/forge-ai/src/main/java/forge/ai/ability/AssignGroupAi.java @@ -0,0 +1,33 @@ +package forge.ai.ability; + +import java.util.List; +import java.util.Map; + +import com.google.common.collect.Iterables; + +import forge.ai.SpellAbilityAi; +import forge.game.player.Player; +import forge.game.spellability.SpellAbility; + +public class AssignGroupAi extends SpellAbilityAi { + + protected boolean canPlayAI(Player ai, SpellAbility sa) { + // TODO: Currently this AI relies on the card-specific limiting hints (NeedsToPlay / NeedsToPlayVar), + // otherwise the AI considers the card playable. + + return true; + } + + public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, List spells, Map params) { + final String logic = sa.getParamOrDefault("AILogic", ""); + + if (logic.equals("FriendOrFoe")) { + if (params.containsKey("Affected") && spells.size() >= 2) { + Player t = (Player) params.get("Affected"); + return spells.get(player.isOpponentOf(t) ? 1 : 0); + } + } + + return Iterables.getFirst(spells, null); + } +} diff --git a/forge-ai/src/main/java/forge/ai/ability/CanPlayAsDrawbackAi.java b/forge-ai/src/main/java/forge/ai/ability/CanPlayAsDrawbackAi.java index 0b4cf77f7c9..96876913dd9 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CanPlayAsDrawbackAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CanPlayAsDrawbackAi.java @@ -6,6 +6,7 @@ import forge.game.player.Player; import forge.game.spellability.SpellAbility; import java.util.List; +import java.util.Map; public class CanPlayAsDrawbackAi extends SpellAbilityAi { @@ -37,7 +38,8 @@ public class CanPlayAsDrawbackAi extends SpellAbilityAi { @Override - public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, List spells) { + public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, List spells, + Map params) { // This might be called from CopySpellAbilityEffect - to hide warning (for having no overload) use this simple overload return spells.get(0); } diff --git a/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java b/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java index 05ba5338e55..af986809b36 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChooseGenericEffectAi.java @@ -1,6 +1,7 @@ package forge.ai.ability; import java.util.List; +import java.util.Map; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; @@ -79,7 +80,8 @@ public class ChooseGenericEffectAi extends SpellAbilityAi { } @Override - public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, List spells) { + public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, List spells, + Map params) { Card host = sa.getHostCard(); final String sourceName = ComputerUtilAbility.getAbilitySourceName(sa); final Game game = host.getGame(); diff --git a/forge-ai/src/main/java/forge/ai/ability/CopySpellAbilityAi.java b/forge-ai/src/main/java/forge/ai/ability/CopySpellAbilityAi.java index 4471074c3f5..55a0804a562 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CopySpellAbilityAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CopySpellAbilityAi.java @@ -7,6 +7,7 @@ import forge.game.player.PlayerActionConfirmMode; import forge.game.spellability.SpellAbility; import java.util.List; +import java.util.Map; public class CopySpellAbilityAi extends SpellAbilityAi { @@ -36,7 +37,8 @@ public class CopySpellAbilityAi extends SpellAbilityAi { } @Override - public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, List spells) { + public SpellAbility chooseSingleSpellAbility(Player player, SpellAbility sa, List spells, + Map params) { return spells.get(0); } diff --git a/forge-game/src/main/java/forge/game/GameEntity.java b/forge-game/src/main/java/forge/game/GameEntity.java index 61c5ad6457a..cd57b92a10c 100644 --- a/forge-game/src/main/java/forge/game/GameEntity.java +++ b/forge-game/src/main/java/forge/game/GameEntity.java @@ -25,6 +25,7 @@ import forge.game.card.CounterType; import forge.game.event.GameEventCardAttachment; import forge.game.event.GameEventCardAttachment.AttachMethod; import forge.game.keyword.Keyword; +import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.trigger.TriggerType; import forge.util.collect.FCollection; @@ -365,7 +366,7 @@ public abstract class GameEntity extends GameObject implements IIdentifiable { abstract public void setCounters(final Map allCounters); abstract public boolean canReceiveCounters(final CounterType type); - abstract public void addCounter(final CounterType counterType, final int n, final Card source, final boolean applyMultiplier, final boolean fireEvents); + abstract public void addCounter(final CounterType counterType, final int n, final Player source, final boolean applyMultiplier, final boolean fireEvents); abstract public void subtractCounter(final CounterType counterName, final int n); abstract public void clearCounters(); diff --git a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java index e68d8fb454a..b068872a5b4 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java @@ -256,7 +256,7 @@ public final class AbilityFactory { } } - if (api == ApiType.Charm || api == ApiType.GenericChoice) { + if (api == ApiType.Charm || api == ApiType.GenericChoice || api == ApiType.AssignGroup) { final String key = "Choices"; if (mapParams.containsKey(key)) { List names = Lists.newArrayList(mapParams.get(key).split(",")); diff --git a/forge-game/src/main/java/forge/game/ability/ApiType.java b/forge-game/src/main/java/forge/game/ability/ApiType.java index ad4f48c739c..fc8d9ea98d7 100644 --- a/forge-game/src/main/java/forge/game/ability/ApiType.java +++ b/forge-game/src/main/java/forge/game/ability/ApiType.java @@ -21,6 +21,7 @@ public enum ApiType { AnimateAll (AnimateAllEffect.class), Attach (AttachEffect.class), Ascend (AscendEffect.class), + AssignGroup (AssignGroupEffect.class), Balance (BalanceEffect.class), BecomeMonarch (BecomeMonarchEffect.class), BecomesBlocked (BecomesBlockedEffect.class), diff --git a/forge-game/src/main/java/forge/game/ability/effects/ActivateAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ActivateAbilityEffect.java index fc0aae36d17..3114cf48501 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ActivateAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ActivateAbilityEffect.java @@ -12,6 +12,7 @@ import forge.util.Lang; import org.apache.commons.lang3.StringUtils; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import java.util.List; @@ -49,7 +50,8 @@ public class ActivateAbilityEffect extends SpellAbilityEffect { if (possibleAb.isEmpty()) { continue; } - SpellAbility manaAb = p.getController().chooseSingleSpellForEffect(possibleAb, sa, "Choose a mana ability:"); + SpellAbility manaAb = p.getController().chooseSingleSpellForEffect( + possibleAb, sa, "Choose a mana ability:", ImmutableMap.of()); p.getController().playChosenSpellAbility(manaAb); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/AssignGroupEffect.java b/forge-game/src/main/java/forge/game/ability/effects/AssignGroupEffect.java new file mode 100644 index 00000000000..eb53cecf76b --- /dev/null +++ b/forge-game/src/main/java/forge/game/ability/effects/AssignGroupEffect.java @@ -0,0 +1,74 @@ +package forge.game.ability.effects; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; + +import forge.game.Game; +import forge.game.GameObject; +import forge.game.ability.AbilityUtils; +import forge.game.ability.SpellAbilityEffect; +import forge.game.card.Card; +import forge.game.player.Player; +import forge.game.spellability.SpellAbility; + +public class AssignGroupEffect extends SpellAbilityEffect { + + /* (non-Javadoc) + * @see forge.game.ability.SpellAbilityEffect#getStackDescription(forge.game.spellability.SpellAbility) + */ + @Override + protected String getStackDescription(SpellAbility sa) { + return sa.getDescription(); + } + + /* + * (non-Javadoc) + * @see forge.game.ability.SpellAbilityEffect#resolve(forge.game.spellability.SpellAbility) + */ + @Override + public void resolve(SpellAbility sa) { + final Card host = sa.getHostCard(); + final Game game = host.getGame(); + + List defined = getDefinedOrTargeted(sa, "Defined"); + + final List abilities = Lists.newArrayList(sa.getAdditionalAbilityList("Choices")); + + Player chooser = sa.getActivatingPlayer(); + if (sa.hasParam("Chooser")) { + final String choose = sa.getParam("Chooser"); + chooser = AbilityUtils.getDefinedPlayers(sa.getHostCard(), choose, sa).get(0); + } + + Multimap result = ArrayListMultimap.create(); + + for (GameObject g : defined) { + final String title = "Choose ability for " + g.toString(); + Map params = Maps.newHashMap(); + params.put("Affected", g); + + result.put(chooser.getController().chooseSingleSpellForEffect(abilities, sa, title, params), g); + } + + // in order of choice list + for (SpellAbility s : abilities) { + // is that in Player order? + Collection l = result.get(s); + + host.addRemembered(l); + AbilityUtils.resolve(s); + host.removeRemembered(l); + + // this will refresh continuous abilities for players and permanents. + game.getAction().checkStaticAbilities(); + game.getTriggerHandler().resetActiveTriggers(false); + } + } + +} diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java index df665e7a7cb..096e780d397 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java @@ -484,7 +484,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect { } if (sa.hasParam("WithCounters")) { String[] parse = sa.getParam("WithCounters").split("_"); - tgtC.addEtbCounter(CounterType.getType(parse[0]), Integer.parseInt(parse[1]), hostCard); + tgtC.addEtbCounter(CounterType.getType(parse[0]), Integer.parseInt(parse[1]), player); } if (sa.hasParam("GainControl")) { if (sa.hasParam("NewController")) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChooseGenericEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChooseGenericEffect.java index 7cb835542b6..23ab1ad6b46 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChooseGenericEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChooseGenericEffect.java @@ -1,5 +1,6 @@ package forge.game.ability.effects; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; @@ -65,7 +66,8 @@ public class ChooseGenericEffect extends SpellAbilityEffect { int idxChosen = MyRandom.getRandom().nextInt(abilities.size()); chosenSA = abilities.get(idxChosen); } else { - chosenSA = p.getController().chooseSingleSpellForEffect(abilities, sa, "Choose one"); + chosenSA = p.getController().chooseSingleSpellForEffect(abilities, sa, "Choose one", + ImmutableMap.of()); } if (chosenSA != null) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java index c42e215fab3..2c026736c05 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CopyPermanentEffect.java @@ -167,12 +167,18 @@ public class CopyPermanentEffect extends SpellAbilityEffect { } } } else if (sa.hasParam("Choices")) { + Player chooser = activator; + if (sa.hasParam("Chooser")) { + final String choose = sa.getParam("Chooser"); + chooser = AbilityUtils.getDefinedPlayers(sa.getHostCard(), choose, sa).get(0); + } + CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield); choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host); if (!choices.isEmpty()) { String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : "Choose a card "; - Card choosen = activator.getController().chooseSingleEntityForEffect(choices, sa, title, false); + Card choosen = chooser.getController().chooseSingleEntityForEffect(choices, sa, title, false); if (choosen != null) { tgtCards.add(choosen); diff --git a/forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java index aa4d49c6080..4d74f5e274e 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CopySpellAbilityEffect.java @@ -1,5 +1,6 @@ package forge.game.ability.effects; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @@ -83,7 +84,8 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect { for (int multi = 0; multi < spellCount && !tgtSpells.isEmpty(); multi++) { String prompt = "Select " + Lang.getOrdinal(multi + 1) + " spell to copy to stack"; - SpellAbility chosen = controller.getController().chooseSingleSpellForEffect(tgtSpells, sa, prompt); + SpellAbility chosen = controller.getController().chooseSingleSpellForEffect(tgtSpells, sa, prompt, + ImmutableMap.of()); SpellAbility copiedSpell = CardFactory.copySpellAbilityAndSrcCard(card, chosen.getHostCard(), chosen, true); copiedSpell.getHostCard().setController(card.getController(), card.getGame().getNextTimestamp()); copiedSpell.setActivatingPlayer(controller); @@ -92,7 +94,8 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect { } } else if (sa.hasParam("CopyForEachCanTarget")) { - SpellAbility chosenSA = controller.getController().chooseSingleSpellForEffect(tgtSpells, sa, "Select a spell to copy"); + SpellAbility chosenSA = controller.getController().chooseSingleSpellForEffect(tgtSpells, sa, + "Select a spell to copy", ImmutableMap.of()); chosenSA.setActivatingPlayer(controller); // Find subability or rootability that has targets SpellAbility targetedSA = chosenSA; @@ -152,7 +155,8 @@ public class CopySpellAbilityEffect extends SpellAbilityEffect { } } else { - SpellAbility chosenSA = controller.getController().chooseSingleSpellForEffect(tgtSpells, sa, "Select a spell to copy"); + SpellAbility chosenSA = controller.getController().chooseSingleSpellForEffect(tgtSpells, sa, + "Select a spell to copy", ImmutableMap.of()); chosenSA.setActivatingPlayer(controller); for (int i = 0; i < amount; i++) { copies.add(CardFactory.copySpellAbilityAndSrcCard(card, chosenSA.getHostCard(), chosenSA, true)); diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersMoveEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersMoveEffect.java index 5c876c6720b..cea93674399 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersMoveEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersMoveEffect.java @@ -145,7 +145,7 @@ public class CountersMoveEffect extends SpellAbilityEffect { } if (csum > 0) { - dest.addCounter(cType, csum, host, true); + dest.addCounter(cType, csum, player, true); game.updateLastStateForCard(dest); } return; @@ -201,7 +201,7 @@ public class CountersMoveEffect extends SpellAbilityEffect { if (cnum > 0) { source.subtractCounter(cType, cnum); - dest.addCounter(cType, cnum, host, true); + dest.addCounter(cType, cnum, player, true); game.updateLastStateForCard(dest); updateSource = true; } @@ -262,7 +262,7 @@ public class CountersMoveEffect extends SpellAbilityEffect { if (source.getCounters(cType) >= cntToMove) { source.subtractCounter(cType, cntToMove); - dest.addCounter(cType, cntToMove, host, true); + dest.addCounter(cType, cntToMove, player, true); game.updateLastStateForCard(dest); } } else { @@ -296,7 +296,7 @@ public class CountersMoveEffect extends SpellAbilityEffect { sa, sb.toString(), 0, Math.min(tgtCounters.get(chosenType), cntToMove), params); if (chosenAmount > 0) { - dest.addCounter(chosenType, chosenAmount, host, true); + dest.addCounter(chosenType, chosenAmount, player, true); source.subtractCounter(chosenType, chosenAmount); game.updateLastStateForCard(dest); cntToMove -= chosenAmount; diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersMultiplyEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersMultiplyEffect.java index 08117188072..8eaced12614 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersMultiplyEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersMultiplyEffect.java @@ -7,6 +7,7 @@ import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.card.CounterType; +import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.util.Lang; @@ -37,6 +38,7 @@ public class CountersMultiplyEffect extends SpellAbilityEffect { public void resolve(SpellAbility sa) { final Card host = sa.getHostCard(); final Game game = host.getGame(); + final Player player = sa.getActivatingPlayer(); final CounterType counterType = getCounterType(sa); final int n = Integer.valueOf(sa.getParamOrDefault("Multiplier", "2")) - 1; @@ -50,10 +52,10 @@ public class CountersMultiplyEffect extends SpellAbilityEffect { continue; } if (counterType != null) { - gameCard.addCounter(counterType, gameCard.getCounters(counterType) * n, host, true); + gameCard.addCounter(counterType, gameCard.getCounters(counterType) * n, player, true); } else { for (Map.Entry e : gameCard.getCounters().entrySet()) { - gameCard.addCounter(e.getKey(), e.getValue() * n, host, true); + gameCard.addCounter(e.getKey(), e.getValue() * n, player, true); } } game.updateLastStateForCard(gameCard); diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersNoteEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersNoteEffect.java index b5190983232..21a7f4c9d2c 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersNoteEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersNoteEffect.java @@ -6,6 +6,7 @@ import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.card.CardCollection; import forge.game.card.CounterType; +import forge.game.player.Player; import forge.game.spellability.SpellAbility; public class CountersNoteEffect extends SpellAbilityEffect { @@ -26,7 +27,7 @@ public class CountersNoteEffect extends SpellAbilityEffect { if (mode.equals(MODE_STORE)) { noteCounters(c, source); } else if (mode.equals(MODE_LOAD)) { - loadCounters(c, source); + loadCounters(c, source, sa.getActivatingPlayer()); } } } @@ -39,11 +40,11 @@ public class CountersNoteEffect extends SpellAbilityEffect { } } - private void loadCounters(Card notee, Card source) { + private void loadCounters(Card notee, Card source, final Player p) { for(Entry svar : source.getSVars().entrySet()) { String key = svar.getKey(); if (key.startsWith(NOTE_COUNTERS)) { - notee.addCounter(CounterType.getType(key.substring(NOTE_COUNTERS.length())), Integer.parseInt(svar.getValue()), source, false); + notee.addCounter(CounterType.getType(key.substring(NOTE_COUNTERS.length())), Integer.parseInt(svar.getValue()), p, false); } // TODO Probably should "remove" the svars that were temporarily used } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersProliferateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersProliferateEffect.java index 4b317322118..f5ef5b95ed8 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersProliferateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersProliferateEffect.java @@ -24,6 +24,7 @@ public class CountersProliferateEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { + final Player p = sa.getActivatingPlayer(); final Card host = sa.getHostCard(); final Game game = host.getGame(); Player controller = host.getController(); @@ -32,10 +33,10 @@ public class CountersProliferateEffect extends SpellAbilityEffect { return; for(Entry ge: proliferateChoice.entrySet()) { if( ge.getKey() instanceof Player ) - ((Player) ge.getKey()).addCounter(ge.getValue(), 1, host, true); + ((Player) ge.getKey()).addCounter(ge.getValue(), 1, p, true); else if( ge.getKey() instanceof Card) { Card c = (Card) ge.getKey(); - c.addCounter(ge.getValue(), 1, host, true); + c.addCounter(ge.getValue(), 1, p, true); game.updateLastStateForCard(c); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersPutAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersPutAllEffect.java index 29843622384..cf27b138ff8 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersPutAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersPutAllEffect.java @@ -38,30 +38,37 @@ public class CountersPutAllEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { final Card host = sa.getHostCard(); + final Player activator = sa.getActivatingPlayer(); final String type = sa.getParam("CounterType"); final int counterAmount = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("CounterNum"), sa); final String valid = sa.getParam("ValidCards"); final ZoneType zone = sa.hasParam("ValidZone") ? ZoneType.smartValueOf(sa.getParam("ValidZone")) : ZoneType.Battlefield; - final Game game = sa.getActivatingPlayer().getGame(); + final Game game = activator.getGame(); if (counterAmount <= 0) { return; } CardCollectionView cards = game.getCardsIn(zone); - cards = CardLists.getValidCards(cards, valid, sa.getHostCard().getController(), sa.getHostCard()); + cards = CardLists.getValidCards(cards, valid, host.getController(), sa.getHostCard()); if (sa.usesTargeting()) { final Player pl = sa.getTargets().getFirstTargetedPlayer(); cards = CardLists.filterControlledBy(cards, pl); } + Player placer = activator; + if (sa.hasParam("Placer")) { + final String pstr = sa.getParam("Placer"); + placer = AbilityUtils.getDefinedPlayers(host, pstr, sa).get(0); + } + for (final Card tgtCard : cards) { if (game.getZoneOf(tgtCard).is(ZoneType.Battlefield)) { - tgtCard.addCounter(CounterType.valueOf(type), counterAmount, host, true); + tgtCard.addCounter(CounterType.valueOf(type), counterAmount, placer, true); } else { // adding counters to something like re-suspend cards - tgtCard.addCounter(CounterType.valueOf(type), counterAmount, host, false); + tgtCard.addCounter(CounterType.valueOf(type), counterAmount, placer, false); } game.updateLastStateForCard(tgtCard); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java index d58b3ab209c..5d73ca81e51 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersPutEffect.java @@ -110,6 +110,12 @@ public class CountersPutEffect extends SpellAbilityEffect { } } + Player placer = activator; + if (sa.hasParam("Placer")) { + final String pstr = sa.getParam("Placer"); + placer = AbilityUtils.getDefinedPlayers(sa.getHostCard(), pstr, sa).get(0); + } + final boolean etbcounter = sa.hasParam("ETB"); final boolean remember = sa.hasParam("RememberCounters"); final boolean rememberCards = sa.hasParam("RememberCards"); @@ -155,10 +161,10 @@ public class CountersPutEffect extends SpellAbilityEffect { if (eachExistingCounter) { for(CounterType ct : choices) { if (obj instanceof Player) { - ((Player) obj).addCounter(ct, counterAmount, card, true); + ((Player) obj).addCounter(ct, counterAmount, placer, true); } if (obj instanceof Card) { - ((Card) obj).addCounter(ct, counterAmount, card, true); + ((Card) obj).addCounter(ct, counterAmount, placer, true); } } continue; @@ -232,9 +238,9 @@ public class CountersPutEffect extends SpellAbilityEffect { final Zone zone = tgtCard.getGame().getZoneOf(tgtCard); if (zone == null || zone.is(ZoneType.Battlefield) || zone.is(ZoneType.Stack)) { if (etbcounter) { - tgtCard.addEtbCounter(counterType, counterAmount, card); + tgtCard.addEtbCounter(counterType, counterAmount, placer); } else { - tgtCard.addCounter(counterType, counterAmount, card, true); + tgtCard.addCounter(counterType, counterAmount, placer, true); } if (remember) { final int value = tgtCard.getTotalCountersToAdd(); @@ -263,9 +269,9 @@ public class CountersPutEffect extends SpellAbilityEffect { // adding counters to something like re-suspend cards // etbcounter should apply multiplier if (etbcounter) { - tgtCard.addEtbCounter(counterType, counterAmount, card); + tgtCard.addEtbCounter(counterType, counterAmount, placer); } else { - tgtCard.addCounter(counterType, counterAmount, card, false); + tgtCard.addCounter(counterType, counterAmount, placer, false); } } game.updateLastStateForCard(tgtCard); @@ -273,7 +279,7 @@ public class CountersPutEffect extends SpellAbilityEffect { } else if (obj instanceof Player) { // Add Counters to players! Player pl = (Player) obj; - pl.addCounter(counterType, counterAmount, card, true); + pl.addCounter(counterType, counterAmount, placer, true); } } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/CountersPutOrRemoveEffect.java b/forge-game/src/main/java/forge/game/ability/effects/CountersPutOrRemoveEffect.java index 9273c1ce2c6..979e383ab54 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/CountersPutOrRemoveEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/CountersPutOrRemoveEffect.java @@ -5,6 +5,7 @@ import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; import forge.game.card.CounterType; +import forge.game.player.Player; import forge.game.player.PlayerController; import forge.game.player.PlayerController.BinaryChoiceType; import forge.game.spellability.SpellAbility; @@ -81,8 +82,8 @@ public class CountersPutOrRemoveEffect extends SpellAbilityEffect { private void addOrRemoveCounter(final SpellAbility sa, final Card tgtCard, CounterType ctype, final int counterAmount) { - PlayerController pc = sa.getActivatingPlayer().getController(); - final Card source = sa.getHostCard(); + final Player pl = sa.getActivatingPlayer(); + final PlayerController pc = pl.getController(); Map params = Maps.newHashMap(); params.put("Target", tgtCard); @@ -105,7 +106,7 @@ public class CountersPutOrRemoveEffect extends SpellAbilityEffect { boolean apply = zone == null || zone.is(ZoneType.Battlefield) || zone.is(ZoneType.Stack); - tgtCard.addCounter(chosenType, counterAmount, source, apply); + tgtCard.addCounter(chosenType, counterAmount, pl, apply); } else { tgtCard.subtractCounter(chosenType, counterAmount); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java index 80af5a1622a..365adf0855a 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java @@ -377,7 +377,7 @@ public class DigEffect extends SpellAbilityEffect { } } else if (destZone2 == ZoneType.Exile) { if (sa.hasParam("ExileWithCounter")) { - c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, effectHost, true); + c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, player, true); } c.setExiledWith(effectHost); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/ExploreEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ExploreEffect.java index 942512a5ad7..c06be791574 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ExploreEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ExploreEffect.java @@ -44,7 +44,6 @@ public class ExploreEffect extends SpellAbilityEffect { @Override public void resolve(SpellAbility sa) { // check if only the activating player counts - final Card card = sa.getHostCard(); final Player pl = sa.getActivatingPlayer(); final PlayerController pc = pl.getController(); final Game game = pl.getGame(); @@ -78,7 +77,7 @@ public class ExploreEffect extends SpellAbilityEffect { // if the card is not more in the game anymore // this might still return true but its no problem if (game.getZoneOf(gamec).is(ZoneType.Battlefield) && gamec.getTimestamp() == c.getTimestamp()) { - c.addCounter(CounterType.P1P1, 1, card, true); + c.addCounter(CounterType.P1P1, 1, pl, true); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java index f3809584b62..7b371dc58c4 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java @@ -43,7 +43,7 @@ public class SacrificeEffect extends SpellAbilityEffect { return; } } else if (sa.hasParam("CumulativeUpkeep")) { - card.addCounter(CounterType.AGE, 1, card, true); + card.addCounter(CounterType.AGE, 1, activator, true); Cost cumCost = new Cost(sa.getParam("CumulativeUpkeep"), true); Cost payCost = new Cost(ManaCost.ZERO, true); int n = card.getCounters(CounterType.AGE); diff --git a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java index 91695cd6580..5562acf460c 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SetStateEffect.java @@ -104,7 +104,7 @@ public class SetStateEffect extends SpellAbilityEffect { } game.fireEvent(new GameEventCardStatsChanged(tgt)); if (sa.hasParam("Mega")) { - tgt.addCounter(CounterType.P1P1, 1, host, true); + tgt.addCounter(CounterType.P1P1, 1, p, true); } if (remChanged) { host.addRemembered(tgt); diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 5720840885d..f8607957d2b 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -249,7 +249,7 @@ public class Card extends GameEntity implements Comparable { private CardRules cardRules; private final CardView view; - private Table etbCounters = HashBasedTable.create(); + private Table etbCounters = HashBasedTable.create(); private SpellAbility[] basicLandAbilities = new SpellAbility[MagicColor.WUBRG.length]; @@ -746,6 +746,18 @@ public class Card extends GameEntity implements Comparable { view.updateRemembered(this); } } + + public final void removeRemembered(final Iterable list) { + boolean changed = false; + for (T o : list) { + if (rememberedObjects.remove(o)) { + changed = true; + } + } + if (changed) { + view.updateRemembered(this); + } + } public final void clearRemembered() { if (rememberedObjects.isEmpty()) { return; } rememberedObjects.clear(); @@ -1048,15 +1060,15 @@ public class Card extends GameEntity implements Comparable { countersAdded = value; } - public final void addCounter(final CounterType counterType, final int n, final Card source, final boolean applyMultiplier) { + public final void addCounter(final CounterType counterType, final int n, final Player source, final boolean applyMultiplier) { addCounter(counterType, n, source, applyMultiplier, true); } - public final void addCounterFireNoEvents(final CounterType counterType, final int n, final Card source, final boolean applyMultiplier) { + public final void addCounterFireNoEvents(final CounterType counterType, final int n, final Player source, final boolean applyMultiplier) { addCounter(counterType, n, source, applyMultiplier, false); } @Override - public void addCounter(final CounterType counterType, final int n, final Card source, final boolean applyMultiplier, final boolean fireEvents) { + public void addCounter(final CounterType counterType, final int n, final Player source, final boolean applyMultiplier, final boolean fireEvents) { int addAmount = n; if(addAmount < 0) { addAmount = 0; // As per rule 107.1b @@ -4625,7 +4637,7 @@ public class Card extends GameEntity implements Comparable { if (isInPlay()) { if (wither) { - addCounter(CounterType.M1M1, damageIn, source, true); + addCounter(CounterType.M1M1, damageIn, source.getController(), true); damageType = DamageType.M1M1Counters; } else { @@ -5707,11 +5719,7 @@ public class Card extends GameEntity implements Comparable { * and when the Card really enters the Battlefield with the counters * @return map of counters */ - public final void addEtbCounter(CounterType type, Integer val) { - addEtbCounter(type, val, this); - } - - public final void addEtbCounter(CounterType type, Integer val, final Card source) { + public final void addEtbCounter(CounterType type, Integer val, final Player source) { int old = etbCounters.contains(source, type) ? etbCounters.get(source, type) : 0; etbCounters.put(source, type, old + val); } @@ -5721,7 +5729,7 @@ public class Card extends GameEntity implements Comparable { } public final void putEtbCounters() { - for (Table.Cell e : etbCounters.cellSet()) { + for (Table.Cell e : etbCounters.cellSet()) { this.addCounter(e.getColumnKey(), e.getValue(), e.getRowKey(), true); } } 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 c4a17b85912..4819a6c7914 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -4027,12 +4027,8 @@ public class CardFactoryUtil { @Override public void run() { - if (card.isCreature()) { - card.addCounter(CounterType.P1P1, card.getSunburstValue(), card, true); - } else { - card.addCounter(CounterType.CHARGE, card.getSunburstValue(), card, true); - } - + CounterType t = card.isCreature() ? CounterType.P1P1 : CounterType.CHARGE; + card.addCounter(t, card.getSunburstValue(), card.getController(), true); } }; @@ -4091,9 +4087,9 @@ public class CardFactoryUtil { final Card c = game.getAction().exile(this.getHostCard(), this); int counters = AbilityUtils.calculateAmount(c, k[1], this); - c.addCounter(CounterType.TIME, counters, c, true); + c.addCounter(CounterType.TIME, counters, getActivatingPlayer(), true); - String sb = TextUtil.concatWithSpace(this.getActivatingPlayer().toString(),"has suspended", c.getName(), "with", String.valueOf(counters),"time counters on it."); + String sb = TextUtil.concatWithSpace(getActivatingPlayer().toString(),"has suspended", c.getName(), "with", String.valueOf(counters),"time counters on it."); game.getGameLog().add(GameLogEntryType.STACK_RESOLVE, sb); } }; diff --git a/forge-game/src/main/java/forge/game/cost/CostPutCounter.java b/forge-game/src/main/java/forge/game/cost/CostPutCounter.java index be83e5d0490..c33bbea5441 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPutCounter.java +++ b/forge-game/src/main/java/forge/game/cost/CostPutCounter.java @@ -188,7 +188,7 @@ public class CostPutCounter extends CostPartWithList { */ @Override protected Card doPayment(SpellAbility ability, Card targetCard){ - targetCard.addCounter(this.getCounter(), 1, ability.getHostCard(), false); + targetCard.addCounter(this.getCounter(), 1, ability.getActivatingPlayer(), false); return targetCard; } diff --git a/forge-game/src/main/java/forge/game/cost/CostRemoveCounter.java b/forge-game/src/main/java/forge/game/cost/CostRemoveCounter.java index 9d30526dad1..d4b2d6b9c5c 100644 --- a/forge-game/src/main/java/forge/game/cost/CostRemoveCounter.java +++ b/forge-game/src/main/java/forge/game/cost/CostRemoveCounter.java @@ -114,7 +114,7 @@ public class CostRemoveCounter extends CostPartWithList { public final void refund(final Card source) { int refund = this.getCardList().size() == 1 ? this.cntRemoved : 1; // is wrong for Ooze Flux and Novijen Sages for (final Card c : this.getCardList()) { - c.addCounter(this.counter, refund, source, false); + c.addCounter(this.counter, refund, source.getController(), false); } } 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 f24bf5b3113..ef98aee7dcd 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -876,12 +876,12 @@ public class Player extends GameEntity implements Comparable { return true; } - public final void addCounter(final CounterType counterType, final int n, final Card source, final boolean applyMultiplier) { + public final void addCounter(final CounterType counterType, final int n, final Player source, final boolean applyMultiplier) { addCounter(counterType, n, source, applyMultiplier, true); } @Override - public void addCounter(CounterType counterType, int n, final Card source, boolean applyMultiplier, boolean fireEvents) { + public void addCounter(CounterType counterType, int n, final Player source, boolean applyMultiplier, boolean fireEvents) { if (!canReceiveCounters(counterType)) { return; } @@ -983,7 +983,7 @@ public class Player extends GameEntity implements Comparable { } public final void addPoisonCounters(final int num, final Card source) { int oldPoison = getCounters(CounterType.POISON); - addCounter(CounterType.POISON, num, source, false, true); + addCounter(CounterType.POISON, num, source.getController(), false, true); if (oldPoison != getCounters(CounterType.POISON)) { game.fireEvent(new GameEventPlayerPoisoned(this, source, oldPoison, num)); diff --git a/forge-game/src/main/java/forge/game/player/PlayerController.java b/forge-game/src/main/java/forge/game/player/PlayerController.java index 40849fccd4f..3d02dcea56d 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerController.java +++ b/forge-game/src/main/java/forge/game/player/PlayerController.java @@ -107,7 +107,8 @@ public abstract class PlayerController { public final T chooseSingleEntityForEffect(FCollectionView optionList, SpellAbility sa, String title) { return chooseSingleEntityForEffect(optionList, null, sa, title, false, null); } public final T chooseSingleEntityForEffect(FCollectionView optionList, SpellAbility sa, String title, boolean isOptional) { return chooseSingleEntityForEffect(optionList, null, sa, title, isOptional, null); } public abstract T chooseSingleEntityForEffect(FCollectionView optionList, DelayedReveal delayedReveal, SpellAbility sa, String title, boolean isOptional, Player relatedPlayer); - public abstract SpellAbility chooseSingleSpellForEffect(List spells, SpellAbility sa, String title); + public abstract SpellAbility chooseSingleSpellForEffect(List spells, SpellAbility sa, String title, + Map params); public abstract List chooseEntitiesForEffect(FCollectionView optionList, DelayedReveal delayedReveal, SpellAbility sa, String title, Player relatedPlayer); diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedOnce.java b/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedOnce.java index 74b5f898122..549a3d81670 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedOnce.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerCounterAddedOnce.java @@ -53,15 +53,21 @@ public class TriggerCounterAddedOnce extends Trigger { /** {@inheritDoc} */ @Override public final boolean performTest(final Map runParams2) { - final CounterType addedType = (CounterType) runParams2.get("CounterType"); + if (hasParam("CounterType")) { + final CounterType addedType = (CounterType) runParams2.get("CounterType"); + final String type = getParam("CounterType"); + if (!type.equals(addedType.toString())) { + return false; + } + } if (hasParam("ValidCard")) { if (!runParams2.containsKey("Card")) return false; final Card addedTo = (Card) runParams2.get("Card"); - if (!addedTo.isValid(getParam("ValidCard").split(","), this.getHostCard().getController(), - this.getHostCard(), null)) { + if (!addedTo.isValid(getParam("ValidCard").split(","), getHostCard().getController(), + getHostCard(), null)) { return false; } } @@ -71,8 +77,8 @@ public class TriggerCounterAddedOnce extends Trigger { return false; final Player addedTo = (Player) runParams2.get("Player"); - if (!addedTo.isValid(getParam("ValidPlayer").split(","), this.getHostCard().getController(), - this.getHostCard(), null)) { + if (!addedTo.isValid(getParam("ValidPlayer").split(","), getHostCard().getController(), + getHostCard(), null)) { return false; } } @@ -81,21 +87,14 @@ public class TriggerCounterAddedOnce extends Trigger { if (!runParams2.containsKey("Source")) return false; - final Card source = (Card) runParams2.get("Source"); + final Player source = (Player) runParams2.get("Source"); if (source == null) { return false; } - if (!source.isValid(getParam("ValidSource").split(","), this.getHostCard().getController(), - this.getHostCard(), null)) { - return false; - } - } - - if (hasParam("CounterType")) { - final String type = getParam("CounterType"); - if (!type.equals(addedType.toString())) { + if (!source.isValid(getParam("ValidSource").split(","), getHostCard().getController(), + getHostCard(), null)) { return false; } } diff --git a/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java b/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java index 7fea93ce0e4..8508b594ac1 100644 --- a/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java +++ b/forge-gui-desktop/src/test/java/forge/ai/simulation/GameSimulatorTest.java @@ -215,7 +215,7 @@ public class GameSimulatorTest extends SimulationTestCase { Game game = initAndCreateGame(); Player p = game.getPlayers().get(1); Card sorin = addCard("Sorin, Solemn Visitor", p); - sorin.addCounter(CounterType.LOYALTY, 5, sorin, false); + sorin.addCounter(CounterType.LOYALTY, 5, p, false); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getAction().checkStateEffects(true); @@ -259,7 +259,7 @@ public class GameSimulatorTest extends SimulationTestCase { String bearCardName = "Runeclaw Bear"; addCard(bearCardName, p); Card gideon = addCard("Gideon, Ally of Zendikar", p); - gideon.addCounter(CounterType.LOYALTY, 4, gideon, false); + gideon.addCounter(CounterType.LOYALTY, 4, p, false); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getAction().checkStateEffects(true); @@ -378,7 +378,7 @@ public class GameSimulatorTest extends SimulationTestCase { Game game = initAndCreateGame(); Player p = game.getPlayers().get(1); Card sarkhan = addCard(sarkhanCardName, p); - sarkhan.addCounter(CounterType.LOYALTY, 4, sarkhan, false); + sarkhan.addCounter(CounterType.LOYALTY, 4, p, false); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getAction().checkStateEffects(true); @@ -412,7 +412,7 @@ public class GameSimulatorTest extends SimulationTestCase { addCard(ornithoperCardName, p); addCard(bearCardName, p); Card ajani = addCard(ajaniCardName, p); - ajani.addCounter(CounterType.LOYALTY, 4, ajani, false); + ajani.addCounter(CounterType.LOYALTY, 4, p, false); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getAction().checkStateEffects(true); @@ -443,7 +443,7 @@ public class GameSimulatorTest extends SimulationTestCase { SpellAbility boltSA = boltCard.getFirstSpellAbility(); Card ajani = addCard(ajaniCardName, p); - ajani.addCounter(CounterType.LOYALTY, 8, ajani, false); + ajani.addCounter(CounterType.LOYALTY, 8, p, false); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getAction().checkStateEffects(true); @@ -493,7 +493,7 @@ public class GameSimulatorTest extends SimulationTestCase { addCard("Swamp", p); addCard("Swamp", p); Card depths = addCard("Dark Depths", p); - depths.addCounter(CounterType.ICE, 10, depths, false); + depths.addCounter(CounterType.ICE, 10, p, false); Card thespian = addCard("Thespian's Stage", p); game.getPhaseHandler().devModeSet(PhaseType.MAIN2, p); game.getAction().checkStateEffects(true); diff --git a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java index 0f237eadf20..0994bcc54f1 100644 --- a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java +++ b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java @@ -167,7 +167,8 @@ public class PlayerControllerForTests extends PlayerController { } @Override - public SpellAbility chooseSingleSpellForEffect(List spells, SpellAbility sa, String title) { + public SpellAbility chooseSingleSpellForEffect(List spells, SpellAbility sa, String title, + Map params) { return chooseItem(spells); } diff --git a/forge-gui/res/cardsfolder/d/defiant_greatmaw.txt b/forge-gui/res/cardsfolder/d/defiant_greatmaw.txt index ff594980ec4..d8bb7ad3ec7 100644 --- a/forge-gui/res/cardsfolder/d/defiant_greatmaw.txt +++ b/forge-gui/res/cardsfolder/d/defiant_greatmaw.txt @@ -4,6 +4,6 @@ Types:Creature Hippo PT:4/5 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPutCounter | TriggerDescription$ When CARDNAME enters the battlefield, put two -1/-1 counters on target creature you control. SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature | CounterType$ M1M1 | CounterNum$ 2 -T:Mode$ CounterAddedOnce | ValidCard$ Creature.Self | ValidSource$ Card.YouCtrl | CounterType$ M1M1 | TriggerZones$ Battlefield | Execute$ RemoveCounter | TriggerDescription$ Whenever you put one or more -1/-1 counters on CARDNAME, remove a -1/-1 counter from another target creature you control. +T:Mode$ CounterAddedOnce | ValidCard$ Creature.Self | ValidSource$ You | CounterType$ M1M1 | TriggerZones$ Battlefield | Execute$ RemoveCounter | TriggerDescription$ Whenever you put one or more -1/-1 counters on CARDNAME, remove a -1/-1 counter from another target creature you control. SVar:RemoveCounter:DB$ RemoveCounter | ValidTgts$ Creature.YouCtrl+Other | AITgts$ Creature.counters_GE1_M1M1 | TgtPrompt$ Select another target creature you control | CounterType$ M1M1 | CounterNum$ 1 Oracle:When Defiant Greatmaw enters the battlefield, put two -1/-1 counters on target creature you control.\nWhenever you put one or more -1/-1 counters on Defiant Greatmaw, remove a -1/-1 counter from another target creature you control. diff --git a/forge-gui/res/cardsfolder/h/hapatra_vizier_of_poisons.txt b/forge-gui/res/cardsfolder/h/hapatra_vizier_of_poisons.txt index 74a0f9befe4..bf8ef1713bd 100644 --- a/forge-gui/res/cardsfolder/h/hapatra_vizier_of_poisons.txt +++ b/forge-gui/res/cardsfolder/h/hapatra_vizier_of_poisons.txt @@ -4,7 +4,7 @@ Types:Legendary Creature Human Cleric PT:2/2 T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Opponent | TriggerZones$ Battlefield | OptionalDecider$ You | Execute$ TrigPutCounter | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may put a -1/-1 counter on target creature. SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ M1M1 | CounterNum$ 1 | IsCurse$ True -T:Mode$ CounterAddedOnce | ValidCard$ Creature | ValidSource$ Card.YouCtrl | CounterType$ M1M1 | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever you put one or more -1/-1 counters on a creature, create a 1/1 green Snake creature token with deathtouch. +T:Mode$ CounterAddedOnce | ValidCard$ Creature | ValidSource$ You | CounterType$ M1M1 | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever you put one or more -1/-1 counters on a creature, create a 1/1 green Snake creature token with deathtouch. SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenName$ Snake | TokenTypes$ Creature,Snake | TokenOwner$ You | TokenColors$ Green | TokenPower$ 1 | TokenToughness$ 1 | TokenKeywords$ Deathtouch | TokenImage$ g 1 1 snake AKH DeckHas:Ability$Counters & Ability$Token Oracle:Whenever Hapatra, Vizier of Poisons deals combat damage to a player, you may put a -1/-1 counter on target creature.\nWhenever you put one or more -1/-1 counters on a creature, create a 1/1 green Snake creature token with deathtouch. diff --git a/forge-gui/res/cardsfolder/n/nest_of_scarabs.txt b/forge-gui/res/cardsfolder/n/nest_of_scarabs.txt index 8ef46e2da80..b53230e10d4 100644 --- a/forge-gui/res/cardsfolder/n/nest_of_scarabs.txt +++ b/forge-gui/res/cardsfolder/n/nest_of_scarabs.txt @@ -1,7 +1,7 @@ Name:Nest of Scarabs ManaCost:2 B Types:Enchantment -T:Mode$ CounterAddedOnce | ValidCard$ Creature | ValidSource$ Card.YouCtrl | CounterType$ M1M1 | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever you put one or more -1/-1 counters on a creature, create that many 1/1 black Insect creature tokens. +T:Mode$ CounterAddedOnce | ValidCard$ Creature | ValidSource$ You | CounterType$ M1M1 | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever you put one or more -1/-1 counters on a creature, create that many 1/1 black Insect creature tokens. SVar:TrigToken:DB$ Token | TokenAmount$ X | References$ X | TokenName$ Insect | TokenTypes$ Creature,Insect | TokenOwner$ You | TokenColors$ Black | TokenPower$ 1 | TokenToughness$ 1 | TokenImage$ b 1 1 insect AKH SVar:X:TriggerCount$Amount DeckHints:Ability$Counters diff --git a/forge-gui/res/cardsfolder/o/obelisk_spider.txt b/forge-gui/res/cardsfolder/o/obelisk_spider.txt index 89b2df21f08..6d67d82d05c 100644 --- a/forge-gui/res/cardsfolder/o/obelisk_spider.txt +++ b/forge-gui/res/cardsfolder/o/obelisk_spider.txt @@ -5,7 +5,7 @@ PT:1/4 K:Reach T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Creature | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever CARDNAME deals combat damage to a creature, put a -1/-1 counter on that creature. SVar:TrigPutCounter:DB$PutCounter | Defined$ TriggeredTargetLKICopy | CounterType$ M1M1 | CounterNum$ 1 -T:Mode$ CounterAddedOnce | ValidCard$ Creature | ValidSource$ Card.YouCtrl | CounterType$ M1M1 | TriggerZones$ Battlefield | Execute$ TrigDrain | TriggerDescription$ Whenever you put one or more -1/-1 counters on a creature, each opponent loses 1 life and you gain 1 life. +T:Mode$ CounterAddedOnce | ValidCard$ Creature | ValidSource$ You | CounterType$ M1M1 | TriggerZones$ Battlefield | Execute$ TrigDrain | TriggerDescription$ Whenever you put one or more -1/-1 counters on a creature, each opponent loses 1 life and you gain 1 life. SVar:TrigDrain:DB$ LoseLife | Defined$ Player.Opponent | LifeAmount$ 1 | SubAbility$ DBGainLife SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1 DeckHas:Ability$Counters diff --git a/forge-gui/res/cardsfolder/upcoming/generous_patron.txt b/forge-gui/res/cardsfolder/upcoming/generous_patron.txt index 2dba1257878..521fbf9e2c3 100644 --- a/forge-gui/res/cardsfolder/upcoming/generous_patron.txt +++ b/forge-gui/res/cardsfolder/upcoming/generous_patron.txt @@ -4,7 +4,7 @@ Types:Creature Elf Advisor PT:1/4 T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPut | TriggerDescription$ When CARDNAME enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.) SVar:TrigPut:DB$PutCounter | ValidTgts$ Creature.Other | TgtPrompt$ Select target creature other than CARDNAME | TargetMin$ 0 | TargetMax$ 2 | CounterType$ P1P1 | CounterNum$ 1 -T:Mode$ CounterAddedOnce | ValidCard$ Creature.YouDontCtrl | TriggerZones$ Battlefield | CounterType$ P1P1 | Execute$ DBDraw | TriggerDescription$ Whenever you put one or more counters on a creature you don't control, draw a card. +T:Mode$ CounterAddedOnce | ValidCard$ Creature.YouDontCtrl | ValidSource$ You | TriggerZones$ Battlefield | CounterType$ P1P1 | Execute$ DBDraw | TriggerDescription$ Whenever you put one or more counters on a creature you don't control, draw a card. SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 1 DeckHas:Ability$Counters DeckHints:Ability$Counters diff --git a/forge-gui/res/cardsfolder/upcoming/khorvaths_fury.txt b/forge-gui/res/cardsfolder/upcoming/khorvaths_fury.txt new file mode 100644 index 00000000000..88a9bcf369f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/khorvaths_fury.txt @@ -0,0 +1,16 @@ +Name:Khorvath's Fury +ManaCost:4 R +Types:Sorcery +A:SP$ AssignGroup | Cost$ 4 R | Defined$ Player | Choices$ FriendRepeat,FoeRepeat | AILogic$ FriendOrFoe | SpellDescription$ For each player, choose friend or foe. Each friend discards all cards from their hand, then draws that many cards plus one. CARDNAME deals damage to each foe equal to the number of cards in their hand. +SVar:FriendRepeat:DB$ RepeatEach | RepeatPlayers$ Remembered | ClearRememberedBeforeLoop$ True | RepeatSubAbility$ DBDiscard | StackDescription$ SpellDescription | SpellDescription$ Each friend discards all cards from their hand, then draws that many cards plus one. +SVar:DBDiscard:DB$ Discard | Defined$ Player.IsRemembered | Mode$ Hand | RememberDiscarded$ True | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | NumCards$ X | Defined$ Player.IsRemembered | References$ X | SubAbility$ DBCleanup +SVar:FoeRepeat:DB$ RepeatEach | RepeatPlayers$ Remembered | ClearRememberedBeforeLoop$ True | RepeatSubAbility$ DBDmg | DamageMap$ True | StackDescription$ SpellDescription | SpellDescription$ CARDNAME deals damage to each foe equal to the number of cards in their hand. +SVar:DBDmg:DB$ DealDamage | Defined$ Player.IsRemembered | NumDmg$ Y | References$ Y +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Remembered$Amount.Plus.1 +SVar:Y:Count$ValidHand Card.RememberedPlayerCtrl +SVar:NeedsToPlayVar:Z GE4 +SVar:Z:Count$ValidHand Card.OppCtrl +SVar:Picture:http://www.wizards.com/global/images/magic/general/khorvaths_fury.jpg +Oracle:For each player, choose friend or foe. Each friend discards all cards from their hand, then draws that many cards plus one. Khorvath's Fury deals damage to each foe equal to the number of cards in their hand. diff --git a/forge-gui/res/cardsfolder/upcoming/pirs_whim.txt b/forge-gui/res/cardsfolder/upcoming/pirs_whim.txt new file mode 100644 index 00000000000..fcaceefbbc0 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/pirs_whim.txt @@ -0,0 +1,14 @@ +Name:Pir's Whim +ManaCost:3 G +Types:Sorcery +A:SP$ AssignGroup | Cost$ 3 G | Defined$ Player | Choices$ DBSearch,DBSacrifice | AILogic$ FriendOrFoe | SpellDescription$ For each player, choose friend or foe. Each friend searches their library for a land card, puts it onto the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment they control. +SVar:DBSearch:DB$ChangeZone | Origin$ Library | Destination$ Battlefield | DefinedPlayer$ Remembered | ChangeType$ Land | ChangeNum$ 1 | StackDescription$ Each friend searches their library for a land card, puts it onto the battlefield tapped, then shuffles their library. | SpellDescription$ Friend searches their library for a land card, puts it onto the battlefield tapped, then shuffles their library. +SVar:DBSacrifice:DB$Sacrifice | Defined$ Remembered | SacValid$ Artifact,Enchantment | SacMessage$ artifact or enchantment | StackDescription$ Each foe sacrifices an artifact or enchantment they control. | SpellDescription$ Foe sacrifices an artifact or enchantment they control. +SVar:NeedsToPlayVar:Z GE1 +SVar:Z:SVar$Z1/Plus.C1 +SVar:Z1:SVar$C2/Plus.C3 +SVar:C1:Count$Valid Land.YourTeamCtrl+inZoneLibrary +SVar:C2:Count$Valid Enchantment.OppCtrl+inZoneBattlefield +SVar:C3:Count$Valid Artifact.OppCtrl+inZoneBattlefield +SVar:Picture:http://www.wizards.com/global/images/magic/general/pirs_whim.jpg +Oracle:For each player, choose friend or foe. Each friend searches their library for a land card, puts it onto the battlefield tapped, then shuffles their library. Each foe sacrifices an artifact or enchantment they control. diff --git a/forge-gui/res/cardsfolder/upcoming/regnas_sanction.txt b/forge-gui/res/cardsfolder/upcoming/regnas_sanction.txt new file mode 100644 index 00000000000..12f421c3171 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/regnas_sanction.txt @@ -0,0 +1,19 @@ +Name:Regna's Sanction +ManaCost:3 W +Types:Sorcery +A:SP$ AssignGroup | Cost$ 3 W | Defined$ Player | Choices$ FriendRepeat,FoeRepeat | AILogic$ FriendOrFoe | SpellDescription$ For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest. +SVar:FriendRepeat:DB$ RepeatEach | RepeatPlayers$ Remembered | RepeatSubAbility$ DBPutCounter | ClearRememberedBeforeLoop$ True | StackDescription$ Each friend puts a +1/+1 counter on each creature they control. | SpellDescription$ Friend puts a +1/+1 counter on each creature they control. +SVar:DBPutCounter:DB$ PutCounterAll | ValidCards$ Creature.RememberedPlayerCtrl | CounterType$ P1P1 | CounterNum$ 1 | Placer$ Remembered +SVar:FoeRepeat:DB$ RepeatEach | AILogic$ OpponentHasMultipleCreatures | RepeatPlayers$ Remembered | ClearRememberedBeforeLoop$ True | RepeatSubAbility$ DBChoose | SubAbility$ DBTapAll | StackDescription$ Each foe chooses one untapped creature they control, then taps the rest. | SpellDescription$ Foe chooses one untapped creature they control, then taps the rest. +SVar:DBChoose:DB$ ChooseCard | Defined$ Remembered | Amount$ 1 | Choices$ Creature.untapped+RememberedPlayerCtrl | Mandatory$ True | RememberChosen$ True | SubAbility$ DBImprint +#Need to imprint all non remembered cards +SVar:DBImprint:DB$ Pump | ImprintCards$ Valid Creature.IsNotRemembered+RememberedPlayerCtrl | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearChosenCard$ True +SVar:DBTapAll:DB$ TapAll | ValidCards$ Creature.IsImprinted | SubAbility$ DBCleanupAll +SVar:DBCleanupAll:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True | ClearChosenCard$ True +SVar:NeedsToPlayVar:Z GE3 +SVar:Z:SVar$Z1/Plus.Z2 +SVar:Z1:Count$Valid Creature.YourTeamCtrl+inZoneBattlefield +SVar:Z2:Count$Valid Creature.OppCtrl+inZoneBattlefield+untapped +SVar:Picture:http://www.wizards.com/global/images/magic/general/regna_sanction.jpg +Oracle:For each player, choose friend or foe. Each friend puts a +1/+1 counter on each creature they control. Each foe chooses one untapped creature they control, then taps the rest. diff --git a/forge-gui/res/cardsfolder/upcoming/virtuss_maneuver.txt b/forge-gui/res/cardsfolder/upcoming/virtuss_maneuver.txt new file mode 100644 index 00000000000..aae76276af4 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/virtuss_maneuver.txt @@ -0,0 +1,15 @@ +Name:Virtus's Maneuver +ManaCost:2 B +Types:Sorcery +A:SP$ AssignGroup | Cost$ 2 B | Defined$ Player | Choices$ FriendRepeat,DBSacrifice | AILogic$ FriendOrFoe | SpellDescription$ For each player, choose friend or foe. Each friend returns a creature card from their graveyard to their hand. Each foe sacrifices a creature they control. +SVar:FriendRepeat:DB$ RepeatEach | RepeatPlayers$ Remembered | RepeatSubAbility$ PlayChoose | ClearRememberedBeforeLoop$ True | SubAbility$ ReturnAll | StackDescription$ SpellDescription | SpellDescription$ Each friend returns a creature card from their graveyard to their hand. +SVar:PlayChoose:DB$ ChooseCard | Defined$ Player.IsRemembered | Choices$ Creature.RememberedPlayerCtrl | Amount$ 1 | Mandatory$ True | ChoiceZone$ Graveyard | ChoiceTitle$ Choose a creature in your graveyard | RememberChosen$ True +SVar:ReturnAll:DB$ ChangeZoneAll | Origin$ Graveyard | Destination$ Hand | ChangeType$ Creature.IsRemembered | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearChosenCard$ True +SVar:DBSacrifice:DB$Sacrifice | Defined$ Remembered | SacValid$ Creature | SacMessage$ creature | StackDescription$ SpellDescription | SpellDescription$ Each foe sacrifices a creature they control. +SVar:NeedsToPlayVar:Z GE2 +SVar:Z:SVar$Z1/Plus.Z2 +SVar:Z1:Count$ValidGraveyard Creature.YourTeamCtrl +SVar:Z2:Count$Valid Creature.OppCtrl+inZoneBattlefield +SVar:Picture:http://www.wizards.com/global/images/magic/general/virtuss_maneuver.jpg +Oracle:For each player, choose friend or foe. Each friend returns a creature card from their graveyard to their hand. Each foe sacrifices a creature they control. diff --git a/forge-gui/res/cardsfolder/upcoming/zndrsplts_judgment.txt b/forge-gui/res/cardsfolder/upcoming/zndrsplts_judgment.txt new file mode 100644 index 00000000000..ef57e37a24d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/zndrsplts_judgment.txt @@ -0,0 +1,16 @@ +Name:Zndrsplt's Judgment +ManaCost:4 U +Types:Sorcery +A:SP$ AssignGroup | Cost$ 4 U | Defined$ Player | Choices$ FriendRepeat,FoeRepeat | AILogic$ FriendOrFoe | SpellDescription$ For each player, choose friend or foe. Each friend creates a token that's a copy of a creature they control. Each foe returns a creature they control to its owner's hand. +SVar:FriendRepeat:DB$ RepeatEach | RepeatPlayers$ Remembered | RepeatSubAbility$ DBClone | ClearRememberedBeforeLoop$ True | StackDescription$ Each friend creates a token that's a copy of a creature they control. | SpellDescription$ Friend creates a token that's a copy of a creature they control. +SVar:DBClone:DB$ CopyPermanent | Choices$ Creature.RememberedPlayerCtrl | Chooser$ Remembered | Controller$ Remembered +SVar:FoeRepeat:DB$ RepeatEach | RepeatPlayers$ Remembered | RepeatSubAbility$ PlayChoose | ClearRememberedBeforeLoop$ True | SubAbility$ BounceAll | StackDescription$ Each foe returns a creature they control to its owner's hand. | SpellDescription$ Foe returns a creature they control to its owner's hand. +SVar:PlayChoose:DB$ ChooseCard | Defined$ Player.IsRemembered | Choices$ Creature.RememberedPlayerCtrl | Amount$ 1 | Mandatory$ True | AILogic$ WorstCard | ChoiceTitle$ Choose a creature you control | RememberChosen$ True +SVar:BounceAll:DB$ ChangeZoneAll | Origin$ Battlefield | Destination$ Hand | ChangeType$ Creature.IsRemembered | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearChosenCard$ True +SVar:NeedsToPlayVar:Z GE2 +SVar:Z:SVar$Z1/Plus.Z2 +SVar:Z1:Count$Valid Creature.YourTeamCtrl+inZoneBattlefield +SVar:Z2:Count$Valid Creature.OppCtrl+inZoneBattlefield +SVar:Picture:http://www.wizards.com/global/images/magic/general/zndrsplt_judgment.jpg +Oracle:For each player, choose friend or foe. Each friend creates a token that's a copy of a creature they control. Each foe returns a creature they control to its owner's hand. diff --git a/forge-gui/src/main/java/forge/player/HumanPlay.java b/forge-gui/src/main/java/forge/player/HumanPlay.java index 21f04529811..fd96df17d56 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/player/HumanPlay.java @@ -438,7 +438,7 @@ public class HumanPlay { return false; } - source.addCounter(counterType, amount, source, false); + source.addCounter(counterType, amount, p, false); } else { CardCollectionView list = p.getGame().getCardsIn(ZoneType.Battlefield); @@ -456,7 +456,7 @@ public class HumanPlay { continue; } Card selected = inp.getFirstSelected(); - selected.addCounter(counterType, 1, source, false); + selected.addCounter(counterType, 1, p, false); amount--; } } diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index c050ea72183..d33e1ecc56d 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -537,7 +537,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont @Override public SpellAbility chooseSingleSpellForEffect(final List spells, final SpellAbility sa, - final String title) { + final String title, Map params) { if (spells.size() < 2) { return Iterables.getFirst(spells, null); } @@ -2085,7 +2085,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont if (subtract) { card.subtractCounter(counter, count); } else { - card.addCounter(counter, count, card, false); + card.addCounter(counter, count, card.getController(), false); } }