From f10ec1751f4ace29e78b368fecee78fd1f1d8ba2 Mon Sep 17 00:00:00 2001 From: swordshine Date: Thu, 9 Jan 2014 13:46:14 +0000 Subject: [PATCH] - Converted Old Man of the Sea - Added Rootwater Matriarch --- .gitattributes | 1 + .../res/cardsfolder/o/old_man_of_the_sea.txt | 4 +- .../res/cardsfolder/r/rootwater_matriarch.txt | 11 ++ forge-gui/src/main/java/forge/game/Game.java | 2 +- .../src/main/java/forge/game/GameAction.java | 39 +++++- .../main/java/forge/game/GameActionUtil.java | 44 ------- .../main/java/forge/game/StaticEffects.java | 123 ------------------ .../ability/effects/ControlGainEffect.java | 21 +-- .../src/main/java/forge/game/card/Card.java | 56 +++----- .../main/java/forge/game/phase/EndOfTurn.java | 1 - .../game/zone/PlayerZoneBattlefield.java | 34 ----- 11 files changed, 75 insertions(+), 261 deletions(-) create mode 100644 forge-gui/res/cardsfolder/r/rootwater_matriarch.txt diff --git a/.gitattributes b/.gitattributes index 2255ade4937..673f3afe7cd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9593,6 +9593,7 @@ forge-gui/res/cardsfolder/r/rootwater_commando.txt svneol=native#text/plain forge-gui/res/cardsfolder/r/rootwater_depths.txt svneol=native#text/plain forge-gui/res/cardsfolder/r/rootwater_diver.txt svneol=native#text/plain forge-gui/res/cardsfolder/r/rootwater_hunter.txt svneol=native#text/plain +forge-gui/res/cardsfolder/r/rootwater_matriarch.txt -text forge-gui/res/cardsfolder/r/rootwater_mystic.txt svneol=native#text/plain forge-gui/res/cardsfolder/r/rootwater_shaman.txt -text forge-gui/res/cardsfolder/r/rootwater_thief.txt svneol=native#text/plain diff --git a/forge-gui/res/cardsfolder/o/old_man_of_the_sea.txt b/forge-gui/res/cardsfolder/o/old_man_of_the_sea.txt index 701586934cd..b9a16a37f02 100644 --- a/forge-gui/res/cardsfolder/o/old_man_of_the_sea.txt +++ b/forge-gui/res/cardsfolder/o/old_man_of_the_sea.txt @@ -3,7 +3,9 @@ ManaCost:1 U U Types:Creature Djinn PT:2/3 K:You may choose not to untap CARDNAME during your untap step. -A:AB$ GainControl | Cost$ T | ValidTgts$ Creature.powerLEX | References$ X | TgtPrompt$ Select target creature with power less than or equal to Old Man's. | LoseControl$ Untap,LeavesPlay,LoseControl | SpellDescription$ Gain control of target creature with power less than or equal to Old Man of the Sea's power for as long as Old Man of the Sea remains tapped and that creature's power remains less than or equal to Old Man of the Sea's power. +A:AB$ GainControl | Cost$ T | ValidTgts$ Creature.powerLEX | TgtPrompt$ Select target creature with power less than or equal to Old Man's. | LoseControl$ Untap,LeavesPlay,LoseControl,StaticCommandCheck | StaticCommandCheckSVar$ Y | StaticCommandSVarCompare$ GTX | References$ X,Y | SpellDescription$ Gain control of target creature with power less than or equal to Old Man of the Sea's power for as long as Old Man of the Sea remains tapped and that creature's power remains less than or equal to Old Man of the Sea's power. SVar:X:Count$CardPower +# the hostcard of SVar Y is the controlled card +SVar:Y:Count$CardPower SVar:Picture:http://www.wizards.com/global/images/magic/general/old_man_of_the_sea.jpg Oracle:You may choose not to untap Old Man of the Sea during your untap step.\n{T}: Gain control of target creature with power less than or equal to Old Man of the Sea's power for as long as Old Man of the Sea remains tapped and that creature's power remains less than or equal to Old Man of the Sea's power. \ No newline at end of file diff --git a/forge-gui/res/cardsfolder/r/rootwater_matriarch.txt b/forge-gui/res/cardsfolder/r/rootwater_matriarch.txt new file mode 100644 index 00000000000..767059823bb --- /dev/null +++ b/forge-gui/res/cardsfolder/r/rootwater_matriarch.txt @@ -0,0 +1,11 @@ +Name:Rootwater Matriarch +ManaCost:2 U U +Types:Creature Merfolk +PT:2/3 +A:AB$ GainControl | Cost$ T | ValidTgts$ Creature | References$ X,Y | AITgts$ Creature.enchanted | LoseControl$ StaticCommandCheck | StaticCommandCheckSVar$ X | StaticCommandSVarCompare$ EQ0 | ConditionCheckSVar$ Y | ContionSVarCompare$ GE1 | SpellDescription$ Gain control of target creature for as long as that creature is enchanted. +# the hostcard of SVar X is the controlled card +SVar:X:Count$Valid Card.Self+enchanted +SVar:Y:Targeted$Valid Card.enchanted +SVar:RemRandomDeck:True +SVar:Picture:http://www.wizards.com/global/images/magic/general/rootwater_matriarch.jpg +Oracle:{T}: Gain control of target creature for as long as that creature is enchanted. diff --git a/forge-gui/src/main/java/forge/game/Game.java b/forge-gui/src/main/java/forge/game/Game.java index df8815dc3bb..982885d9de5 100644 --- a/forge-gui/src/main/java/forge/game/Game.java +++ b/forge-gui/src/main/java/forge/game/Game.java @@ -72,7 +72,7 @@ public class Game { public final Upkeep upkeep; public final MagicStack stack; private final PhaseHandler phaseHandler; - private final StaticEffects staticEffects = new StaticEffects(this); + private final StaticEffects staticEffects = new StaticEffects(); private final TriggerHandler triggerHandler = new TriggerHandler(this); private final ReplacementHandler replacementHandler = new ReplacementHandler(this); private final EventBus events = new EventBus("game events"); diff --git a/forge-gui/src/main/java/forge/game/GameAction.java b/forge-gui/src/main/java/forge/game/GameAction.java index 8cdcc72c958..f5c3da55473 100644 --- a/forge-gui/src/main/java/forge/game/GameAction.java +++ b/forge-gui/src/main/java/forge/game/GameAction.java @@ -27,7 +27,6 @@ import java.util.List; import java.util.Map.Entry; import java.util.Set; -import com.google.common.base.Function; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @@ -38,6 +37,7 @@ import forge.FThreads; import forge.card.CardCharacteristicName; import forge.card.CardType; import forge.game.ability.AbilityFactory; +import forge.game.ability.AbilityUtils; import forge.game.ability.ApiType; import forge.game.ability.effects.AttachEffect; import forge.game.card.Card; @@ -71,6 +71,7 @@ import forge.game.zone.ZoneType; import forge.item.PaperCard; import forge.util.Aggregates; import forge.util.CollectionSuppliers; +import forge.util.Expressions; import forge.util.ThreadUtil; import forge.util.maps.HashMapOfLists; import forge.util.maps.MapOfLists; @@ -473,6 +474,7 @@ public class GameAction { for (Player p : game.getPlayers()) { ((PlayerZoneBattlefield) p.getZone(ZoneType.Battlefield)).setTriggers(true); } + c.runChangeControllerCommands(); } /** @@ -701,6 +703,7 @@ public class GameAction { // search for cards with static abilities final List allCards = game.getCardsInGame(); final ArrayList staticAbilities = new ArrayList(); + final List staticList = new ArrayList(); for (final Card c : allCards) { for (int i = 0; i < c.getStaticAbilities().size(); i++) { StaticAbility stAb = c.getCharacteristics().getStaticAbilities().get(i); @@ -712,6 +715,9 @@ public class GameAction { i--; } } + if (!c.getStaticCommandList().isEmpty()) { + staticList.add(c); + } } final Comparator comp = new Comparator() { @@ -733,14 +739,33 @@ public class GameAction { } // card state effects like Glorious Anthem - for (final String effect : game.getStaticEffects().getStateBasedMap().keySet()) { - final Function com = GameActionUtil.getCommands().get(effect); - com.apply(game); - } +// for (final String effect : game.getStaticEffects().getStateBasedMap().keySet()) { +// final Function com = GameActionUtil.getCommands().get(effect); +// com.apply(game); +// } List lands = game.getCardsIn(ZoneType.Battlefield); GameActionUtil.grantBasicLandsManaAbilities(CardLists.filter(lands, CardPredicates.Presets.LANDS)); + for (final Card c : staticList) { + for (int i = 0; i < c.getStaticCommandList().size(); i++) { + final Object[] staticCheck = c.getStaticCommandList().get(i); + final String leftVar = (String) staticCheck[0]; + final String rightVar = (String) staticCheck[1]; + final Card affected = (Card) staticCheck[2]; + // calculate the affected card + final int sVar = AbilityUtils.calculateAmount(affected, leftVar, null); + final String svarOperator = rightVar.substring(0, 2); + final String svarOperand = rightVar.substring(2); + final int operandValue = AbilityUtils.calculateAmount(c, svarOperand, null); + if (Expressions.compare(sVar, svarOperator, operandValue)) { + ((Command) staticCheck[3]).run(); + c.getStaticCommandList().remove(i); + i--; + affectedCards.add(c); + } + } + } // Exclude cards in hidden zones from update Iterator it = affectedCards.iterator(); while (it.hasNext()) { @@ -753,6 +778,7 @@ public class GameAction { if (!affectedCards.isEmpty()) { game.fireEvent(new GameEventCardStatsChanged(affectedCards)); } + } /** @@ -796,9 +822,8 @@ public class GameAction { for (Player p : game.getPlayers()) { for (Card c : p.getCardsIn(ZoneType.Battlefield)) { - if (!c.getController().equals(p)) { + if (!c.getController().equals(p)) { // should not be here controllerChangeZoneCorrection(c); - c.runChangeControllerCommands(); checkAgain = true; } } diff --git a/forge-gui/src/main/java/forge/game/GameActionUtil.java b/forge-gui/src/main/java/forge/game/GameActionUtil.java index 012a3538841..2fc23885285 100644 --- a/forge-gui/src/main/java/forge/game/GameActionUtil.java +++ b/forge-gui/src/main/java/forge/game/GameActionUtil.java @@ -18,17 +18,14 @@ package forge.game; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; -import com.google.common.base.Function; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; -import forge.Command; import forge.card.MagicColor; import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityUtils; @@ -114,47 +111,6 @@ public final class GameActionUtil { c.getDamageHistory().registerCombatDamage(player); } // executeCombatDamageToPlayerEffects - /** Constant oldManOfTheSea. */ - private static Function oldManOfTheSea = new Function() { - - @Override - public Object apply(Game game) { - final List list = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), CardPredicates.nameEquals("Old Man of the Sea")); - for (final Card oldman : list) { - if (!oldman.getGainControlTargets().isEmpty()) { - if (oldman.getNetAttack() < oldman.getGainControlTargets().get(0).getNetAttack()) { - final List coms = oldman.getGainControlReleaseCommands(); - for (int i = 0; i < coms.size(); i++) { - coms.get(i).run(); - } - } - } - } - return null; - } - }; // Old Man of the Sea - - - /** Constant commands. */ - private final static HashMap> commands = new HashMap>(); - - static { - // Please add cards in alphabetical order so they are easier to find - - GameActionUtil.getCommands().put("Old_Man_of_the_Sea", GameActionUtil.oldManOfTheSea); - - // The commands above are in alphabetical order by cardname. - } - - /** - * Gets the commands. - * - * @return the commands - */ - public static Map> getCommands() { - return GameActionUtil.commands; - } - /** * Gets the st land mana abilities. * @param game diff --git a/forge-gui/src/main/java/forge/game/StaticEffects.java b/forge-gui/src/main/java/forge/game/StaticEffects.java index 6ab80292220..ed333a8ed23 100644 --- a/forge-gui/src/main/java/forge/game/StaticEffects.java +++ b/forge-gui/src/main/java/forge/game/StaticEffects.java @@ -25,14 +25,11 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import com.esotericsoftware.minlog.Log; - import forge.game.card.Card; import forge.game.card.CardUtil; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.staticability.StaticAbility; -import forge.game.zone.ZoneType; /** *

