This commit is contained in:
churrufli
2019-02-23 20:25:57 +01:00
4 changed files with 69 additions and 42 deletions

View File

@@ -8,7 +8,6 @@ import forge.game.GameEntity;
import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityFactory;
import forge.game.ability.AbilityUtils; import forge.game.ability.AbilityUtils;
import forge.game.ability.ApiType; import forge.game.ability.ApiType;
import forge.game.ability.effects.TokenEffect;
import forge.game.card.Card; import forge.game.card.Card;
import forge.game.card.CardCollection; import forge.game.card.CardCollection;
import forge.game.card.CardLists; import forge.game.card.CardLists;
@@ -61,20 +60,9 @@ public class TokenAi extends SpellAbilityAi {
private void readParameters(final SpellAbility mapParams) { private void readParameters(final SpellAbility mapParams) {
this.tokenAmount = mapParams.getParamOrDefault("TokenAmount", "1"); this.tokenAmount = mapParams.getParamOrDefault("TokenAmount", "1");
TokenEffect effect = new TokenEffect(); this.actualToken = TokenInfo.getProtoType(mapParams.getParam("TokenScript"), mapParams);
this.actualToken = effect.loadTokenPrototype(mapParams);
if (actualToken == null) { if (actualToken == null) {
String[] keywords;
if (mapParams.hasParam("TokenKeywords")) {
// TODO: Change this Split to a semicolon or something else
keywords = mapParams.getParam("TokenKeywords").split("<>");
} else {
keywords = new String[0];
}
this.tokenPower = mapParams.getParam("TokenPower"); this.tokenPower = mapParams.getParam("TokenPower");
this.tokenToughness = mapParams.getParam("TokenToughness"); this.tokenToughness = mapParams.getParam("TokenToughness");
} else { } else {
@@ -394,6 +382,7 @@ public class TokenAi extends SpellAbilityAi {
* @param sa Token SpellAbility * @param sa Token SpellAbility
* @return token creature created by ability * @return token creature created by ability
*/ */
@Deprecated
public static Card spawnToken(Player ai, SpellAbility sa) { public static Card spawnToken(Player ai, SpellAbility sa) {
return spawnToken(ai, sa, false); return spawnToken(ai, sa, false);
} }
@@ -406,9 +395,17 @@ public class TokenAi extends SpellAbilityAi {
* @return token creature created by ability * @return token creature created by ability
*/ */
// TODO Is this just completely copied from TokenEffect? Let's just call that thing // TODO Is this just completely copied from TokenEffect? Let's just call that thing
@Deprecated
public static Card spawnToken(Player ai, SpellAbility sa, boolean notNull) { public static Card spawnToken(Player ai, SpellAbility sa, boolean notNull) {
final Card host = sa.getHostCard(); final Card host = sa.getHostCard();
Card result = TokenInfo.getProtoType(sa.getParam("TokenScript"), sa);
if (result != null) {
result.setController(ai, 0);
return result;
}
String[] tokenKeywords = sa.hasParam("TokenKeywords") ? sa.getParam("TokenKeywords").split("<>") : new String[0]; String[] tokenKeywords = sa.hasParam("TokenKeywords") ? sa.getParam("TokenKeywords").split("<>") : new String[0];
String tokenPower = sa.getParam("TokenPower"); String tokenPower = sa.getParam("TokenPower");
String tokenToughness = sa.getParam("TokenToughness"); String tokenToughness = sa.getParam("TokenToughness");

View File

@@ -147,13 +147,6 @@ public class GameAction {
} }
} }
// Cards returned from exile face-down must be reset to their original state, otherwise
// all sort of funky shenanigans may happen later (e.g. their ETB replacement effects are set
// up on the wrong card state etc.).
if (wasFacedown && (fromBattlefield || (toHand && zoneFrom.is(ZoneType.Exile)))) {
c.setState(CardStateName.Original, true);
c.runFaceupCommands();
}
// Clean up the temporary Dash SVar when the Dashed card leaves the battlefield // Clean up the temporary Dash SVar when the Dashed card leaves the battlefield
// Clean up the temporary AtEOT SVar // Clean up the temporary AtEOT SVar
@@ -191,6 +184,14 @@ public class GameAction {
lastKnownInfo = CardUtil.getLKICopy(c); lastKnownInfo = CardUtil.getLKICopy(c);
} }
// Cards returned from exile face-down must be reset to their original state, otherwise
// all sort of funky shenanigans may happen later (e.g. their ETB replacement effects are set
// up on the wrong card state etc.).
if (wasFacedown && (fromBattlefield || (toHand && zoneFrom.is(ZoneType.Exile)))) {
c.setState(CardStateName.Original, true);
c.runFaceupCommands();
}
if (!c.isToken()) { if (!c.isToken()) {
if (c.isCloned()) { if (c.isCloned()) {
c.switchStates(CardStateName.Original, CardStateName.Cloner, false); c.switchStates(CardStateName.Original, CardStateName.Cloner, false);
@@ -215,15 +216,15 @@ public class GameAction {
c.updateStateForView(); c.updateStateForView();
} }
if (fromBattlefield && c.getCurrentStateName() != CardStateName.Original) { copied = CardFactory.copyCard(c, false);
if (fromBattlefield && copied.getCurrentStateName() != CardStateName.Original) {
// when a card leaves the battlefield, ensure it's in its original state // when a card leaves the battlefield, ensure it's in its original state
// (we need to do this on the object before copying it, or it won't work correctly e.g. // (we need to do this on the object before copying it, or it won't work correctly e.g.
// on Transformed objects) // on Transformed objects)
c.setState(CardStateName.Original, false); copied.setState(CardStateName.Original, false);
} }
copied = CardFactory.copyCard(c, false);
copied.setUnearthed(c.isUnearthed()); copied.setUnearthed(c.isUnearthed());
copied.setTapped(false); copied.setTapped(false);
@@ -250,11 +251,10 @@ public class GameAction {
// special rule for Worms of the Earth // special rule for Worms of the Earth
if (toBattlefield && game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noLandBattlefield)) { if (toBattlefield && game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noLandBattlefield)) {
// something that is already a Land cant enter the battlefield // something that is already a Land cant enter the battlefield
if (c.isLand()) { Card noLandLKI = c;
return c; if (!c.isLand()) {
}
// check if something would be a land // check if something would be a land
Card noLandLKI = CardUtil.getLKICopy(c); noLandLKI = CardUtil.getLKICopy(c);
// this check needs to check if this card would be on the battlefield // this check needs to check if this card would be on the battlefield
noLandLKI.setLastKnownZone(zoneTo); noLandLKI.setLastKnownZone(zoneTo);
@@ -269,7 +269,7 @@ public class GameAction {
checkStaticAbilities(false, Sets.newHashSet(noLandLKI), preList); checkStaticAbilities(false, Sets.newHashSet(noLandLKI), preList);
} }
} }
}
if(noLandLKI.isLand()) { if(noLandLKI.isLand()) {
// if it isn't on the Stack, it stays in that Zone // if it isn't on the Stack, it stays in that Zone
if (!c.getZone().is(ZoneType.Stack)) { if (!c.getZone().is(ZoneType.Stack)) {
@@ -278,6 +278,7 @@ public class GameAction {
// if something would only be a land when entering the battlefield and not before // if something would only be a land when entering the battlefield and not before
// put it into the graveyard instead // put it into the graveyard instead
zoneTo = c.getOwner().getZone(ZoneType.Graveyard); zoneTo = c.getOwner().getZone(ZoneType.Graveyard);
// reset facedown // reset facedown
copied.setState(CardStateName.Original, false); copied.setState(CardStateName.Original, false);
copied.setManifested(false); copied.setManifested(false);
@@ -285,6 +286,26 @@ public class GameAction {
// not to battlefield anymore! // not to battlefield anymore!
toBattlefield = false; toBattlefield = false;
if (copied.isCloned()) {
copied.switchStates(CardStateName.Original, CardStateName.Cloner, false);
copied.setState(CardStateName.Original, false);
copied.clearStates(CardStateName.Cloner, false);
if (copied.isFlipCard()) {
copied.clearStates(CardStateName.Flipped, false);
}
if (copied.getStates().contains(CardStateName.OriginalText)) {
copied.clearStates(CardStateName.OriginalText, false);
copied.removeSVar("GainingTextFrom");
copied.removeSVar("GainingTextFromTimestamp");
}
}
if (copied.getCurrentStateName() != CardStateName.Original) {
copied.setState(CardStateName.Original, false);
}
copied.updateStateForView();
} }
} }

View File

@@ -226,6 +226,10 @@ public class TokenInfo {
} }
static public Card getProtoType(final String script, final SpellAbility sa) { static public Card getProtoType(final String script, final SpellAbility sa) {
// script might be null, or sa might be null
if (script == null || sa == null) {
return null;
}
final Card host = sa.getHostCard(); final Card host = sa.getHostCard();
final Game game = host.getGame(); final Game game = host.getGame();

View File

@@ -100,8 +100,8 @@ public class TriggerChangesZone extends Trigger {
if (hasParam("ValidCard")) { if (hasParam("ValidCard")) {
Card moved = (Card) runParams2.get("Card"); Card moved = (Card) runParams2.get("Card");
final Game game = getHostCard().getGame(); final Game game = getHostCard().getGame();
boolean isDiesTrig = "Battlefield".equals(getParam("Origin")) boolean leavesBattlefield = "Battlefield".equals(getParam("Origin"));
&& "Graveyard".equals(getParam("Destination")); boolean isDiesTrig = leavesBattlefield && "Graveyard".equals(getParam("Destination"));
if (isDiesTrig) { if (isDiesTrig) {
moved = game.getChangeZoneLKIInfo(moved); moved = game.getChangeZoneLKIInfo(moved);
@@ -111,6 +111,11 @@ public class TriggerChangesZone extends Trigger {
getHostCard(), null)) { getHostCard(), null)) {
return false; return false;
} }
// if it is a die trigger, and the hostcard is the moved one, but it doesn't has the trigger
if (leavesBattlefield && moved.equals(getHostCard()) && !moved.hasTrigger(this)) {
return false;
}
} }
if (hasParam("ValidCause")) { if (hasParam("ValidCause")) {