mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18:01 +00:00
Merge branch 'master' of https://git.cardforge.org/core-developers/forge
This commit is contained in:
@@ -8,7 +8,6 @@ import forge.game.GameEntity;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.ability.effects.TokenEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardLists;
|
||||
@@ -61,20 +60,9 @@ public class TokenAi extends SpellAbilityAi {
|
||||
private void readParameters(final SpellAbility mapParams) {
|
||||
this.tokenAmount = mapParams.getParamOrDefault("TokenAmount", "1");
|
||||
|
||||
TokenEffect effect = new TokenEffect();
|
||||
|
||||
this.actualToken = effect.loadTokenPrototype(mapParams);
|
||||
this.actualToken = TokenInfo.getProtoType(mapParams.getParam("TokenScript"), mapParams);
|
||||
|
||||
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.tokenToughness = mapParams.getParam("TokenToughness");
|
||||
} else {
|
||||
@@ -394,6 +382,7 @@ public class TokenAi extends SpellAbilityAi {
|
||||
* @param sa Token SpellAbility
|
||||
* @return token creature created by ability
|
||||
*/
|
||||
@Deprecated
|
||||
public static Card spawnToken(Player ai, SpellAbility sa) {
|
||||
return spawnToken(ai, sa, false);
|
||||
}
|
||||
@@ -406,9 +395,17 @@ public class TokenAi extends SpellAbilityAi {
|
||||
* @return token creature created by ability
|
||||
*/
|
||||
// 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) {
|
||||
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 tokenPower = sa.getParam("TokenPower");
|
||||
String tokenToughness = sa.getParam("TokenToughness");
|
||||
|
||||
@@ -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 AtEOT SVar
|
||||
@@ -191,6 +184,14 @@ public class GameAction {
|
||||
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.isCloned()) {
|
||||
c.switchStates(CardStateName.Original, CardStateName.Cloner, false);
|
||||
@@ -215,15 +216,15 @@ public class GameAction {
|
||||
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
|
||||
// (we need to do this on the object before copying it, or it won't work correctly e.g.
|
||||
// on Transformed objects)
|
||||
c.setState(CardStateName.Original, false);
|
||||
copied.setState(CardStateName.Original, false);
|
||||
}
|
||||
|
||||
copied = CardFactory.copyCard(c, false);
|
||||
|
||||
copied.setUnearthed(c.isUnearthed());
|
||||
copied.setTapped(false);
|
||||
|
||||
@@ -250,11 +251,10 @@ public class GameAction {
|
||||
// special rule for Worms of the Earth
|
||||
if (toBattlefield && game.getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noLandBattlefield)) {
|
||||
// something that is already a Land cant enter the battlefield
|
||||
if (c.isLand()) {
|
||||
return c;
|
||||
}
|
||||
Card noLandLKI = c;
|
||||
if (!c.isLand()) {
|
||||
// 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
|
||||
noLandLKI.setLastKnownZone(zoneTo);
|
||||
|
||||
@@ -269,7 +269,7 @@ public class GameAction {
|
||||
checkStaticAbilities(false, Sets.newHashSet(noLandLKI), preList);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(noLandLKI.isLand()) {
|
||||
// if it isn't on the Stack, it stays in that Zone
|
||||
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
|
||||
// put it into the graveyard instead
|
||||
zoneTo = c.getOwner().getZone(ZoneType.Graveyard);
|
||||
|
||||
// reset facedown
|
||||
copied.setState(CardStateName.Original, false);
|
||||
copied.setManifested(false);
|
||||
@@ -285,6 +286,26 @@ public class GameAction {
|
||||
|
||||
// not to battlefield anymore!
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -226,6 +226,10 @@ public class TokenInfo {
|
||||
}
|
||||
|
||||
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 Game game = host.getGame();
|
||||
|
||||
|
||||
@@ -100,8 +100,8 @@ public class TriggerChangesZone extends Trigger {
|
||||
if (hasParam("ValidCard")) {
|
||||
Card moved = (Card) runParams2.get("Card");
|
||||
final Game game = getHostCard().getGame();
|
||||
boolean isDiesTrig = "Battlefield".equals(getParam("Origin"))
|
||||
&& "Graveyard".equals(getParam("Destination"));
|
||||
boolean leavesBattlefield = "Battlefield".equals(getParam("Origin"));
|
||||
boolean isDiesTrig = leavesBattlefield && "Graveyard".equals(getParam("Destination"));
|
||||
|
||||
if (isDiesTrig) {
|
||||
moved = game.getChangeZoneLKIInfo(moved);
|
||||
@@ -111,6 +111,11 @@ public class TriggerChangesZone extends Trigger {
|
||||
getHostCard(), null)) {
|
||||
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")) {
|
||||
|
||||
Reference in New Issue
Block a user