From c10b5706f1bc79a8b9475c22cd73cacd68005e5b Mon Sep 17 00:00:00 2001 From: tool4ever Date: Fri, 26 Sep 2025 08:48:22 +0200 Subject: [PATCH] Some fixes (#8779) --- .../src/main/java/forge/ai/ComputerUtil.java | 63 ++++---- .../main/java/forge/ai/ComputerUtilMana.java | 9 +- .../java/forge/ai/ability/ChangeZoneAi.java | 3 - .../ability/effects/RestartGameEffect.java | 3 +- .../java/forge/game/card/CardFactory.java | 147 +++++++++--------- .../game/spellability/AbilityActivated.java | 2 +- .../k/kami_of_twisted_reflection.txt | 2 +- forge-gui/res/cardsfolder/p/parker_luck.txt | 1 + .../res/cardsfolder/s/spider_man_2099.txt | 2 +- 9 files changed, 113 insertions(+), 119 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index ca942690ab9..bad4b3c3bbc 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -3104,41 +3104,38 @@ public class ComputerUtil { public static CardCollection filterAITgts(SpellAbility sa, Player ai, CardCollection srcList, boolean alwaysStrict) { final Card source = sa.getHostCard(); - if (source == null) { return srcList; } - - if (sa.hasParam("AITgts")) { - CardCollection list; - String aiTgts = sa.getParam("AITgts"); - if (aiTgts.startsWith("BetterThan")) { - int value = 0; - if (aiTgts.endsWith("Source")) { - value = ComputerUtilCard.evaluateCreature(source); - if (source.isEnchanted()) { - for (Card enc : source.getEnchantedBy()) { - if (enc.getController().equals(ai)) { - value += 100; // is 100 per AI's own aura enough? - } - } - } - } else if (aiTgts.contains("EvalRating.")) { - value = AbilityUtils.calculateAmount(source, aiTgts.substring(aiTgts.indexOf(".") + 1), sa); - } else { - System.err.println("Warning: Unspecified AI target evaluation rating for SA " + sa); - value = ComputerUtilCard.evaluateCreature(source); - } - final int totalValue = value; - list = CardLists.filter(srcList, c -> ComputerUtilCard.evaluateCreature(c) > totalValue + 30); - } else { - list = CardLists.getValidCards(srcList, sa.getParam("AITgts"), sa.getActivatingPlayer(), source, sa); - } - - if (!list.isEmpty() || sa.hasParam("AITgtsStrict") || alwaysStrict) { - return list; - } else { - return srcList; - } + if (source == null || !sa.hasParam("AITgts")) { + return srcList; } + CardCollection list; + String aiTgts = sa.getParam("AITgts"); + if (aiTgts.startsWith("BetterThan")) { + int value = 0; + if (aiTgts.endsWith("Source")) { + value = ComputerUtilCard.evaluateCreature(source); + if (source.isEnchanted()) { + for (Card enc : source.getEnchantedBy()) { + if (enc.getController().equals(ai)) { + value += 100; // is 100 per AI's own aura enough? + } + } + } + } else if (aiTgts.contains("EvalRating.")) { + value = AbilityUtils.calculateAmount(source, aiTgts.substring(aiTgts.indexOf(".") + 1), sa); + } else { + System.err.println("Warning: Unspecified AI target evaluation rating for SA " + sa); + value = ComputerUtilCard.evaluateCreature(source); + } + final int totalValue = value; + list = CardLists.filter(srcList, c -> ComputerUtilCard.evaluateCreature(c) > totalValue + 30); + } else { + list = CardLists.getValidCards(srcList, sa.getParam("AITgts"), sa.getActivatingPlayer(), source, sa); + } + + if (!list.isEmpty() || sa.hasParam("AITgtsStrict") || alwaysStrict) { + return list; + } return srcList; } diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java index 52cacd0283d..9518b852d63 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java @@ -815,7 +815,7 @@ public class ComputerUtilMana { String manaProduced = predictManafromSpellAbility(saPayment, ai, toPay); payMultipleMana(cost, manaProduced, ai); - // remove from available lists + // remove to prevent re-usage since resources don't get consumed sourcesForShards.values().removeIf(CardTraitPredicates.isHostCard(saPayment.getHostCard())); } else { final CostPayment pay = new CostPayment(saPayment.getPayCosts(), saPayment); @@ -828,8 +828,10 @@ public class ComputerUtilMana { // subtract mana from mana pool manapool.payManaFromAbility(sa, cost, saPayment); - // no need to remove abilities from resource map, - // once their costs are paid and consume resources, they can not be used again + // need to consider if another use is now prevented + if (!cost.isPaid() && saPayment.isActivatedAbility() && !saPayment.getRestrictions().canPlay(saPayment.getHostCard(), saPayment)) { + sourcesForShards.values().removeIf(s -> s == saPayment); + } if (hasConverge) { // hack to prevent converge re-using sources @@ -1662,7 +1664,6 @@ public class ComputerUtilMana { if (replaced.contains("C")) { manaMap.put(ManaAtom.COLORLESS, m); } - } } } diff --git a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java index 6cfc0b0600c..f964381fa5f 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java @@ -891,9 +891,6 @@ public class ChangeZoneAi extends SpellAbilityAi { CardCollection list = CardLists.getTargetableCards(game.getCardsIn(origin), sa); list = ComputerUtil.filterAITgts(sa, ai, list, true); - if (sa.hasParam("AITgtsOnlyBetterThanSelf")) { - list = CardLists.filter(list, card -> ComputerUtilCard.evaluateCreature(card) > ComputerUtilCard.evaluateCreature(source) + 30); - } if (source.isInZone(ZoneType.Hand)) { list = CardLists.filter(list, CardPredicates.nameNotEquals(source.getName())); // Don't get the same card back. 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 32bb7126c0e..92fbc180d36 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 @@ -75,9 +75,8 @@ public class RestartGameEffect extends SpellAbilityEffect { p.clearController(); CardCollection newLibrary = new CardCollection(p.getCardsIn(restartZones, false)); - List filteredCards = null; if (leaveZone != null) { - filteredCards = CardLists.getValidCards(p.getCardsIn(leaveZone), leaveRestriction, p, sa.getHostCard(), sa); + List filteredCards = CardLists.getValidCards(p.getCardsIn(leaveZone), leaveRestriction, p, sa.getHostCard(), sa); newLibrary.addAll(filteredCards); } diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index 690b1535942..b800d8e0a25 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -466,29 +466,29 @@ public class CardFactory { return new WrappedAbility(sa.getTrigger(), sa.getWrappedAbility().copy(newHost, controller, false), sa.getDecider()); } - public static CardCloneStates getCloneStates(final Card in, final Card out, final CardTraitBase sa) { - final Card host = sa.getHostCard(); + public static CardCloneStates getCloneStates(final Card in, final Card out, final CardTraitBase cause) { + final Card host = cause.getHostCard(); final Map origSVars = host.getSVars(); final List types = Lists.newArrayList(); final List keywords = Lists.newArrayList(); boolean KWifNew = false; final List removeKeywords = Lists.newArrayList(); List creatureTypes = null; - final CardCloneStates result = new CardCloneStates(in, sa); + final CardCloneStates result = new CardCloneStates(in, cause); - final String newName = sa.getParam("NewName"); + final String newName = cause.getParam("NewName"); ColorSet colors = null; - if (sa.hasParam("AddTypes")) { - types.addAll(Arrays.asList(sa.getParam("AddTypes").split(" & "))); + if (cause.hasParam("AddTypes")) { + types.addAll(Arrays.asList(cause.getParam("AddTypes").split(" & "))); } - if (sa.hasParam("SetCreatureTypes")) { - creatureTypes = ImmutableList.copyOf(sa.getParam("SetCreatureTypes").split(" ")); + if (cause.hasParam("SetCreatureTypes")) { + creatureTypes = ImmutableList.copyOf(cause.getParam("SetCreatureTypes").split(" ")); } - if (sa.hasParam("AddKeywords")) { - String kwString = sa.getParam("AddKeywords"); + if (cause.hasParam("AddKeywords")) { + String kwString = cause.getParam("AddKeywords"); if (kwString.startsWith("IfNew ")) { KWifNew = true; kwString = kwString.substring(6); @@ -496,21 +496,21 @@ public class CardFactory { keywords.addAll(Arrays.asList(kwString.split(" & "))); } - if (sa.hasParam("RemoveKeywords")) { - removeKeywords.addAll(Arrays.asList(sa.getParam("RemoveKeywords").split(" & "))); + if (cause.hasParam("RemoveKeywords")) { + removeKeywords.addAll(Arrays.asList(cause.getParam("RemoveKeywords").split(" & "))); } - if (sa.hasParam("AddColors")) { - colors = ColorSet.fromNames(sa.getParam("AddColors").split(",")); + if (cause.hasParam("AddColors")) { + colors = ColorSet.fromNames(cause.getParam("AddColors").split(",")); } - if (sa.hasParam("SetColor")) { - colors = ColorSet.fromNames(sa.getParam("SetColor").split(",")); + if (cause.hasParam("SetColor")) { + colors = ColorSet.fromNames(cause.getParam("SetColor").split(",")); } - if (sa.hasParam("SetColorByManaCost")) { - if (sa.hasParam("SetManaCost")) { - colors = ColorSet.fromManaCost(new ManaCost(new ManaCostParser(sa.getParam("SetManaCost")))); + if (cause.hasParam("SetColorByManaCost")) { + if (cause.hasParam("SetManaCost")) { + colors = ColorSet.fromManaCost(new ManaCost(new ManaCostParser(cause.getParam("SetManaCost")))); } else { colors = ColorSet.fromManaCost(host.getManaCost()); } @@ -522,56 +522,55 @@ public class CardFactory { // if something is cloning a facedown card, it only clones the // facedown state into original final CardState ret = new CardState(out, CardStateName.Original); - ret.copyFrom(in.getFaceDownState(), false, sa); + ret.copyFrom(in.getFaceDownState(), false, cause); result.put(CardStateName.Original, ret); } else if (in.isFlipCard()) { // if something is cloning a flip card, copy both original and // flipped state final CardState ret1 = new CardState(out, CardStateName.Original); - ret1.copyFrom(in.getState(CardStateName.Original), false, sa); + ret1.copyFrom(in.getState(CardStateName.Original), false, cause); result.put(CardStateName.Original, ret1); final CardState ret2 = new CardState(out, CardStateName.Flipped); - ret2.copyFrom(in.getState(CardStateName.Flipped), false, sa); + ret2.copyFrom(in.getState(CardStateName.Flipped), false, cause); result.put(CardStateName.Flipped, ret2); } else if (in.hasState(CardStateName.Secondary)) { final CardState ret1 = new CardState(out, CardStateName.Original); - ret1.copyFrom(in.getState(CardStateName.Original), false, sa); + ret1.copyFrom(in.getState(CardStateName.Original), false, cause); result.put(CardStateName.Original, ret1); final CardState ret2 = new CardState(out, CardStateName.Secondary); - ret2.copyFrom(in.getState(CardStateName.Secondary), false, sa); + ret2.copyFrom(in.getState(CardStateName.Secondary), false, cause); result.put(CardStateName.Secondary, ret2); - } else if (in.isTransformable() && sa instanceof SpellAbility && ( - ApiType.CopyPermanent.equals(((SpellAbility)sa).getApi()) || - ApiType.CopySpellAbility.equals(((SpellAbility)sa).getApi()) || - ApiType.ReplaceToken.equals(((SpellAbility)sa).getApi()) - )) { + } else if (in.isTransformable() && cause instanceof SpellAbility sa && ( + ApiType.CopyPermanent.equals(sa.getApi()) || + ApiType.CopySpellAbility.equals(sa.getApi()) || + ApiType.ReplaceToken.equals(sa.getApi()))) { // CopyPermanent can copy token final CardState ret1 = new CardState(out, CardStateName.Original); - ret1.copyFrom(in.getState(CardStateName.Original), false, sa); + ret1.copyFrom(in.getState(CardStateName.Original), false, cause); result.put(CardStateName.Original, ret1); final CardState ret2 = new CardState(out, CardStateName.Backside); - ret2.copyFrom(in.getState(CardStateName.Backside), false, sa); + ret2.copyFrom(in.getState(CardStateName.Backside), false, cause); result.put(CardStateName.Backside, ret2); } else if (in.isSplitCard()) { // for split cards, copy all three states final CardState ret1 = new CardState(out, CardStateName.Original); - ret1.copyFrom(in.getState(CardStateName.Original), false, sa); + ret1.copyFrom(in.getState(CardStateName.Original), false, cause); result.put(CardStateName.Original, ret1); final CardState ret2 = new CardState(out, CardStateName.LeftSplit); - ret2.copyFrom(in.getState(CardStateName.LeftSplit), false, sa); + ret2.copyFrom(in.getState(CardStateName.LeftSplit), false, cause); result.put(CardStateName.LeftSplit, ret2); final CardState ret3 = new CardState(out, CardStateName.RightSplit); - ret3.copyFrom(in.getState(CardStateName.RightSplit), false, sa); + ret3.copyFrom(in.getState(CardStateName.RightSplit), false, cause); result.put(CardStateName.RightSplit, ret3); } else { // in all other cases just copy the current state to original final CardState ret = new CardState(out, CardStateName.Original); - ret.copyFrom(in.getState(in.getCurrentStateName()), false, sa); + ret.copyFrom(in.getState(in.getCurrentStateName()), false, cause); result.put(CardStateName.Original, ret); } @@ -581,32 +580,32 @@ public class CardFactory { final CardState state = e.getValue(); // has Embalm Condition for extra changes of Vizier of Many Faces - if (sa.hasParam("Embalm") && !out.isEmbalmed()) { + if (cause.hasParam("Embalm") && !out.isEmbalmed()) { continue; } // update the names for the states - if (sa.hasParam("KeepName")) { + if (cause.hasParam("KeepName")) { state.setName(originalState.getName()); } else if (newName != null) { // convert NICKNAME descriptions? state.setName(newName); } - if (sa.hasParam("AddColors")) { + if (cause.hasParam("AddColors")) { state.addColor(colors.getColor()); } - if (sa.hasParam("SetColor") || sa.hasParam("SetColorByManaCost")) { + if (cause.hasParam("SetColor") || cause.hasParam("SetColorByManaCost")) { state.setColor(colors.getColor()); } - if (sa.hasParam("NonLegendary")) { + if (cause.hasParam("NonLegendary")) { state.removeType(CardType.Supertype.Legendary); } - if (sa.hasParam("RemoveCardTypes")) { - state.removeCardTypes(sa.hasParam("RemoveSubTypes")); + if (cause.hasParam("RemoveCardTypes")) { + state.removeCardTypes(cause.hasParam("RemoveSubTypes")); } state.addType(types); @@ -638,31 +637,31 @@ public class CardFactory { // CR 208.3 A noncreature object not on the battlefield has power or toughness only if it has a power and toughness printed on it. // currently only LKI can be trusted? - if ((sa.hasParam("SetPower") || sa.hasParam("SetToughness")) && + if ((cause.hasParam("SetPower") || cause.hasParam("SetToughness")) && (state.getType().isCreature() || (originalState != null && in.getOriginalState(originalState.getStateName()).getBasePowerString() != null))) { - if (sa.hasParam("SetPower")) { - state.setBasePower(AbilityUtils.calculateAmount(host, sa.getParam("SetPower"), sa)); + if (cause.hasParam("SetPower")) { + state.setBasePower(AbilityUtils.calculateAmount(host, cause.getParam("SetPower"), cause)); } - if (sa.hasParam("SetToughness")) { - state.setBaseToughness(AbilityUtils.calculateAmount(host, sa.getParam("SetToughness"), sa)); + if (cause.hasParam("SetToughness")) { + state.setBaseToughness(AbilityUtils.calculateAmount(host, cause.getParam("SetToughness"), cause)); } } - if (state.getType().isPlaneswalker() && sa.hasParam("SetLoyalty")) { - state.setBaseLoyalty(String.valueOf(AbilityUtils.calculateAmount(host, sa.getParam("SetLoyalty"), sa))); + if (state.getType().isPlaneswalker() && cause.hasParam("SetLoyalty")) { + state.setBaseLoyalty(String.valueOf(AbilityUtils.calculateAmount(host, cause.getParam("SetLoyalty"), cause))); } - if (sa.hasParam("RemoveCost")) { + if (cause.hasParam("RemoveCost")) { state.setManaCost(ManaCost.NO_COST); } - if (sa.hasParam("SetManaCost")) { - state.setManaCost(new ManaCost(new ManaCostParser(sa.getParam("SetManaCost")))); + if (cause.hasParam("SetManaCost")) { + state.setManaCost(new ManaCost(new ManaCostParser(cause.getParam("SetManaCost")))); } // SVars to add to clone - if (sa.hasParam("AddSVars") || sa.hasParam("GainTextSVars")) { - final String str = sa.getParamOrDefault("GainTextSVars", sa.getParam("AddSVars")); + if (cause.hasParam("AddSVars") || cause.hasParam("GainTextSVars")) { + final String str = cause.getParamOrDefault("GainTextSVars", cause.getParam("AddSVars")); for (final String s : str.split(",")) { if (origSVars.containsKey(s)) { final String actualsVar = origSVars.get(s); @@ -672,8 +671,8 @@ public class CardFactory { } // triggers to add to clone - if (sa.hasParam("AddTriggers")) { - for (final String s : sa.getParam("AddTriggers").split(",")) { + if (cause.hasParam("AddTriggers")) { + for (final String s : cause.getParam("AddTriggers").split(",")) { if (origSVars.containsKey(s)) { final String actualTrigger = origSVars.get(s); final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, out, true, state); @@ -683,8 +682,8 @@ public class CardFactory { } // abilities to add to clone - if (sa.hasParam("AddAbilities") || sa.hasParam("GainTextAbilities")) { - final String str = sa.getParamOrDefault("GainTextAbilities", sa.getParam("AddAbilities")); + if (cause.hasParam("AddAbilities") || cause.hasParam("GainTextAbilities")) { + final String str = cause.getParamOrDefault("GainTextAbilities", cause.getParam("AddAbilities")); for (final String s : str.split(",")) { if (origSVars.containsKey(s)) { final String actualAbility = origSVars.get(s); @@ -696,18 +695,18 @@ public class CardFactory { } // static abilities to add to clone - if (sa.hasParam("AddStaticAbilities")) { - final String str = sa.getParam("AddStaticAbilities"); + if (cause.hasParam("AddStaticAbilities")) { + final String str = cause.getParam("AddStaticAbilities"); for (final String s : str.split(",")) { if (origSVars.containsKey(s)) { final String actualStatic = origSVars.get(s); - state.addStaticAbility(StaticAbility.create(actualStatic, out, sa.getCardState(), true)); + state.addStaticAbility(StaticAbility.create(actualStatic, out, cause.getCardState(), true)); } } } - if (sa.hasParam("GainThisAbility") && sa instanceof SpellAbility) { - SpellAbility root = ((SpellAbility) sa).getRootAbility(); + if (cause.hasParam("GainThisAbility") && cause instanceof SpellAbility sa) { + SpellAbility root = sa.getRootAbility(); // Aurora Shifter if (root.isTrigger() && root.getTrigger().getSpawningAbility() != null) { @@ -724,35 +723,35 @@ public class CardFactory { } // Special Rules for Embalm and Eternalize - if (sa.isEmbalm() && sa.isIntrinsic()) { + if (cause.isEmbalm() && cause.isIntrinsic()) { String name = "embalm_" + TextUtil.fastReplace( TextUtil.fastReplace(host.getName(), ",", ""), " ", "_").toLowerCase(); state.setImageKey(StaticData.instance().getOtherImageKey(name, host.getSetCode())); } - if (sa.isEternalize() && sa.isIntrinsic()) { + if (cause.isEternalize() && cause.isIntrinsic()) { String name = "eternalize_" + TextUtil.fastReplace( TextUtil.fastReplace(host.getName(), ",", ""), " ", "_").toLowerCase(); state.setImageKey(StaticData.instance().getOtherImageKey(name, host.getSetCode())); } - if (sa.isKeyword(Keyword.OFFSPRING) && sa.isIntrinsic()) { + if (cause.isKeyword(Keyword.OFFSPRING) && cause.isIntrinsic()) { String name = "offspring_" + TextUtil.fastReplace( TextUtil.fastReplace(host.getName(), ",", ""), " ", "_").toLowerCase(); state.setImageKey(StaticData.instance().getOtherImageKey(name, host.getSetCode())); } - if (sa.isKeyword(Keyword.SQUAD) && sa.isIntrinsic()) { + if (cause.isKeyword(Keyword.SQUAD) && cause.isIntrinsic()) { String name = "squad_" + TextUtil.fastReplace( TextUtil.fastReplace(host.getName(), ",", ""), " ", "_").toLowerCase(); state.setImageKey(StaticData.instance().getOtherImageKey(name, host.getSetCode())); } - if (sa.hasParam("GainTextOf") && originalState != null) { + if (cause.hasParam("GainTextOf") && originalState != null) { state.setSetCode(originalState.getSetCode()); state.setRarity(originalState.getRarity()); state.setImageKey(originalState.getImageKey()); @@ -764,27 +763,27 @@ public class CardFactory { continue; } - if (sa.hasParam("SetPower") && sta.hasParam("SetPower")) + if (cause.hasParam("SetPower") && sta.hasParam("SetPower")) state.removeStaticAbility(sta); - if (sa.hasParam("SetToughness") && sta.hasParam("SetToughness")) + if (cause.hasParam("SetToughness") && sta.hasParam("SetToughness")) state.removeStaticAbility(sta); // currently only Changeling and similar should be affected by that // other cards using AddType$ ChosenType should not - if (sa.hasParam("SetCreatureTypes") && sta.hasParam("AddAllCreatureTypes")) { + if (cause.hasParam("SetCreatureTypes") && sta.hasParam("AddAllCreatureTypes")) { state.removeStaticAbility(sta); } - if ((sa.hasParam("SetColor") || sa.hasParam("SetColorByManaCost")) && sta.hasParam("SetColor")) { + if ((cause.hasParam("SetColor") || cause.hasParam("SetColorByManaCost")) && sta.hasParam("SetColor")) { state.removeStaticAbility(sta); } } // remove some keywords - if (sa.hasParam("SetCreatureTypes")) { + if (cause.hasParam("SetCreatureTypes")) { state.removeIntrinsicKeyword(Keyword.CHANGELING); } - if (sa.hasParam("SetColor") || sa.hasParam("SetColorByManaCost")) { + if (cause.hasParam("SetColor") || cause.hasParam("SetColorByManaCost")) { state.removeIntrinsicKeyword(Keyword.DEVOID); } } diff --git a/forge-game/src/main/java/forge/game/spellability/AbilityActivated.java b/forge-game/src/main/java/forge/game/spellability/AbilityActivated.java index ce10ab07de9..fcdc1b77f54 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilityActivated.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilityActivated.java @@ -92,7 +92,7 @@ public abstract class AbilityActivated extends SpellAbility implements Cloneable return false; } - if (!(this.getRestrictions().canPlay(c, this))) { + if (!getRestrictions().canPlay(c, this)) { return false; } diff --git a/forge-gui/res/cardsfolder/k/kami_of_twisted_reflection.txt b/forge-gui/res/cardsfolder/k/kami_of_twisted_reflection.txt index 5d531b281ea..a2dfd611327 100644 --- a/forge-gui/res/cardsfolder/k/kami_of_twisted_reflection.txt +++ b/forge-gui/res/cardsfolder/k/kami_of_twisted_reflection.txt @@ -2,5 +2,5 @@ Name:Kami of Twisted Reflection ManaCost:1 U U Types:Creature Spirit PT:2/2 -A:AB$ ChangeZone | Cost$ Sac<1/CARDNAME> | ValidTgts$ Creature.YouCtrl | AITgts$ Creature.Other+YouCtrl | AITgtsOnlyBetterThanSelf$ True | TgtPrompt$ Select target creature you control | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target creature you control to its owner's hand. +A:AB$ ChangeZone | Cost$ Sac<1/CARDNAME> | ValidTgts$ Creature.YouCtrl | AITgts$ BetterThanSource | TgtPrompt$ Select target creature you control | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target creature you control to its owner's hand. Oracle:Sacrifice Kami of Twisted Reflection: Return target creature you control to its owner's hand. diff --git a/forge-gui/res/cardsfolder/p/parker_luck.txt b/forge-gui/res/cardsfolder/p/parker_luck.txt index a7fac4e599b..802200a0944 100644 --- a/forge-gui/res/cardsfolder/p/parker_luck.txt +++ b/forge-gui/res/cardsfolder/p/parker_luck.txt @@ -8,4 +8,5 @@ SVar:DBLoseLife:DB$ LoseLife | Defined$ Player.IsRemembered | LifeAmount$ X SVar:DBChangeZoneAll:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered | Origin$ Library | Destination$ Hand | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Count$ValidLibrary Card.IsRemembered+!RememberedPlayerOwn$CardManaCost +AI:RemoveDeck:All Oracle:At the beginning of your end step, two target players each reveal the top card of their library. They each lose life equal to the mana value of the card revealed by the other player. Then they each put the card they revealed into their hand. diff --git a/forge-gui/res/cardsfolder/s/spider_man_2099.txt b/forge-gui/res/cardsfolder/s/spider_man_2099.txt index e9c82d77279..3023ae58621 100644 --- a/forge-gui/res/cardsfolder/s/spider_man_2099.txt +++ b/forge-gui/res/cardsfolder/s/spider_man_2099.txt @@ -6,7 +6,7 @@ K:Double Strike K:Vigilance S:Mode$ CantBeCast | ValidCard$ Card.Self | EffectZone$ All | Caster$ Player.Active | CheckSVar$ Z | SVarCompare$ LE3 | Description$ You can't cast CARDNAME during your first, second, or third turns of the game. SVar:Z:Count$YourTurns -T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | CheckSVar$ Y | SVarCompare$ EQ1 | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ At the beginning of your end step, if you've played a land or cast a spell this turn from anywhere other than your hand, CARDNAME deals damage equal to his power to any target. +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | CheckSVar$ Y | SVarCompare$ GE1 | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ At the beginning of your end step, if you've played a land or cast a spell this turn from anywhere other than your hand, CARDNAME deals damage equal to his power to any target. SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ X | AILogic$ PowerDmg SVar:X:Count$CardPower T:Mode$ LandPlayed | Origin$ Exile,Library,Graveyard | ValidCard$ Land.YouCtrl | Execute$ StoreVar | Static$ True