Merge remote-tracking branch 'upstream/master' into editions-type-review

This commit is contained in:
leriomaggio
2021-06-25 17:13:25 +01:00
16 changed files with 39 additions and 35 deletions

View File

@@ -11,6 +11,7 @@ import forge.game.mana.ManaCostBeingPaid;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.staticability.StaticAbility; import forge.game.staticability.StaticAbility;
import forge.game.zone.ZoneType;
import forge.util.Expressions; import forge.util.Expressions;
public class ForgeScript { public class ForgeScript {
@@ -122,7 +123,6 @@ public class ForgeScript {
return Expressions.compare(y, property, x); return Expressions.compare(y, property, x);
} else return cardState.getTypeWithChanges().hasStringType(property); } else return cardState.getTypeWithChanges().hasStringType(property);
} }
public static boolean spellAbilityHasProperty(SpellAbility sa, String property, Player sourceController, public static boolean spellAbilityHasProperty(SpellAbility sa, String property, Player sourceController,
@@ -187,7 +187,14 @@ public class ForgeScript {
} else if (property.equals("OppCtrl")) { } else if (property.equals("OppCtrl")) {
return sa.getActivatingPlayer().isOpponentOf(sourceController); return sa.getActivatingPlayer().isOpponentOf(sourceController);
} else if (property.startsWith("cmc")) { } else if (property.startsWith("cmc")) {
int y = sa.getPayCosts().getTotalMana().getCMC(); int y = 0;
// spell was on the stack
if (sa.getCardState().getCard().isInZone(ZoneType.Stack)) {
y = sa.getHostCard().getCMC();
}
else {
y = sa.getPayCosts().getTotalMana().getCMC();
}
int x = AbilityUtils.calculateAmount(spellAbility.getHostCard(), property.substring(5), spellAbility); int x = AbilityUtils.calculateAmount(spellAbility.getHostCard(), property.substring(5), spellAbility);
if (!Expressions.compare(y, property, x)) { if (!Expressions.compare(y, property, x)) {
return false; return false;

View File

@@ -329,7 +329,6 @@ public abstract class SpellAbilityEffect {
} }
protected static void addSelfTrigger(final SpellAbility sa, String location, final Card card) { protected static void addSelfTrigger(final SpellAbility sa, String location, final Card card) {
String trigStr = "Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield " + String trigStr = "Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield " +
"| TriggerDescription$ At the beginning of the end step, " + location.toLowerCase() + " CARDNAME."; "| TriggerDescription$ At the beginning of the end step, " + location.toLowerCase() + " CARDNAME.";

View File

@@ -45,7 +45,6 @@ public class DestroyAllEffect extends SpellAbilityEffect {
*/ */
@Override @Override
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
final boolean noRegen = sa.hasParam("NoRegen"); final boolean noRegen = sa.hasParam("NoRegen");
final Card card = sa.getHostCard(); final Card card = sa.getHostCard();
final Game game = sa.getActivatingPlayer().getGame(); final Game game = sa.getActivatingPlayer().getGame();

View File

@@ -18,6 +18,8 @@ public class ETBReplacementEffect extends SpellAbilityEffect {
Map<AbilityKey, Object> params = AbilityKey.newMap(); Map<AbilityKey, Object> params = AbilityKey.newMap();
params.put(AbilityKey.CardLKI, sa.getReplacingObject(AbilityKey.CardLKI)); params.put(AbilityKey.CardLKI, sa.getReplacingObject(AbilityKey.CardLKI));
params.put(AbilityKey.ReplacementEffect, sa.getReplacementEffect()); params.put(AbilityKey.ReplacementEffect, sa.getReplacementEffect());
sa.getActivatingPlayer().getGame().getAction().moveToPlay(card, card.getController(), sa, params); final SpellAbility root = sa.getRootAbility();
SpellAbility cause = (SpellAbility) root.getReplacingObject(AbilityKey.Cause);
sa.getActivatingPlayer().getGame().getAction().moveToPlay(card, card.getController(), cause, params);
} }
} }

View File

@@ -150,7 +150,6 @@ public class PumpEffect extends SpellAbilityEffect {
*/ */
@Override @Override
protected String getStackDescription(final SpellAbility sa) { protected String getStackDescription(final SpellAbility sa) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
List<GameEntity> tgts = Lists.newArrayList(); List<GameEntity> tgts = Lists.newArrayList();
tgts.addAll(getCardsfromTargets(sa)); tgts.addAll(getCardsfromTargets(sa));

View File

@@ -1262,8 +1262,15 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
} }
public final int getXManaCostPaid() { public final int getXManaCostPaid() {
if (getCastSA() != null) { SpellAbility castSA;
Integer paid = getCastSA().getXManaCostPaid(); if (getCopiedPermanent() != null) {
castSA = getCopiedPermanent().getCastSA();
}
else {
castSA = getCastSA();
}
if (castSA != null) {
Integer paid = castSA.getXManaCostPaid();
return paid == null ? 0 : paid; return paid == null ? 0 : paid;
} }
return 0; return 0;

View File

@@ -534,7 +534,6 @@ public class CardFactory {
} }
public static void copySpellAbility(SpellAbility from, SpellAbility to, final Card host, final Player p, final boolean lki) { public static void copySpellAbility(SpellAbility from, SpellAbility to, final Card host, final Player p, final boolean lki) {
if (from.getTargetRestrictions() != null) { if (from.getTargetRestrictions() != null) {
to.setTargetRestrictions(from.getTargetRestrictions()); to.setTargetRestrictions(from.getTargetRestrictions());
} }
@@ -562,7 +561,7 @@ public class CardFactory {
to.setConditions((SpellAbilityCondition) from.getConditions().copy()); to.setConditions((SpellAbilityCondition) from.getConditions().copy());
} }
// do this after other abilties are copied // do this after other abilities are copied
if (p != null) { if (p != null) {
to.setActivatingPlayer(p, lki); to.setActivatingPlayer(p, lki);
} }

View File

@@ -23,7 +23,6 @@ public abstract class KeywordInstance<T extends KeywordInstance<?>> implements K
private Keyword keyword; private Keyword keyword;
private String original; private String original;
private boolean hidden; private boolean hidden;
private List<Trigger> triggers = Lists.newArrayList(); private List<Trigger> triggers = Lists.newArrayList();
@@ -206,8 +205,6 @@ public abstract class KeywordInstance<T extends KeywordInstance<?>> implements K
staticAbilities.add(st); staticAbilities.add(st);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see forge.game.keyword.KeywordInterface#getHidden() * @see forge.game.keyword.KeywordInterface#getHidden()
*/ */

View File

@@ -960,7 +960,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
return this.isAlternativeCost(AlternativeCost.Foretold); return this.isAlternativeCost(AlternativeCost.Foretold);
} }
/** /**
* @return the aftermath * @return the aftermath
*/ */

View File

@@ -111,7 +111,6 @@ public class SpellAbilityStackInstance implements IIdentifiable, IHasCardView {
ability.resetPaidHash(); ability.resetPaidHash();
splicedCards = sa.getSplicedCards(); splicedCards = sa.getSplicedCards();
// TODO getXManaCostPaid should be on the SA, not the Card
xManaPaid = sa.getXManaCostPaid(); xManaPaid = sa.getXManaCostPaid();
// Triggering info // Triggering info

View File

@@ -3,9 +3,8 @@ ManaCost:4 U U
Types:Creature Human Soldier Types:Creature Human Soldier
PT:4/3 PT:4/3
K:Flying K:Flying
A:AB$ Dig | Cost$ 1 U U | Defined$ You | DigNum$ 1 | Destination$ Exile | RememberChanged$ True | SubAbility$ DBEffect | AILogic$ ExileAndPlayUntilEOT | SpellDescription$ Exile the top card of your library. Until end of turn, you may play that card. (Reveal the card as you exile it.) A:AB$ Dig | Cost$ 1 U U | Defined$ You | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | AILogic$ ExileAndPlayUntilEOT | SpellDescription$ Exile the top card of your library. Until end of turn, you may play that card. (Reveal the card as you exile it.)
SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play | SubAbility$ DBCleanup | ExileOnMoved$ Exile SVar:DBEffect:DB$ Effect | RememberObjects$ RememberedCard | StaticAbilities$ Play | SubAbility$ DBCleanup | ExileOnMoved$ Exile
SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play remembered card. SVar:Play:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play remembered card.
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:Picture:http://www.wizards.com/global/images/magic/general/aerial_caravan.jpg
Oracle:Flying\n{1}{U}{U}: Exile the top card of your library. Until end of turn, you may play that card. (Reveal the card as you exile it.) Oracle:Flying\n{1}{U}{U}: Exile the top card of your library. Until end of turn, you may play that card. (Reveal the card as you exile it.)

View File

@@ -4,9 +4,8 @@ Types:Legendary Creature Human Wizard
PT:3/3 PT:3/3
T:Mode$ SpellCastOrCopy | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Magecraft — Whenever you cast or copy an instant or sorcery spell, create a 0/0 green and blue Fractal creature token. Put X +1/+1 counters on it, where X is that spell's mana value. T:Mode$ SpellCastOrCopy | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Magecraft — Whenever you cast or copy an instant or sorcery spell, create a 0/0 green and blue Fractal creature token. Put X +1/+1 counters on it, where X is that spell's mana value.
SVar:TrigToken:DB$ Token | TokenScript$ gu_0_0_fractal | RememberTokens$ True | SubAbility$ DBPutCounter SVar:TrigToken:DB$ Token | TokenScript$ gu_0_0_fractal | RememberTokens$ True | SubAbility$ DBPutCounter
SVar:DBPutCounter:DB$ PutCounter | Defined$ Remembered | CounterType$ P1P1 | CounterNum$ X | SubAbility$ DBCleanup SVar:DBPutCounter:DB$ PutCounter | Defined$ Remembered | CounterType$ P1P1 | CounterNum$ TriggerCount$CastSACMC | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:TriggerCount$CastSACMC
A:AB$ Pump | Cost$ 3 U | KW$ HIDDEN Unblockable | TgtPrompt$ Select target creature token | ValidTgts$ Creature.token | SpellDescription$ Target creature token can't be blocked this turn. A:AB$ Pump | Cost$ 3 U | KW$ HIDDEN Unblockable | TgtPrompt$ Select target creature token | ValidTgts$ Creature.token | SpellDescription$ Target creature token can't be blocked this turn.
DeckHas:Ability$Token & Ability$Counters DeckHas:Ability$Token & Ability$Counters
DeckNeeds:Type$Instant|Sorcery DeckNeeds:Type$Instant|Sorcery

View File

@@ -9,5 +9,5 @@ SVar:X:PlayerCountOpponents$Amount
SVar:PlayMain1:TRUE SVar:PlayMain1:TRUE
DeckHas:Ability$Token & Ability$LifeGain & Ability$Food & Ability$Sacrifice DeckHas:Ability$Token & Ability$LifeGain & Ability$Food & Ability$Sacrifice
SVar:AIPreference:SacCost$Card.Food,Card.token,Card.cmcEQ1,Card.cmcEQ2 SVar:AIPreference:SacCost$Card.Food,Card.token,Card.cmcEQ1,Card.cmcEQ2
A:AB$ Pump | Cost$ 1 G Sac<1/Permanent.Other/another nonland permanent> | Defined$ Self | NumAtt$ +2 | NumDef$ +2 | SpellDescription$ CARDNAME gets +2/+2 until end of turn. A:AB$ Pump | Cost$ 1 G Sac<1/Permanent.Other+nonLand/another nonland permanent> | Defined$ Self | NumAtt$ +2 | NumDef$ +2 | SpellDescription$ CARDNAME gets +2/+2 until end of turn.
Oracle:Trample\nWhen Gluttonous Troll enters the battlefield, create a number of Food tokens equal to the number of opponents you have. (Food tokens are artifacts with "{2}, {T}, Sacrifice this artifact: You gain 3 life.")\n{1}{G}, Sacrifice another nonland permanent: Gluttonous Troll gets +2/+2 until end of turn. Oracle:Trample\nWhen Gluttonous Troll enters the battlefield, create a number of Food tokens equal to the number of opponents you have. (Food tokens are artifacts with "{2}, {T}, Sacrifice this artifact: You gain 3 life.")\n{1}{G}, Sacrifice another nonland permanent: Gluttonous Troll gets +2/+2 until end of turn.

View File

@@ -4,8 +4,7 @@ Types:Creature Human Shaman
PT:2/2 PT:2/2
T:Mode$ SpellCastOrCopy | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Magecraft — Whenever you cast or copy an instant or sorcery spell, CARDNAME can't be blocked this turn. If that spell has mana value 5 or greater, put a +1/+1 counter on CARDNAME. T:Mode$ SpellCastOrCopy | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Magecraft — Whenever you cast or copy an instant or sorcery spell, CARDNAME can't be blocked this turn. If that spell has mana value 5 or greater, put a +1/+1 counter on CARDNAME.
SVar:TrigPump:DB$ Pump | Defined$ Self | KW$ HIDDEN Unblockable | SubAbility$ DBPutCounter SVar:TrigPump:DB$ Pump | Defined$ Self | KW$ HIDDEN Unblockable | SubAbility$ DBPutCounter
SVar:DBPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | ConditionCheckSVar$ X | ConditionSVarCompare$ GE5 SVar:DBPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | ConditionCheckSVar$ TriggerCount$CastSACMC | ConditionSVarCompare$ GE5
DeckNeeds:Type$Instant|Sorcery DeckNeeds:Type$Instant|Sorcery
DeckHas:Ability$Counters DeckHas:Ability$Counters
SVar:X:TriggeredCard$CardManaCost
Oracle:Magecraft — Whenever you cast or copy an instant or sorcery spell, Prismari Apprentice can't be blocked this turn. If that spell has mana value 5 or greater, put a +1/+1 counter on Prismari Apprentice. Oracle:Magecraft — Whenever you cast or copy an instant or sorcery spell, Prismari Apprentice can't be blocked this turn. If that spell has mana value 5 or greater, put a +1/+1 counter on Prismari Apprentice.

View File

@@ -2,11 +2,11 @@ Name:Zaffai, Thunder Conductor
ManaCost:2 U R ManaCost:2 U R
Types:Legendary Creature Human Shaman Types:Legendary Creature Human Shaman
PT:1/4 PT:1/4
T:Mode$ SpellCastOrCopy | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ DBScry | TriggerDescription$ Magecraft — Whenever you cast or copy an instant or sorcery spell, scry 1. If that spell's mana value is 5 or greater, create a 4/4 blue and red Elemental creature token. If that spell's mana value is 10 ore greater, CARDNAME deals 10 damage to an opponent chosen at random. T:Mode$ SpellCastOrCopy | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | Execute$ DBScry | TriggerDescription$ Magecraft — Whenever you cast or copy an instant or sorcery spell, scry 1. If that spell's mana value is 5 or greater, create a 4/4 blue and red Elemental creature token. If that spell's mana value is 10 or greater, CARDNAME deals 10 damage to an opponent chosen at random.
SVar:DBScry:DB$ Scry | ScryNum$ 1 | SubAbility$ DBToken SVar:DBScry:DB$ Scry | ScryNum$ 1 | SubAbility$ DBToken
SVar:DBToken:DB$ Token | TokenScript$ ur_4_4_elemental | TokenOwner$ You | ConditionPresent$ Card.cmcGE5 | ConditionDefined$ TriggeredCard | ConditionCompare$ GE1 | SubAbility$ DBChoose SVar:DBToken:DB$ Token | TokenScript$ ur_4_4_elemental | TokenOwner$ You | ConditionCheckSVar$ TriggerCount$CastSACMC | ConditionSVarCompare$ GE5 | SubAbility$ DBChoose
SVar:DBChoose:DB$ ChoosePlayer | Defined$ You | Choices$ Player.Opponent | Random$ True | SubAbility$ DBDamage SVar:DBChoose:DB$ ChoosePlayer | Defined$ You | Choices$ Player.Opponent | Random$ True | SubAbility$ DBDamage
SVar:DBDamage:DB$ DealDamage | NumDmg$ 10 | Defined$ ChosenPlayer | ConditionPresent$ Card.cmcGE10 | ConditionDefined$ TriggeredCard | ConditionCompare$ GE1 SVar:DBDamage:DB$ DealDamage | NumDmg$ 10 | Defined$ ChosenPlayer | ConditionCheckSVar$ TriggerCount$CastSACMC | ConditionSVarCompare$ GE10
DeckHas:Ability$Token DeckHas:Ability$Token
SVar:BuffedBy:Instant,Sorcery SVar:BuffedBy:Instant,Sorcery
DeckHints:Type$Instant|Sorcery DeckHints:Type$Instant|Sorcery