mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
BOT: "new" mechanics (#1679)
* CardFactoryUtil.addStaticAbility support "Living metal" keyword * GameActionUtil.getAlternativeCosts() add "More Than Meets the Eye" * Keyword.LIVING_METAL and Keyword.MORE_THAN_MEETS_THE_EYE * TypeLists add Robot * AlternativeCost.MTMtE * ultra_magnus_tactician_ultra_magnus_armored_carrier.txt * CardSplitType.Convert * CardStateName.Converted * GameState.addCard Converted check * DevModeCheats for Converted * Card.changeCardState() add Convert mode * Card.isConvertable() * PaperCard.hasBackFace add Convert * Card implement convertedTimestamp * Card.keywordsToText add Living metal to list * DamageDealEffect.internalDamageDeal move "ExcessSVar" for more flexibility * ComputerUtil.choosePermanentsToSacrifice improve AI for Megatron * megatron_tyrant_megatron_destructive_force.txt * optimus_prime_hero_optimus_prime_autobot_leader.txt * ChangeZoneEffect.changeKnownOriginResolve support "Converted" * Card.changeCardState() fixup
This commit is contained in:
@@ -840,12 +840,13 @@ public class ComputerUtil {
|
|||||||
|
|
||||||
String logic = source.getParamOrDefault("AILogic", "");
|
String logic = source.getParamOrDefault("AILogic", "");
|
||||||
if (logic.startsWith("SacForDamage")) {
|
if (logic.startsWith("SacForDamage")) {
|
||||||
if (c.getNetPower() <= 0) {
|
final int damageAmt = logic.contains("cmc") ? c.getManaCost().getCMC() : c.getNetPower();
|
||||||
|
if (damageAmt <= 0) {
|
||||||
return false;
|
return false;
|
||||||
} else if (c.getNetPower() >= ai.getOpponentsSmallestLifeTotal()) {
|
} else if (damageAmt >= ai.getOpponentsSmallestLifeTotal()) {
|
||||||
return true;
|
return true;
|
||||||
} else if (logic.endsWith(".GiantX2") && c.getType().hasCreatureType("Giant")
|
} 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?
|
return true; // TODO: generalize this for any type and actually make the AI prefer giants?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -313,6 +313,8 @@ public abstract class GameState {
|
|||||||
newText.append("|Meld");
|
newText.append("|Meld");
|
||||||
} else if (c.getCurrentStateName().equals(CardStateName.Modal)) {
|
} else if (c.getCurrentStateName().equals(CardStateName.Modal)) {
|
||||||
newText.append("|Modal");
|
newText.append("|Modal");
|
||||||
|
} else if (c.getCurrentStateName().equals(CardStateName.Converted)) {
|
||||||
|
newText.append("|Converted");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.getPlayerAttachedTo() != null) {
|
if (c.getPlayerAttachedTo() != null) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import forge.card.CardFace.FaceSelectionMethod;
|
|||||||
public enum CardSplitType
|
public enum CardSplitType
|
||||||
{
|
{
|
||||||
None(FaceSelectionMethod.USE_PRIMARY_FACE, null),
|
None(FaceSelectionMethod.USE_PRIMARY_FACE, null),
|
||||||
|
Convert(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Converted),
|
||||||
Transform(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Transformed),
|
Transform(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Transformed),
|
||||||
Meld(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Meld),
|
Meld(FaceSelectionMethod.USE_ACTIVE_FACE, CardStateName.Meld),
|
||||||
Split(FaceSelectionMethod.COMBINE, CardStateName.RightSplit),
|
Split(FaceSelectionMethod.COMBINE, CardStateName.RightSplit),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ public enum CardStateName {
|
|||||||
Original,
|
Original,
|
||||||
FaceDown,
|
FaceDown,
|
||||||
Flipped,
|
Flipped,
|
||||||
|
Converted,
|
||||||
Transformed,
|
Transformed,
|
||||||
Meld,
|
Meld,
|
||||||
LeftSplit,
|
LeftSplit,
|
||||||
|
|||||||
@@ -399,7 +399,8 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
|
|||||||
@Override
|
@Override
|
||||||
public boolean hasBackFace(){
|
public boolean hasBackFace(){
|
||||||
CardSplitType cst = this.rules.getSplitType();
|
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
|
// Return true if card is one of the five basic lands that can be added for free
|
||||||
|
|||||||
@@ -275,6 +275,28 @@ public final class GameActionUtil {
|
|||||||
foretold.setPayCosts(new Cost(k[1], false));
|
foretold.setPayCosts(new Cost(k[1], false));
|
||||||
|
|
||||||
alternatives.add(foretold);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -588,6 +588,14 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
continue;
|
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")) {
|
if (sa.hasParam("WithCountersType")) {
|
||||||
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
|
||||||
int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa);
|
int cAmount = AbilityUtils.calculateAmount(hostCard, sa.getParamOrDefault("WithCountersAmount", "1"), sa);
|
||||||
|
|||||||
@@ -298,9 +298,9 @@ public class DamageDealEffect extends DamageBaseEffect {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
damageMap.put(sourceLKI, c, dmg);
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,6 +220,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
|
|
||||||
private long bestowTimestamp = -1;
|
private long bestowTimestamp = -1;
|
||||||
private long transformedTimestamp = 0;
|
private long transformedTimestamp = 0;
|
||||||
|
private long convertedTimestamp = 0;
|
||||||
private long mutatedTimestamp = -1;
|
private long mutatedTimestamp = -1;
|
||||||
private int timesMutated = 0;
|
private int timesMutated = 0;
|
||||||
private boolean tributed = false;
|
private boolean tributed = false;
|
||||||
@@ -392,6 +393,9 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
public long getTransformedTimestamp() { return transformedTimestamp; }
|
public long getTransformedTimestamp() { return transformedTimestamp; }
|
||||||
public void incrementTransformedTimestamp() { this.transformedTimestamp++; }
|
public void incrementTransformedTimestamp() { this.transformedTimestamp++; }
|
||||||
|
|
||||||
|
public long getConvertedTimestamp() { return convertedTimestamp; }
|
||||||
|
public void incrementConvertedTimestamp() { this.convertedTimestamp++; }
|
||||||
|
|
||||||
public CardState getCurrentState() {
|
public CardState getCurrentState() {
|
||||||
return currentState;
|
return currentState;
|
||||||
}
|
}
|
||||||
@@ -625,6 +629,29 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
|
|
||||||
return retResult;
|
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")) {
|
} else if (mode.equals("Flip")) {
|
||||||
// 709.4. Flipping a permanent is a one-way process.
|
// 709.4. Flipping a permanent is a one-way process.
|
||||||
if (isFlipped()) {
|
if (isFlipped()) {
|
||||||
@@ -930,12 +957,16 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
return getRules() != null && getRules().getSplitType() == CardSplitType.Meld;
|
return getRules() != null && getRules().getSplitType() == CardSplitType.Meld;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final boolean isConvertable() {
|
||||||
|
return getRules() != null && getRules().getSplitType() == CardSplitType.Convert;
|
||||||
|
}
|
||||||
|
|
||||||
public final boolean isModal() {
|
public final boolean isModal() {
|
||||||
return getRules() != null && getRules().getSplitType() == CardSplitType.Modal;
|
return getRules() != null && getRules().getSplitType() == CardSplitType.Modal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean hasBackSide() {
|
public final boolean hasBackSide() {
|
||||||
return isDoubleFaced() || isMeldable() || isModal();
|
return isDoubleFaced() || isMeldable() || isModal() || isConvertable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isFlipCard() {
|
public final boolean isFlipCard() {
|
||||||
@@ -2035,7 +2066,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
|| keyword.startsWith("Escape") || keyword.startsWith("Foretell:")
|
|| keyword.startsWith("Escape") || keyword.startsWith("Foretell:")
|
||||||
|| keyword.startsWith("Disturb") || keyword.startsWith("Madness:")
|
|| keyword.startsWith("Disturb") || keyword.startsWith("Madness:")
|
||||||
|| keyword.startsWith("Reconfigure") || keyword.startsWith("Squad")
|
|| keyword.startsWith("Reconfigure") || keyword.startsWith("Squad")
|
||||||
|| keyword.startsWith("Miracle")) {
|
|| keyword.startsWith("Miracle") || keyword.startsWith("More Than Meets the Eye")) {
|
||||||
String[] k = keyword.split(":");
|
String[] k = keyword.split(":");
|
||||||
sbLong.append(k[0]);
|
sbLong.append(k[0]);
|
||||||
if (k.length > 1) {
|
if (k.length > 1) {
|
||||||
@@ -2148,7 +2179,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
|| keyword.equals("Living Weapon") || keyword.equals("Myriad") || keyword.equals("Exploit")
|
|| keyword.equals("Living Weapon") || keyword.equals("Myriad") || keyword.equals("Exploit")
|
||||||
|| keyword.equals("Changeling") || keyword.equals("Delve") || keyword.equals("Decayed")
|
|| keyword.equals("Changeling") || keyword.equals("Delve") || keyword.equals("Decayed")
|
||||||
|| keyword.equals("Split second") || keyword.equals("Sunburst")
|
|| 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("Suspend") // for the ones without amount
|
||||||
|| keyword.equals("Foretell") // for the ones without cost
|
|| keyword.equals("Foretell") // for the ones without cost
|
||||||
|| keyword.equals("Ascend") || keyword.equals("Totem armor")
|
|| keyword.equals("Ascend") || keyword.equals("Totem armor")
|
||||||
|
|||||||
@@ -3692,6 +3692,9 @@ public class CardFactoryUtil {
|
|||||||
String effect = "Mode$ CantBlockBy | ValidAttacker$ Creature.Self | ValidBlocker$ Creature.nonArtifact+notSharesColorWith | Secondary$ True " +
|
String effect = "Mode$ CantBlockBy | ValidAttacker$ Creature.Self | ValidBlocker$ Creature.nonArtifact+notSharesColorWith | Secondary$ True " +
|
||||||
" | Description$ Intimidate ( " + inst.getReminderText() + ")";
|
" | Description$ Intimidate ( " + inst.getReminderText() + ")";
|
||||||
inst.addStaticAbility(StaticAbility.create(effect, state.getCard(), state, intrinsic));
|
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")) {
|
} 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.";
|
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));
|
inst.addStaticAbility(StaticAbility.create(effect, state.getCard(), state, intrinsic));
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ public enum Keyword {
|
|||||||
LANDWALK("Landwalk", KeywordWithType.class, false, "This creature is unblockable as long as defending player controls a %s."),
|
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."),
|
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."),
|
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."),
|
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."),
|
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."),
|
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
|
// 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."),
|
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."),
|
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."),
|
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."),
|
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."),
|
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."),
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public enum AlternativeCost {
|
|||||||
Flashback,
|
Flashback,
|
||||||
Foretold,
|
Foretold,
|
||||||
Madness,
|
Madness,
|
||||||
|
MTMtE, // More Than Meets the Eye (Transformers Universes Beyond)
|
||||||
Mutate,
|
Mutate,
|
||||||
Offering,
|
Offering,
|
||||||
Outlast, // ActivatedAbility
|
Outlast, // ActivatedAbility
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -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.
|
||||||
@@ -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.
|
||||||
@@ -217,6 +217,7 @@ Rebel:Rebels
|
|||||||
Reflection:Reflections
|
Reflection:Reflections
|
||||||
Rhino:Rhinos
|
Rhino:Rhinos
|
||||||
Rigger:Riggers
|
Rigger:Riggers
|
||||||
|
Robot:Robots
|
||||||
Rogue:Rogues
|
Rogue:Rogues
|
||||||
Sable:Sables
|
Sable:Sables
|
||||||
Salamander:Salamanders
|
Salamander:Salamanders
|
||||||
|
|||||||
@@ -2766,7 +2766,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
|||||||
if (!forgeCard.getName().equals(f.getName())) {
|
if (!forgeCard.getName().equals(f.getName())) {
|
||||||
forgeCard.changeToState(forgeCard.getRules().getSplitType().getChangedStateName());
|
forgeCard.changeToState(forgeCard.getRules().getSplitType().getChangedStateName());
|
||||||
if (forgeCard.getCurrentStateName().equals(CardStateName.Transformed) ||
|
if (forgeCard.getCurrentStateName().equals(CardStateName.Transformed) ||
|
||||||
forgeCard.getCurrentStateName().equals(CardStateName.Modal)) {
|
forgeCard.getCurrentStateName().equals(CardStateName.Modal) ||
|
||||||
|
forgeCard.getCurrentStateName().equals(CardStateName.Converted)) {
|
||||||
forgeCard.setBackSide(true);
|
forgeCard.setBackSide(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user