@@ -48,8 +45,6 @@ public class StaticEffects { private final ArrayList staticEffects = new ArrayList(); //Global rule changes private final EnumSet ruleChanges = EnumSet.noneOf(GlobalRuleChange.class); - - private final Game game; public final Set clearStaticEffects() { ruleChanges.clear(); @@ -256,123 +251,5 @@ public class StaticEffects { // **************** End StaticAbility system ************************** - // this is used to keep track of all state-based effects in play: - private final HashMap stateBasedMap = new HashMap(); - - // this is used to define all cards that are state-based effects, and map - // the - // corresponding commands to their cardnames - /** Constant cardToEffectsList. */ - private static HashMap cardToEffectsList = new HashMap(); - - /** - *

- * Constructor for StaticEffects. - *

- */ - public StaticEffects(Game game) { - this.game = game; - this.initStateBasedEffectsList(); - } - - /** - *

- * initStateBasedEffectsList. - *

- */ - public final void initStateBasedEffectsList() { - // value has to be an array, since certain cards have multiple commands - // associated with them - StaticEffects.cardToEffectsList.put("Old Man of the Sea", new String[] { "Old_Man_of_the_Sea" }); - } - - /** - *

- * Getter for the field cardToEffectsList. - *

- * - * @return a {@link java.util.HashMap} object. - */ - public final HashMap getCardToEffectsList() { - return StaticEffects.cardToEffectsList; - } - - /** - *

- * addStateBasedEffect. - *

- * - * @param s - * a {@link java.lang.String} object. - */ - public final void addStateBasedEffect(final String s) { - if (this.stateBasedMap.containsKey(s)) { - this.stateBasedMap.put(s, this.stateBasedMap.get(s) + 1); - } else { - this.stateBasedMap.put(s, 1); - } - } - - /** - *

- * removeStateBasedEffect. - *

- * - * @param s - * a {@link java.lang.String} object. - */ - public final void removeStateBasedEffect(final String s) { - if (this.stateBasedMap.containsKey(s)) { - this.stateBasedMap.put(s, this.stateBasedMap.get(s) - 1); - if (this.stateBasedMap.get(s) == 0) { - this.stateBasedMap.remove(s); - } - } - } - - /** - *

- * Getter for the field stateBasedMap. - *

- * - * @return a {@link java.util.HashMap} object. - */ - public final HashMap getStateBasedMap() { - return this.stateBasedMap; - } - - /** - *

- * reset. - *

- */ - public final void reset() { - this.stateBasedMap.clear(); - } - - /** - *

- * rePopulateStateBasedList. - *

- * @param game - */ - public final void rePopulateStateBasedList() { - this.reset(); - - final List cards = game.getCardsIn(ZoneType.Battlefield); - - Log.debug("== Start add state effects =="); - for (Card c : cards) { - if (StaticEffects.cardToEffectsList.containsKey(c.getName())) { - final String[] effects = this.getCardToEffectsList().get(c.getName()); - for (final String effect : effects) { - this.addStateBasedEffect(effect); - Log.debug("Added " + effect); - } - } - } - Log.debug("== End add state effects =="); - - } } // end class StaticEffects diff --git a/forge-gui/src/main/java/forge/game/ability/effects/ControlGainEffect.java b/forge-gui/src/main/java/forge/game/ability/effects/ControlGainEffect.java index 5d034f94d6a..6a9bf664b7e 100644 --- a/forge-gui/src/main/java/forge/game/ability/effects/ControlGainEffect.java +++ b/forge-gui/src/main/java/forge/game/ability/effects/ControlGainEffect.java @@ -61,8 +61,8 @@ public class ControlGainEffect extends SpellAbilityEffect { } } } // if - host.clearGainControlTargets(); - host.clearGainControlReleaseCommands(); + host.removeGainControlTargets(c); + } @Override @@ -103,12 +103,12 @@ public class ControlGainEffect extends SpellAbilityEffect { for (Card tgtC : tgtCards) { - if (!tgtC.equals(sa.getSourceCard()) && !sa.getSourceCard().getGainControlTargets().contains(tgtC)) { - sa.getSourceCard().addGainControlTarget(tgtC); + if (!tgtC.isInPlay()) { + continue; } - if (!tgtC.isInPlay()) { - return; + if (!tgtC.equals(sa.getSourceCard()) && !sa.getSourceCard().getGainControlTargets().contains(tgtC)) { + sa.getSourceCard().addGainControlTarget(tgtC); } long tStamp = game.getNextTimestamp(); @@ -150,6 +150,12 @@ public class ControlGainEffect extends SpellAbilityEffect { game.getEndOfTurn().addUntil(this.getLoseControlCommand(tgtC, tStamp, bTapOnLose, source, kws)); tgtC.setSVar("SacMe", "6"); } + if (lose.contains("StaticCommandCheck")) { + String leftVar = sa.getSVar(sa.getParam("StaticCommandCheckSVar")); + String rightVar = sa.getParam("StaticCommandSVarCompare"); + sa.getSourceCard().addStaticCommandList(new Object[]{leftVar, rightVar, tgtC, + this.getLoseControlCommand(tgtC, tStamp, bTapOnLose, source, kws)}); + } } if (destroyOn != null) { @@ -164,10 +170,7 @@ public class ControlGainEffect extends SpellAbilityEffect { } } - sa.getSourceCard().clearGainControlReleaseCommands(); - sa.getSourceCard().addGainControlReleaseCommand(this.getLoseControlCommand(tgtC, tStamp, bTapOnLose, source, kws)); game.getAction().controllerChangeZoneCorrection(tgtC); - tgtC.runChangeControllerCommands(); } // end foreach target } diff --git a/forge-gui/src/main/java/forge/game/card/Card.java b/forge-gui/src/main/java/forge/game/card/Card.java index 27ccd303e27..b804bb45f33 100644 --- a/forge-gui/src/main/java/forge/game/card/Card.java +++ b/forge-gui/src/main/java/forge/game/card/Card.java @@ -234,11 +234,11 @@ public class Card extends GameEntity implements Comparable { private Card cloneOrigin = null; private final List clones = new ArrayList(); private final List gainControlTargets = new ArrayList(); - private final List gainControlReleaseCommands = new ArrayList(); private final List zcTriggers = new ArrayList(); private final List untapCommandList = new ArrayList(); private final List changeControllerCommandList = new ArrayList(); + private final List staticCommandList = new ArrayList(); private final static ImmutableList storableSVars = ImmutableList.of("ChosenX"); @@ -1762,44 +1762,8 @@ public class Card extends GameEntity implements Comparable { *

* used primarily with AbilityFactory_GainControl */ - public final void clearGainControlTargets() { - this.gainControlTargets.clear(); - } - - /** - * get the commands to be executed to lose control of Cards this card has - * gained control of. - *

- * used primarily with AbilityFactory_GainControl (Old Man of the Sea - * specifically) - * - * @return a {@link java.util.ArrayList} object. - */ - public final List getGainControlReleaseCommands() { - return this.gainControlReleaseCommands; - } - - /** - * set a command to be executed to lose control of Cards this card has - * gained control of. - *

- * used primarily with AbilityFactory_GainControl (Old Man of the Sea - * specifically) - * - * @param c - * the Command to be executed - */ - public final void addGainControlReleaseCommand(final Command c) { - this.gainControlReleaseCommands.add(c); - } - - /** - *

- * clearGainControlReleaseCommands. - *

- */ - public final void clearGainControlReleaseCommands() { - this.gainControlReleaseCommands.clear(); + public final void removeGainControlTargets(final Card c) { + this.gainControlTargets.remove(c); } /** @@ -8703,9 +8667,19 @@ public class Card extends GameEntity implements Comparable { * @param pc */ public static void updateCard(PaperCard pc) { - Card res = cp2card.get(pc); + Card res = cp2card.get(pc); if (res != null) { - cp2card.put(pc, fromPaperCard(pc, null)); + cp2card.put(pc, fromPaperCard(pc, null)); } } + + /** return staticCommanderList */ + public List getStaticCommandList() { + return staticCommandList; + } + + /** return staticCommanderList */ + public void addStaticCommandList(Object[] objects) { + this.staticCommandList.add(objects); + } } // end Card class diff --git a/forge-gui/src/main/java/forge/game/phase/EndOfTurn.java b/forge-gui/src/main/java/forge/game/phase/EndOfTurn.java index 55e2074a483..62b72d54785 100644 --- a/forge-gui/src/main/java/forge/game/phase/EndOfTurn.java +++ b/forge-gui/src/main/java/forge/game/phase/EndOfTurn.java @@ -54,7 +54,6 @@ public class EndOfTurn extends Phase { public final void executeAt() { // reset mustAttackEntity for me game.getPhaseHandler().getPlayerTurn().setMustAttackEntity(null); - game.getStaticEffects().rePopulateStateBasedList(); for (final Card c : game.getCardsIn(ZoneType.Battlefield)) { if (!c.isFaceDown() && c.hasKeyword("At the beginning of the end step, sacrifice CARDNAME.")) { diff --git a/forge-gui/src/main/java/forge/game/zone/PlayerZoneBattlefield.java b/forge-gui/src/main/java/forge/game/zone/PlayerZoneBattlefield.java index df57ce7cd8c..6f236fa5001 100644 --- a/forge-gui/src/main/java/forge/game/zone/PlayerZoneBattlefield.java +++ b/forge-gui/src/main/java/forge/game/zone/PlayerZoneBattlefield.java @@ -19,13 +19,10 @@ package forge.game.zone; import java.util.List; -import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; -import forge.game.GameActionUtil; -import forge.game.Game; import forge.game.card.Card; import forge.game.player.Player; import forge.game.staticability.StaticAbility; @@ -82,28 +79,8 @@ public class PlayerZoneBattlefield extends PlayerZone { c.setSickness(true); // summoning sickness c.executeTrigger(ZCTrigger.ENTERFIELD); - /*if (c.isLand()) { - - - for( Player opp : c.getOwner().getOpponents()) - for( Card le : opp.getCardsIn(ZoneType.Battlefield, "Land Equilibrium") ) { - final List pLands = c.getOwner().getLandsInPlay(); - final List oLands = opp.getLandsInPlay(); - - if (oLands.size() <= (pLands.size() - 1)) { - SpellAbility abSac = AbilityFactory.getAbility(le.getSVar("SacLand"), le); - game.getStack().addSimultaneousStackEntry(abSac); - } - } - } // isLand()*/ } - if (game.getStaticEffects().getCardToEffectsList().containsKey(c.getName())) { - final String[] effects = game.getStaticEffects().getCardToEffectsList().get(c.getName()); - for (final String effect : effects) { - game.getStaticEffects().addStateBasedEffect(effect); - } - } } // end add() /** {@inheritDoc} */ @@ -115,17 +92,6 @@ public class PlayerZoneBattlefield extends PlayerZone { c.executeTrigger(ZCTrigger.LEAVEFIELD); } - if (game.getStaticEffects().getCardToEffectsList().containsKey(c.getName())) { - final String[] effects = game.getStaticEffects().getCardToEffectsList().get(c.getName()); - String tempEffect = ""; - for (final String effect : effects) { - tempEffect = effect; - game.getStaticEffects().removeStateBasedEffect(effect); - // this is to make sure cards reset correctly - final Function comm = GameActionUtil.getCommands().get(tempEffect); - comm.apply(game); - } - } }