diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index f1b41ac4085..56b905e9010 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -840,12 +840,13 @@ public class ComputerUtil { String logic = source.getParamOrDefault("AILogic", ""); if (logic.startsWith("SacForDamage")) { - if (c.getNetPower() <= 0) { + final int damageAmt = logic.contains("cmc") ? c.getManaCost().getCMC() : c.getNetPower(); + if (damageAmt <= 0) { return false; - } else if (c.getNetPower() >= ai.getOpponentsSmallestLifeTotal()) { + } else if (damageAmt >= ai.getOpponentsSmallestLifeTotal()) { return true; } else if (logic.endsWith(".GiantX2") && c.getType().hasCreatureType("Giant") - && c.getNetPower() * 2 >= ai.getOpponentsSmallestLifeTotal()) { + && damageAmt * 2 >= ai.getOpponentsSmallestLifeTotal()) { return true; // TODO: generalize this for any type and actually make the AI prefer giants? } } diff --git a/forge-ai/src/main/java/forge/ai/GameState.java b/forge-ai/src/main/java/forge/ai/GameState.java index 0921a64c51a..84c4e73eb91 100644 --- a/forge-ai/src/main/java/forge/ai/GameState.java +++ b/forge-ai/src/main/java/forge/ai/GameState.java @@ -313,6 +313,8 @@ public abstract class GameState { newText.append("|Meld"); } else if (c.getCurrentStateName().equals(CardStateName.Modal)) { newText.append("|Modal"); + } else if (c.getCurrentStateName().equals(CardStateName.Converted)) { + newText.append("|Converted"); } if (c.getPlayerAttachedTo() != null) { diff --git a/forge-core/src/main/java/forge/card/CardSplitType.java b/forge-core/src/main/java/forge/card/CardSplitType.java index 69c6aea1814..ef4dbd70d67 100644 --- a/forge-core/src/main/java/forge/card/CardSplitType.java +++ b/forge-core/src/main/java/forge/card/CardSplitType.java @@ -5,6 +5,7 @@ import forge.card.CardFace.FaceSelectionMethod; public enum CardSplitType { None(FaceSelectionMethod.USE_PRIMARY_FACE, null), + Convert(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Converted), Transform(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Transformed), Meld(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Meld), Split(FaceSelectionMethod.COMBINE, CardStateName.RightSplit), diff --git a/forge-core/src/main/java/forge/card/CardStateName.java b/forge-core/src/main/java/forge/card/CardStateName.java index fca71c5556f..42005ef9c9e 100644 --- a/forge-core/src/main/java/forge/card/CardStateName.java +++ b/forge-core/src/main/java/forge/card/CardStateName.java @@ -5,6 +5,7 @@ public enum CardStateName { Original, FaceDown, Flipped, + Converted, Transformed, Meld, LeftSplit, diff --git a/forge-core/src/main/java/forge/item/PaperCard.java b/forge-core/src/main/java/forge/item/PaperCard.java index eea20d881b3..32e9550b253 100644 --- a/forge-core/src/main/java/forge/item/PaperCard.java +++ b/forge-core/src/main/java/forge/item/PaperCard.java @@ -399,7 +399,8 @@ public class PaperCard implements Comparable, InventoryItemFromSet, @Override public boolean hasBackFace(){ CardSplitType cst = this.rules.getSplitType(); - return cst == CardSplitType.Transform || cst == CardSplitType.Flip || cst == CardSplitType.Meld || cst == CardSplitType.Modal; + return cst == CardSplitType.Transform || cst == CardSplitType.Flip || cst == CardSplitType.Meld + || cst == CardSplitType.Modal || cst == CardSplitType.Convert; } // Return true if card is one of the five basic lands that can be added for free diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java index c33fbbf51b2..a9271c3cadc 100644 --- a/forge-game/src/main/java/forge/game/GameActionUtil.java +++ b/forge-game/src/main/java/forge/game/GameActionUtil.java @@ -275,6 +275,28 @@ public final class GameActionUtil { foretold.setPayCosts(new Cost(k[1], false)); alternatives.add(foretold); + } else if (keyword.startsWith("More Than Meets the Eye")) { + final String[] k = keyword.split(":"); + final Cost convertCost = new Cost(k[1], true); + + final SpellAbility newSA = new SpellPermanent(source); + newSA.setCardState(source.getAlternateState()); + newSA.setPayCosts(convertCost); + newSA.setActivatingPlayer(activator); + + newSA.putParam("PrecostDesc", k[0] + " "); + newSA.putParam("CostDesc", convertCost.toString()); + + // makes new SpellDescription + final StringBuilder desc = new StringBuilder(); + desc.append(newSA.getCostDescription()); + desc.append("(").append(inst.getReminderText()).append(")"); + newSA.setDescription(desc.toString()); + newSA.putParam("AfterDescription", "(Converted)"); + + newSA.setAlternativeCost(AlternativeCost.MTMtE); + + alternatives.add(newSA); } } 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 3588cef356f..08aad2989f1 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 @@ -588,6 +588,14 @@ public class ChangeZoneEffect extends SpellAbilityEffect { continue; } } + if (sa.hasParam("Converted")) { + if (gameCard.isConvertable()) { + gameCard.changeCardState("Convert", null, sa); + } else { + // If it can't convert, don't change zones. + continue; + } + } if (sa.hasParam("WithCountersType")) { CounterType cType = CounterType.getType(sa.getParam("WithCountersType")); int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa); diff --git a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java index 06d5f9904b5..5f303703298 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DamageDealEffect.java @@ -298,9 +298,9 @@ public class DamageDealEffect extends DamageBaseEffect { } } else { damageMap.put(sourceLKI, c, dmg); - if (sa.hasParam("ExcessSVar")) { - sa.setSVar(sa.getParam("ExcessSVar"), Integer.toString(excess)); - } + } + if (sa.hasParam("ExcessSVar")) { + sa.setSVar(sa.getParam("ExcessSVar"), Integer.toString(excess)); } } } 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 96728df527b..ff60331a0bb 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -220,6 +220,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { private long bestowTimestamp = -1; private long transformedTimestamp = 0; + private long convertedTimestamp = 0; private long mutatedTimestamp = -1; private int timesMutated = 0; private boolean tributed = false; @@ -392,6 +393,9 @@ public class Card extends GameEntity implements Comparable, IHasSVars { public long getTransformedTimestamp() { return transformedTimestamp; } public void incrementTransformedTimestamp() { this.transformedTimestamp++; } + public long getConvertedTimestamp() { return convertedTimestamp; } + public void incrementConvertedTimestamp() { this.convertedTimestamp++; } + public CardState getCurrentState() { return currentState; } @@ -625,6 +629,29 @@ public class Card extends GameEntity implements Comparable, IHasSVars { return retResult; + } else if (mode.equals("Convert") && (isConvertable() || hasMergedCard())) { + // Need to remove mutated states, otherwise the changeToState() will fail + if (hasMergedCard()) { + removeMutatedStates(); + } + CardCollectionView cards = hasMergedCard() ? getMergedCards() : new CardCollection(this); + boolean retResult = false; + for (final Card c : cards) { + if (!c.isConvertable()) { + continue; + } + c.backside = !c.backside; + + boolean result = c.changeToState(c.backside ? CardStateName.Converted : CardStateName.Original); + retResult = retResult || result; + } + if (hasMergedCard()) { + rebuildMutatedStates(cause); + game.getTriggerHandler().clearActiveTriggers(this, null); + game.getTriggerHandler().registerActiveTrigger(this, false); + } + return retResult; + } else if (mode.equals("Flip")) { // 709.4. Flipping a permanent is a one-way process. if (isFlipped()) { @@ -930,12 +957,16 @@ public class Card extends GameEntity implements Comparable, IHasSVars { return getRules() != null && getRules().getSplitType() == CardSplitType.Meld; } + public final boolean isConvertable() { + return getRules() != null && getRules().getSplitType() == CardSplitType.Convert; + } + public final boolean isModal() { return getRules() != null && getRules().getSplitType() == CardSplitType.Modal; } public final boolean hasBackSide() { - return isDoubleFaced() || isMeldable() || isModal(); + return isDoubleFaced() || isMeldable() || isModal() || isConvertable(); } public final boolean isFlipCard() { @@ -2035,7 +2066,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { || keyword.startsWith("Escape") || keyword.startsWith("Foretell:") || keyword.startsWith("Disturb") || keyword.startsWith("Madness:") || keyword.startsWith("Reconfigure") || keyword.startsWith("Squad") - || keyword.startsWith("Miracle")) { + || keyword.startsWith("Miracle") || keyword.startsWith("More Than Meets the Eye")) { String[] k = keyword.split(":"); sbLong.append(k[0]); if (k.length > 1) { @@ -2148,7 +2179,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { || keyword.equals("Living Weapon") || keyword.equals("Myriad") || keyword.equals("Exploit") || keyword.equals("Changeling") || keyword.equals("Delve") || keyword.equals("Decayed") || keyword.equals("Split second") || keyword.equals("Sunburst") - || keyword.equals("Double team") + || keyword.equals("Double team") || keyword.equals("Living metal") || keyword.equals("Suspend") // for the ones without amount || keyword.equals("Foretell") // for the ones without cost || keyword.equals("Ascend") || keyword.equals("Totem armor") 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 d9ad34ab36e..fd4f62807d4 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -3692,6 +3692,9 @@ public class CardFactoryUtil { String effect = "Mode$ CantBlockBy | ValidAttacker$ Creature.Self | ValidBlocker$ Creature.nonArtifact+notSharesColorWith | Secondary$ True " + " | Description$ Intimidate ( " + inst.getReminderText() + ")"; inst.addStaticAbility(StaticAbility.create(effect, state.getCard(), state, intrinsic)); + } else if (keyword.equals("Living metal")) { + String effect = "Mode$ Continuous | Affected$ Card.Self | AddType$ Creature | Condition$ PlayerTurn | Secondary$ True"; + inst.addStaticAbility(StaticAbility.create(effect, state.getCard(), state, intrinsic)); } else if (keyword.equals("Nightbound")) { String effect = "Mode$ CantTransform | ValidCard$ Creature.Self | ExceptCause$ SpellAbility.Nightbound | Secondary$ True | Description$ This permanent can't be transformed except by its nightbound ability."; inst.addStaticAbility(StaticAbility.create(effect, state.getCard(), state, intrinsic)); diff --git a/forge-game/src/main/java/forge/game/keyword/Keyword.java b/forge-game/src/main/java/forge/game/keyword/Keyword.java index 1b93546d8e8..570cb5ee228 100644 --- a/forge-game/src/main/java/forge/game/keyword/Keyword.java +++ b/forge-game/src/main/java/forge/game/keyword/Keyword.java @@ -109,6 +109,7 @@ public enum Keyword { LANDWALK("Landwalk", KeywordWithType.class, false, "This creature is unblockable as long as defending player controls a %s."), LEVEL_UP("Level up", KeywordWithCost.class, false, "%s: Put a level counter on this. Level up only as a sorcery."), LIFELINK("Lifelink", SimpleKeyword.class, true, "Damage dealt by this creature also causes its controller to gain that much life."), + LIVING_METAL("Living metal", SimpleKeyword.class, true, "As long as it's your turn, this Vehicle is also a creature."), LIVING_WEAPON("Living Weapon", SimpleKeyword.class, true, "When this Equipment enters the battlefield, create a 0/0 black Phyrexian Germ creature token, then attach this to it."), MADNESS("Madness", KeywordWithCost.class, false, "If you discard this card, discard it into exile. When you do, cast it for its madness cost or put it into your graveyard."), MELEE("Melee", SimpleKeyword.class, false, "Whenever this creature attacks, it gets +1/+1 until end of turn for each opponent you attacked this combat."), @@ -119,6 +120,7 @@ public enum Keyword { // technically not a keyword but easier this way MONSTROSITY("Monstrosity", KeywordWithCostAndAmount.class, false, "If this creature isn't monstrous, put {%2$d:+1/+1 counter} on it and it becomes monstrous."), MODULAR("Modular", Modular.class, false, "This creature enters the battlefield with {%d:+1/+1 counter} on it. When it dies, you may put its +1/+1 counters on target artifact creature."), + MORE_THAN_MEETS_THE_EYE("More Than Meets the Eye", KeywordWithCost.class, false, "You may cast this card converted for %s."), MORPH("Morph", KeywordWithCost.class, false, "You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its morph cost."), MULTIKICKER("Multikicker", KeywordWithCost.class, false, "You may pay an additional %s any number of times as you cast this spell."), MUTATE("Mutate", KeywordWithCost.class, true, "If you cast this spell for its mutate cost, put it over or under target non-Human creature you own. They mutate into the creature on top plus all abilities from under it."), diff --git a/forge-game/src/main/java/forge/game/spellability/AlternativeCost.java b/forge-game/src/main/java/forge/game/spellability/AlternativeCost.java index e39bf7b8abe..b33858ff990 100644 --- a/forge-game/src/main/java/forge/game/spellability/AlternativeCost.java +++ b/forge-game/src/main/java/forge/game/spellability/AlternativeCost.java @@ -13,6 +13,7 @@ public enum AlternativeCost { Flashback, Foretold, Madness, + MTMtE, // More Than Meets the Eye (Transformers Universes Beyond) Mutate, Offering, Outlast, // ActivatedAbility diff --git a/forge-gui/res/cardsfolder/upcoming/megatron_tyrant_megatron_destructive_force.txt b/forge-gui/res/cardsfolder/upcoming/megatron_tyrant_megatron_destructive_force.txt new file mode 100644 index 00000000000..5017ed843ca --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/megatron_tyrant_megatron_destructive_force.txt @@ -0,0 +1,30 @@ +Name:Megatron, Tyrant +ManaCost:3 R W B +Types:Legendary Artifact Creature Robot +PT:7/5 +K:More Than Meets the Eye:1 R W B +S:Mode$ CantBeCast | ValidCard$ Card | Caster$ Opponent | Phases$ BeginCombat->EndCombat | Description$ Your opponents can't cast spells during combat. +T:Mode$ Phase | Phase$ Main2 | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigConvert | OptionalDecider$ You | TriggerDescription$ At the beginning of your postcombat main phase, you may convert NICKNAME. If you do, add {C} for each 1 life your opponents have lost this turn. +SVar:TrigConvert:DB$ SetState | Mode$ Convert | RememberChanged$ True | SubAbility$ DBMana +SVar:DBMana:DB$ Mana | ConditionDefined$ Remembered | ConditionPresent$ Card | Produced$ C | Amount$ X | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Count$LifeOppsLostThisTurn +AlternateMode:Convert +Oracle:More Than Meets the Eye {1}{R}{W}{B} (You may cast this card converted for {1}{R}{W}{B}.)\nYour opponents can't cast spells during combat.\nAt the beginning of your postcombat main phase, you may convert Megatron. If you do, add {C} for each 1 life your opponents have lost this turn. + +ALTERNATE + +Name:Megatron, Destructive Force +ManaCost:no cost +Colors:white,black,red +Types:Legendary Artifact Vehicle +PT:4/5 +K:Living metal +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigImmediate | TriggerDescription$ Whenever NICKNAME attacks, you may sacrifice another artifact. When you do, NICKNAME deals damage equal to the sacrificed artifact's mana value to target creature. If excess damage would be dealt to that creature this way, instead that damage is dealt to that creature's controller and you convert NICKNAME. +SVar:TrigImmediate:AB$ ImmediateTrigger | Cost$ Sac<1/Artifact.Other/another artifact> | RememberObjects$ Sacrificed | Execute$ TrigDamage | AILogic$ SacForDamage.cmc | TriggerDescription$ When you do, NICKNAME deals damage equal to the sacrificed artifact's mana value to target creature. If excess damage would be dealt to that creature this way, instead that damage is dealt to that creature's controller and you convert NICKNAME. +SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Creature | NumDmg$ X | ExcessSVar$ Excess | ExcessDamage$ TargetedController | SubAbility$ DBConvert +SVar:DBConvert:DB$ SetState | ConditionCheckSVar$ Excess | Mode$ Convert +SVar:X:TriggerRemembered$CardManaCost +SVar:HasAttackEffect:TRUE +DeckHas:Ability$Sacrifice +Oracle:Living metal (As long as it's your turn, this Vehicle is also a creature.)\nWhenever Megatron attacks, you may sacrifice another artifact. When you do, Megatron deals damage equal to the sacrificed artifact's mana value to target creature. If excess damage would be dealt to that creature this way, instead that damage is dealt to that creature's controller and you convert Megatron. diff --git a/forge-gui/res/cardsfolder/upcoming/optimus_prime_hero_optimus_prime_autobot_leader.txt b/forge-gui/res/cardsfolder/upcoming/optimus_prime_hero_optimus_prime_autobot_leader.txt new file mode 100644 index 00000000000..f2ee8ebbbf1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/optimus_prime_hero_optimus_prime_autobot_leader.txt @@ -0,0 +1,29 @@ +Name:Optimus Prime, Hero +ManaCost:3 U R W +Types:Legendary Artifact Creature Robot +PT:4/8 +K:More Than Meets the Eye:2 U R W +T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | Execute$ TrigBolster | TriggerDescription$ At the beginning of each end step, bolster 1. (Choose a creature with the least toughness among creatures you control and put a +1/+1 counter on it.) +SVar:TrigBolster:DB$ PutCounter | Bolster$ True | CounterType$ P1P1 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When NICKNAME dies, return it to the battlefield converted under its owner's control. +SVar:TrigReturn:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Battlefield | Converted$ True +AlternateMode:Convert +DeckHas:Ability$Counters +Oracle:More Than Meets the Eye {2}{U}{R}{W} (You may cast this card converted for {2}{U}{R}{W}.)\nAt the beginning of each end step, bolster 1. (Choose a creature with the least toughness among creatures you control and put a +1/+1 counter on it.)\nWhen Optimus Prime dies, return it to the battlefield converted under its owner's control. + +ALTERNATE + +Name:Optimus Prime, Autobot Leader +ManaCost:no cost +Colors:white,blue,red +Types:Legendary Artifact Vehicle +PT:6/8 +K:Living metal +K:Trample +T:Mode$ AttackersDeclared | AttackingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigBolster | TriggerDescription$ Whenever you attack, bolster 2. The chosen creature gains trample until end of turn. When that creature deals combat damage to a player this turn, convert NICKNAME. +SVar:TrigBolster:DB$ PutCounter | Bolster$ True | CounterType$ P1P1 | CounterNum$ 2 | RememberPut$ True | SubAbility$ DBPump +SVar:DBPump:DB$ Pump | Defined$ Remembered | KW$ Trample | SubAbility$ DBDelayedTrigger +SVar:DBDelayedTrigger:DB$ DelayedTrigger | Mode$ DamageDone | RememberObjects$ Remembered | ValidSource$ Card.IsTriggerRemembered | ValidTarget$ Player | CombatDamage$ True | ThisTurn$ True | Execute$ TrigConvert | TriggerDescription$ When that creature deals combat damage to a player this turn, convert NICKNAME. +SVar:TrigConvert:DB$ SetState | Mode$ Convert | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +Oracle:Living metal (As long as it's your turn, this Vehicle is also a creature.)\nTrample\nWhenever you attack, bolster 2. The chosen creature gains trample until end of turn. When that creature deals combat damage to a player this turn, convert Optimus Prime. diff --git a/forge-gui/res/cardsfolder/upcoming/ultra_magnus_tactician_ultra_magnus_armored_carrier.txt b/forge-gui/res/cardsfolder/upcoming/ultra_magnus_tactician_ultra_magnus_armored_carrier.txt new file mode 100644 index 00000000000..ee968b26e16 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ultra_magnus_tactician_ultra_magnus_armored_carrier.txt @@ -0,0 +1,30 @@ +Name:Ultra Magnus, Tactician +ManaCost:4 R G W +Types:Legendary Artifact Creature Robot +PT:7/7 +K:More Than Meets the Eye:2 R G W +K:Ward:2 +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigChange | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever NICKNAME attacks, you may put an artifact creature card from your hand onto the battlefield tapped and attacking. If you do, convert NICKNAME at end of combat. +SVar:TrigChange:DB$ ChangeZone | Origin$ Hand | Destination$ Battlefield | ChangeType$ Artifact.Creature | Tapped$ True | Attacking$ True | RememberChanged$ True | SubAbility$ DBDelayedTrigger +SVar:DBDelayedTrigger:DB$ DelayedTrigger | ConditionDefined$ Remembered | ConditionPresent$ Card | Mode$ Phase | Phase$ EndCombat | ValidPlayer$ Player | Execute$ TrigConvert | SubAbility$ DBCleanup | TriggerDescription$ If you do, convert NICKNAME at end of combat. +SVar:TrigConvert:DB$ SetState | Mode$ Convert +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:HasAttackEffect:TRUE +AlternateMode:Convert +Oracle:More Than Meets the Eye {2}{R}{G}{W} (You may cast this card converted for {2}{R}{G}{W}.)\nWard {2}\nWhenever Ultra Magnus attacks, you may put an artifact creature card from your hand onto the battlefield tapped and attacking. If you do, convert Ultra Magnus at end of combat. + +ALTERNATE + +Name:Ultra Magnus, Armored Carrier +ManaCost:no cost +Colors:red,green,white +Types:Legendary Artifact Vehicle +PT:4/7 +K:Living metal +K:Haste +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Formidable — Whenever NICKNAME attacks, attacking creatures you control gain indestructible until end of turn. If those creatures have total power 8 or greater, convert NICKNAME. +SVar:TrigPump:DB$ PumpAll | ValidCards$ Creature.attacking+YouCtrl | KW$ Indestructible | SubAbility$ DBConvert +SVar:DBConvert:DB$ SetState | Mode$ Convert | ConditionCheckSVar$ FormidableTest | ConditionSVarCompare$ GE8 +SVar:FormidableTest:Count$SumPower_Creature.attacking+YouCtrl +SVar:HasAttackEffect:TRUE +Oracle:Living metal (As long as it's your turn, this Vehicle is also a creature.)\nHaste\nFormidable — Whenever Ultra Magnus attacks, attacking creatures you control gain indestructible until end of turn. If those creatures have total power 8 or greater, convert Ultra Magnus. diff --git a/forge-gui/res/lists/TypeLists.txt b/forge-gui/res/lists/TypeLists.txt index 75a3e8c516e..8e643be2944 100644 --- a/forge-gui/res/lists/TypeLists.txt +++ b/forge-gui/res/lists/TypeLists.txt @@ -217,6 +217,7 @@ Rebel:Rebels Reflection:Reflections Rhino:Rhinos Rigger:Riggers +Robot:Robots Rogue:Rogues Sable:Sables Salamander:Salamanders diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index a136355bff0..1ddc397d326 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -2766,7 +2766,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont if (!forgeCard.getName().equals(f.getName())) { forgeCard.changeToState(forgeCard.getRules().getSplitType().getChangedStateName()); if (forgeCard.getCurrentStateName().equals(CardStateName.Transformed) || - forgeCard.getCurrentStateName().equals(CardStateName.Modal)) { + forgeCard.getCurrentStateName().equals(CardStateName.Modal) || + forgeCard.getCurrentStateName().equals(CardStateName.Converted)) { forgeCard.setBackSide(true); } }