*Added ETBReplacement:<Mode>:<SVar>[:Optional] keyword.

*Added ActiveZones parameter to replacement effects to let replacement effects function wherever.
*Converted clones to ETBReplacement
*Added Essence of the Wild
*CardCharacteristics now copy ReplacementEffects
*ReplacementEffects now copy alot more stuff.
*Divvied up Replacement Effect running into layers
*Moved stuff common between Trigger and ReplacementEffect to TriggerReplacementBase
*Let AF_Tap tap cards on the stack in order to work with ETBReplacement.
*Converted Remote Farm to ETBReplacement.
This commit is contained in:
Hellfish
2012-08-31 22:23:02 +00:00
parent 086a2c3cee
commit 2f40a48ecd
90 changed files with 531 additions and 236 deletions

View File

@@ -41,6 +41,7 @@ import forge.card.cardfactory.CardFactoryUtil;
import forge.card.cost.Cost;
import forge.card.mana.ManaCost;
import forge.card.replacement.ReplacementEffect;
import forge.card.replacement.ReplacementResult;
import forge.card.spellability.AbilityMana;
import forge.card.spellability.AbilityTriggered;
import forge.card.spellability.Spell;
@@ -2322,6 +2323,8 @@ public class Card extends GameEntity implements Comparable<Card> {
sbLong.append("defending player controls untap and block it if able.)");
} else if (keyword.get(i).startsWith("MayEffectFromOpeningHand")) {
continue;
} else if (keyword.get(i).startsWith("ETBReplacement")) {
continue;
} else if (keyword.get(i).contains("Haunt")) {
sb.append("\r\nHaunt (");
if (this.isCreature()) {
@@ -5079,6 +5082,9 @@ public class Card extends GameEntity implements Comparable<Card> {
* </p>
*/
public final void untap() {
if(getName().equals("Remote Farm")) {
System.out.println("HE TOUCHED ME");
}
if (this.isTapped()) {
// Run triggers
final Map<String, Object> runParams = new TreeMap<String, Object>();
@@ -8065,7 +8071,7 @@ public class Card extends GameEntity implements Comparable<Card> {
repParams.put("IsCombat", isCombat);
repParams.put("Prevention", true);
if (AllZone.getReplacementHandler().run(repParams)) {
if (AllZone.getReplacementHandler().run(repParams) != ReplacementResult.NotReplaced) {
return 0;
}
@@ -8192,7 +8198,7 @@ public class Card extends GameEntity implements Comparable<Card> {
repParams.put("DamageAmount", damageIn);
repParams.put("IsCombat", isCombat);
if (AllZone.getReplacementHandler().run(repParams)) {
if (AllZone.getReplacementHandler().run(repParams) != ReplacementResult.NotReplaced) {
return 0;
}

View File

@@ -33,6 +33,7 @@ import forge.card.cost.Cost;
import forge.card.cost.CostPayment;
import forge.card.mana.ManaCost;
import forge.card.mana.ManaCostShard;
import forge.card.replacement.ReplacementResult;
import forge.card.spellability.Ability;
import forge.card.spellability.AbilityActivated;
import forge.card.spellability.AbilityStatic;
@@ -128,8 +129,9 @@ public class GameAction {
repParams.put("Origin", zoneFrom != null ? zoneFrom.getZoneType() : null);
repParams.put("Destination", zoneTo.getZoneType());
if (AllZone.getReplacementHandler().run(repParams)) {
if (AllZone.getStack().isResolving(c) && !zoneTo.is(ZoneType.Graveyard)) {
ReplacementResult repres = AllZone.getReplacementHandler().run(repParams);
if (repres != ReplacementResult.NotReplaced) {
if (AllZone.getStack().isResolving(c) && !zoneTo.is(ZoneType.Graveyard) && repres == ReplacementResult.Prevented) {
return Singletons.getModel().getGameAction().moveToGraveyard(c);
}
return c;

View File

@@ -488,6 +488,11 @@ public class CardCharacteristics {
this.sVars = new TreeMap<String, String>(source.getSVars());
// String curSetCode = "";
this.curSetCode = source.getCurSetCode();
this.replacementEffects = new ArrayList<ReplacementEffect>();
for(ReplacementEffect RE : source.getReplacementEffects()) {
this.replacementEffects.add(RE.getCopy());
}
}
/**

View File

@@ -1,7 +1,12 @@
package forge.card;
import java.util.EnumSet;
import forge.Card;
import forge.GameEntity;
import forge.card.spellability.SpellAbility;
import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType;
/**
* Base class for Triggers and ReplacementEffects.
@@ -9,6 +14,75 @@ import forge.GameEntity;
*
*/
public abstract class TriggerReplacementBase {
/** The host card. */
protected Card hostCard;
/**
* <p>
* Getter for the field <code>hostCard</code>.
* </p>
*
* @return a {@link forge.Card} object.
*/
public final Card getHostCard() {
return this.hostCard;
}
/**
* <p>
* Setter for the field <code>hostCard</code>.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void setHostCard(final Card c) {
this.hostCard = c;
}
protected EnumSet<ZoneType> validHostZones;
public void setActiveZone(EnumSet<ZoneType> zones) {
validHostZones = zones;
}
/**
* <p>
* zonesCheck.
* </p>
*
* @return a boolean.
*/
public final boolean zonesCheck(PlayerZone hostCardZone) {
return !this.hostCard.isPhasedOut()
&& (validHostZones == null || validHostZones.isEmpty()
|| (hostCardZone != null && validHostZones.contains(hostCardZone.getZoneType()))
);
}
/** The overriding ability. */
private SpellAbility overridingAbility = null;
/**
* Gets the overriding ability.
*
* @return the overridingAbility
*/
public SpellAbility getOverridingAbility() {
return this.overridingAbility;
}
/**
* Sets the overriding ability.
*
* @param overridingAbility0
* the overridingAbility to set
*/
public void setOverridingAbility(final SpellAbility overridingAbility0) {
this.overridingAbility = overridingAbility0;
}
/**
* <p>
* matchesValid.

View File

@@ -2823,6 +2823,10 @@ public class AbilityFactory {
final AbilityFactory af = sa.getAbilityFactory();
if (af == null) {
sa.resolve();
if(sa.getSubAbility() != null)
{
resolve(sa.getSubAbility(),usedStack);
}
return;
}
final HashMap<String, String> params = af.getMapParams();

View File

@@ -1228,7 +1228,7 @@ public class AbilityFactoryPermanentState {
}
for (final Card tgtC : tgtCards) {
if (AllZoneUtil.isCardInPlay(tgtC) && ((tgt == null) || tgtC.canBeTargetedBy(sa))) {
if ((AllZoneUtil.isCardInPlay(tgtC) || AllZone.getZoneOf(tgtC).is(ZoneType.Stack)) && ((tgt == null) || tgtC.canBeTargetedBy(sa))) {
if (tgtC.isUntapped() && (remTapped)) {
card.addRemembered(tgtC);
}

View File

@@ -27,6 +27,7 @@ import com.esotericsoftware.minlog.Log;
import forge.AllZone;
import forge.AllZoneUtil;
import forge.Card;
import forge.CardCharacteristicName;
import forge.CardList;
import forge.CardListFilter;
import forge.CardUtil;
@@ -36,6 +37,9 @@ import forge.Counters;
import forge.Singletons;
import forge.card.abilityfactory.AbilityFactory;
import forge.card.cost.Cost;
import forge.card.replacement.ReplacementEffect;
import forge.card.replacement.ReplacementHandler;
import forge.card.replacement.ReplacementLayer;
import forge.card.spellability.Ability;
import forge.card.spellability.AbilityActivated;
import forge.card.spellability.AbilityStatic;
@@ -1476,6 +1480,47 @@ public class CardFactoryCreatures {
card.addSpellAbility(finalAb);
}
private static void getCard_EssenceOfTheWild(final Card card,final String cardName) {
class EOTWReplacement extends Ability {
/**
* TODO: Write javadoc for Constructor.
* @param sourceCard
* @param manaCost
*/
public EOTWReplacement(Card sourceCard, String manaCost) {
super(sourceCard, manaCost);
}
/* (non-Javadoc)
* @see forge.card.spellability.SpellAbility#resolve()
*/
@Override
public void resolve() {
Card movedCard = (Card)this.getReplacingObject("Card");
if (movedCard.isCloned()) { // cloning again
movedCard.switchStates(CardCharacteristicName.Cloner, CardCharacteristicName.Original);
movedCard.setState(CardCharacteristicName.Original);
movedCard.clearStates(CardCharacteristicName.Cloner);
}
movedCard.addAlternateState(CardCharacteristicName.Cloner);
movedCard.switchStates(CardCharacteristicName.Original, CardCharacteristicName.Cloner);
movedCard.setState(CardCharacteristicName.Original);
movedCard.getCharacteristics().copy(this.getSourceCard().getCharacteristics());
}
}
SpellAbility repAb = new EOTWReplacement(card,"0");
CardFactoryUtil.setupETBReplacementAbility(repAb);
ReplacementEffect re = ReplacementHandler.parseReplacement("Event$ Moved | ValidCard$ Creature.Other+YouCtrl | Destination$ Battlefield | ActiveZones$ Battlefield | Description$ Creatures you control enter the battlefield as copies of CARDNAME.", card);
re.setLayer(ReplacementLayer.Copy);
re.setOverridingAbility(repAb);
card.addReplacementEffect(re);
}
// // This is a hardcoded card template
//
@@ -1532,7 +1577,10 @@ public class CardFactoryCreatures {
} else if (cardName.equals("Duct Crawler") || cardName.equals("Shrewd Hatchling")
|| cardName.equals("Spin Engine") || cardName.equals("Screeching Griffin")) {
getCard_DuctCrawler(card, cardName);
} else if (cardName.equals("Essence of the Wild")) {
getCard_EssenceOfTheWild(card, cardName);
}
// ***************************************************
// end of card specific code

View File

@@ -46,10 +46,14 @@ import forge.card.abilityfactory.AbilityFactory;
import forge.card.cost.Cost;
import forge.card.mana.ManaCost;
import forge.card.mana.ManaCostShard;
import forge.card.replacement.ReplacementEffect;
import forge.card.replacement.ReplacementHandler;
import forge.card.replacement.ReplacementLayer;
import forge.card.spellability.Ability;
import forge.card.spellability.AbilityActivated;
import forge.card.spellability.AbilityMana;
import forge.card.spellability.AbilityStatic;
import forge.card.spellability.AbilitySub;
import forge.card.spellability.Spell;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityRestriction;
@@ -4807,9 +4811,89 @@ public class CardFactoryUtil {
// add ability to instrinic strings so copies/clones create the ability also
card.getIntrinsicAbilities().add(abilityStr.toString());
}
final int etbrep = CardFactoryUtil.hasKeyword(card, "ETBReplacement");
if (etbrep != -1)
{
String fullkw = card.getKeyword().get(etbrep);
card.getKeyword().remove(etbrep);
String[] splitkw = fullkw.split(":");
ReplacementLayer layer = ReplacementLayer.smartValueOf(splitkw[1]);
AbilityFactory af = new AbilityFactory();
SpellAbility repAb = af.getAbility(card.getSVar(splitkw[2]), card);
String desc = repAb.getDescription();
setupETBReplacementAbility(repAb);
String repeffstr = "Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | Description$ " + desc;
if(splitkw.length == 4) {
if(splitkw[3].contains("Optional")) {
repeffstr += " | OptionalDecider$ You";
}
}
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card);
re.setLayer(layer);
re.setOverridingAbility(repAb);
card.addReplacementEffect(re);
}
return card;
}
public static void setupETBReplacementAbility(SpellAbility sa) {
SpellAbility tailend = sa;
while(tailend.getSubAbility() != null) {
tailend = tailend.getSubAbility();
}
class ETBReplacementMove extends AbilitySub {
private static final long serialVersionUID = 704771599662730112L;
/**
* TODO: Write javadoc for Constructor.
* @param sourceCard
* @param tgt
*/
public ETBReplacementMove(Card sourceCard, Target tgt) {
super(sourceCard, tgt);
}
@Override
public void resolve() {
forge.Singletons.getModel().getGameAction().moveToPlay(((Card)this.getReplacingObject("Card")));
}
/* (non-Javadoc)
* @see forge.card.spellability.AbilitySub#chkAIDrawback()
*/
@Override
public boolean chkAIDrawback() {
return false;
}
/* (non-Javadoc)
* @see forge.card.spellability.AbilitySub#getCopy()
*/
@Override
public AbilitySub getCopy() {
// TODO Auto-generated method stub
return new ETBReplacementMove(getSourceCard(),null);
}
/* (non-Javadoc)
* @see forge.card.spellability.AbilitySub#doTrigger(boolean)
*/
@Override
public boolean doTrigger(boolean mandatory) {
// TODO Auto-generated method stub
return false;
}
}
tailend.setSubAbility(new ETBReplacementMove(sa.getSourceCard(),null));
}
/**
* <p>

View File

@@ -100,7 +100,11 @@ public class ReplaceDamage extends ReplacementEffect {
*/
@Override
public ReplacementEffect getCopy() {
return new ReplaceDamage(this.getMapParams(), this.getHostCard());
ReplacementEffect res = new ReplaceDamage(this.getMapParams(), this.getHostCard());
res.setOverridingAbility(this.getOverridingAbility());
res.setActiveZone(validHostZones);
res.setLayer(getLayer());
return res;
}
/* (non-Javadoc)

View File

@@ -59,7 +59,11 @@ public class ReplaceDraw extends ReplacementEffect {
*/
@Override
public ReplacementEffect getCopy() {
return new ReplaceDraw(this.getMapParams(), getHostCard());
ReplacementEffect res = new ReplaceDraw(this.getMapParams(), this.getHostCard());
res.setOverridingAbility(this.getOverridingAbility());
res.setActiveZone(validHostZones);
res.setLayer(getLayer());
return res;
}
}

View File

@@ -60,7 +60,11 @@ public class ReplaceGainLife extends ReplacementEffect {
*/
@Override
public ReplacementEffect getCopy() {
return new ReplaceGainLife(this.getMapParams(), getHostCard());
ReplacementEffect res = new ReplaceGainLife(this.getMapParams(), this.getHostCard());
res.setOverridingAbility(this.getOverridingAbility());
res.setActiveZone(validHostZones);
res.setLayer(getLayer());
return res;
}
/* (non-Javadoc)

View File

@@ -42,7 +42,11 @@ public class ReplaceGameLoss extends ReplacementEffect {
*/
@Override
public ReplacementEffect getCopy() {
return new ReplaceGameLoss(this.getMapParams(), getHostCard());
ReplacementEffect res = new ReplaceGameLoss(this.getMapParams(), this.getHostCard());
res.setOverridingAbility(this.getOverridingAbility());
res.setActiveZone(validHostZones);
res.setLayer(getLayer());
return res;
}
}

View File

@@ -56,7 +56,11 @@ public class ReplaceMoved extends ReplacementEffect {
*/
@Override
public ReplacementEffect getCopy() {
return new ReplaceMoved(this.getMapParams(), this.getHostCard());
ReplacementEffect res = new ReplaceMoved(this.getMapParams(), this.getHostCard());
res.setOverridingAbility(this.getOverridingAbility());
res.setActiveZone(validHostZones);
res.setLayer(getLayer());
return res;
}
/* (non-Javadoc)

View File

@@ -35,6 +35,8 @@ import forge.game.zone.ZoneType;
*/
public abstract class ReplacementEffect extends TriggerReplacementBase {
private ReplacementLayer layer = ReplacementLayer.None;
/** The has run. */
private boolean hasRun = false;
@@ -135,32 +137,6 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
this.mapParams = mapParams;
}
/** The host card. */
private Card hostCard;
/**
* <p>
* Getter for the field <code>hostCard</code>.
* </p>
*
* @return a {@link forge.Card} object.
*/
public final Card getHostCard() {
return this.hostCard;
}
/**
* <p>
* Setter for the field <code>hostCard</code>.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void setHostCard(final Card c) {
this.hostCard = c;
}
/**
* Can replace.
*
@@ -415,4 +391,18 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
this.setMapParams(map);
this.setHostCard(host);
}
/**
* @return the layer
*/
public ReplacementLayer getLayer() {
return layer;
}
/**
* @param layer0 the layer to set
*/
public void setLayer(ReplacementLayer layer0) {
this.layer = layer0;
}
}

View File

@@ -18,6 +18,7 @@
package forge.card.replacement;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
@@ -40,17 +41,8 @@ public class ReplacementHandler {
private final List<ReplacementEffect> tmpEffects = new ArrayList<ReplacementEffect>();
/**
*
* Runs any applicable replacement effects.
*
* @param runParams
* the run params,same as for triggers.
* @return true if the event was replaced.
*/
public boolean run(final HashMap<String, Object> runParams) {
public ReplacementResult run(final HashMap<String, Object> runParams) {
final Object affected = runParams.get("Affected");
final List<ReplacementEffect> possibleReplacers = new ArrayList<ReplacementEffect>();
Player decider = null;
// Figure out who decides which of multiple replacements to apply
@@ -60,21 +52,66 @@ public class ReplacementHandler {
} else {
decider = ((Card) affected).getController();
}
if(runParams.get("Event").equals("Moved")) {
ReplacementResult res = run(runParams,ReplacementLayer.Control,decider);
if(res != ReplacementResult.NotReplaced) {
return res;
}
res = run(runParams,ReplacementLayer.Copy,decider);
if(res != ReplacementResult.NotReplaced) {
return res;
}
res = run(runParams,ReplacementLayer.Other,decider);
if(res != ReplacementResult.NotReplaced) {
return res;
}
res = run(runParams,ReplacementLayer.None,decider);
if(res != ReplacementResult.NotReplaced) {
return res;
}
}
else {
ReplacementResult res = run(runParams,ReplacementLayer.None,decider);
if(res != ReplacementResult.NotReplaced) {
return res;
}
}
return ReplacementResult.NotReplaced;
}
/**
*
* Runs any applicable replacement effects.
*
* @param runParams
* the run params,same as for triggers.
* @return true if the event was replaced.
*/
public ReplacementResult run(final HashMap<String, Object> runParams, final ReplacementLayer layer,final Player decider) {
final List<ReplacementEffect> possibleReplacers = new ArrayList<ReplacementEffect>();
if(layer == ReplacementLayer.Other && ((String)runParams.get("Event")).equals("Moved")) {
System.out.println("Shdf");
}
// Round up Non-static replacement effects ("Until EOT," or
// "The next time you would..." etc)
for (final ReplacementEffect replacementEffect : this.tmpEffects) {
if (!replacementEffect.hasRun() && replacementEffect.canReplace(runParams)) {
if (!replacementEffect.hasRun() && replacementEffect.canReplace(runParams) && replacementEffect.getLayer() == layer) {
possibleReplacers.add(replacementEffect);
}
}
// Round up Static replacement effects
for (final Player p : AllZone.getPlayersInGame()) {
for (final Card crd : p.getCardsIn(ZoneType.Battlefield)) {
for (final Card crd : p.getAllCards()) {
for (final ReplacementEffect replacementEffect : crd.getReplacementEffects()) {
if (replacementEffect.requirementsCheck()) {
if (!replacementEffect.hasRun() && replacementEffect.canReplace(runParams)) {
if (!replacementEffect.hasRun() && replacementEffect.canReplace(runParams) && replacementEffect.getLayer() == layer && replacementEffect.zonesCheck(AllZone.getZoneOf(crd))) {
possibleReplacers.add(replacementEffect);
}
}
@@ -83,7 +120,7 @@ public class ReplacementHandler {
}
if (possibleReplacers.isEmpty()) {
return false;
return ReplacementResult.NotReplaced;
}
ReplacementEffect chosenRE = null;
@@ -106,23 +143,24 @@ public class ReplacementHandler {
possibleReplacers.remove(chosenRE);
if (chosenRE != null) {
chosenRE.setHasRun(true);
if (this.executeReplacement(runParams, chosenRE, decider)) {
chosenRE.setHasRun(true);
ReplacementResult res = this.executeReplacement(runParams, chosenRE, decider);
if (res != ReplacementResult.NotReplaced) {
chosenRE.setHasRun(false);
AllZone.getGameLog().add("ReplacementEffect", chosenRE.toString(), 2);
return true;
return res;
} else {
if (possibleReplacers.size() == 0) {
return false;
return res;
}
else {
boolean ret = run(runParams);
ReplacementResult ret = run(runParams);
chosenRE.setHasRun(false);
return ret;
}
}
} else {
return false;
return ReplacementResult.NotReplaced;
}
}
@@ -134,9 +172,11 @@ public class ReplacementHandler {
* @param replacementEffect
* the replacement effect to run
*/
private boolean executeReplacement(final HashMap<String, Object> runParams,
private ReplacementResult executeReplacement(final HashMap<String, Object> runParams,
final ReplacementEffect replacementEffect, final Player decider) {
if(replacementEffect.getHostCard().getName().equals("Clone")) {
System.out.println("And here we go.");
}
final HashMap<String, String> mapParams = replacementEffect.getMapParams();
SpellAbility effectSA = null;
@@ -149,7 +189,21 @@ public class ReplacementHandler {
effectSA = abilityFactory.getAbility(effectAbString, replacementEffect.getHostCard());
replacementEffect.setReplacingObjects(runParams, effectSA);
SpellAbility tailend = effectSA;
do
{
replacementEffect.setReplacingObjects(runParams, tailend);
tailend = tailend.getSubAbility();
} while(tailend != null);
}
else if (replacementEffect.getOverridingAbility() != null) {
effectSA = replacementEffect.getOverridingAbility();
SpellAbility tailend = effectSA;
do
{
replacementEffect.setReplacingObjects(runParams, tailend);
tailend = tailend.getSubAbility();
} while(tailend != null);
}
// Decider gets to choose wether or not to apply the replacement.
@@ -168,19 +222,19 @@ public class ReplacementHandler {
buildQuestion.append(replacementEffect.toString());
buildQuestion.append(")");
if (!GameActionUtil.showYesNoDialog(replacementEffect.getHostCard(), buildQuestion.toString())) {
return false;
return ReplacementResult.NotReplaced;
}
} else {
// AI-logic
if (!replacementEffect.aiShouldRun(effectSA)) {
return false;
return ReplacementResult.NotReplaced;
}
}
}
if (mapParams.containsKey("Prevent")) {
if (mapParams.get("Prevent").equals("True")) {
return true; // Nothing should replace the event.
return ReplacementResult.Prevented; // Nothing should replace the event.
}
}
@@ -190,7 +244,7 @@ public class ReplacementHandler {
ComputerUtil.playNoStack(effectSA);
}
return true;
return ReplacementResult.Replaced;
}
/**
@@ -235,6 +289,11 @@ public class ReplacementHandler {
} else if (eventToReplace.equals("Moved")) {
ret = new ReplaceMoved(mapParams, host);
}
String activeZones = mapParams.get("ActiveZones");
if (null != activeZones) {
ret.setActiveZone(EnumSet.copyOf(ZoneType.listValueOf(activeZones)));
}
return ret;
}

View File

@@ -0,0 +1,32 @@
package forge.card.replacement;
import forge.CardCharacteristicName;
/**
* TODO: Write javadoc for this type.
*
*/
public enum ReplacementLayer {
Control,
Copy,
Other,
None;
/**
* TODO: Write javadoc for this method.
* @param substring
* @return
*/
public static ReplacementLayer smartValueOf(String value) {
if (value == null) {
return null;
}
final String valToCompate = value.trim();
for (final ReplacementLayer v : ReplacementLayer.values()) {
if (v.name().compareToIgnoreCase(valToCompate) == 0) {
return v;
}
}
throw new IllegalArgumentException("No element named " + value + " in enum ReplacementLayer");
}
}

View File

@@ -0,0 +1,11 @@
package forge.card.replacement;
/**
* TODO: Write javadoc for this type.
*
*/
public enum ReplacementResult {
Replaced,
NotReplaced,
Prevented;
}

View File

@@ -127,8 +127,7 @@ public abstract class Trigger extends TriggerReplacementBase {
private TriggerType mode;
/** The overriding ability. */
private SpellAbility overridingAbility = null;
private HashMap<String, Object> storedTriggeredObjects = null;
@@ -157,32 +156,6 @@ public abstract class Trigger extends TriggerReplacementBase {
return this.storedTriggeredObjects;
}
/** The host card. */
private Card hostCard;
/**
* <p>
* Getter for the field <code>hostCard</code>.
* </p>
*
* @return a {@link forge.Card} object.
*/
public final Card getHostCard() {
return this.hostCard;
}
/**
* <p>
* Setter for the field <code>hostCard</code>.
* </p>
*
* @param c
* a {@link forge.Card} object.
*/
public final void setHostCard(final Card c) {
this.hostCard = c;
}
/** The is intrinsic. */
private boolean isIntrinsic;
@@ -251,20 +224,6 @@ public abstract class Trigger extends TriggerReplacementBase {
}
}
/**
* <p>
* zonesCheck.
* </p>
*
* @return a boolean.
*/
public final boolean zonesCheck(PlayerZone hostCardZone) {
return !this.getHostCard().isPhasedOut()
&& (validHostZones == null || validHostZones.isEmpty()
|| (hostCardZone != null && validHostZones.contains(hostCardZone.getZoneType()))
);
}
/**
* <p>
* phasesCheck.
@@ -560,7 +519,7 @@ public abstract class Trigger extends TriggerReplacementBase {
/** The temporary. */
private boolean temporary = false;
private EnumSet<ZoneType> validHostZones;
/**
* Sets the temporary.
@@ -619,25 +578,6 @@ public abstract class Trigger extends TriggerReplacementBase {
this.runParams = runParams0;
}
/**
* Gets the overriding ability.
*
* @return the overridingAbility
*/
public SpellAbility getOverridingAbility() {
return this.overridingAbility;
}
/**
* Sets the overriding ability.
*
* @param overridingAbility0
* the overridingAbility to set
*/
public void setOverridingAbility(final SpellAbility overridingAbility0) {
this.overridingAbility = overridingAbility0;
}
/**
* Gets the id.
*
@@ -683,18 +623,13 @@ public abstract class Trigger extends TriggerReplacementBase {
copy.setID(this.getId());
copy.setMode(this.getMode());
copy.setTriggerPhases(this.validPhases);
copy.setTriggerZone(validHostZones);
copy.setActiveZone(validHostZones);
}
public boolean isStatic() {
return getMapParams().containsKey("Static"); // && params.get("Static").equals("True") [always true if present]
}
public void setTriggerZone(EnumSet<ZoneType> zones) {
validHostZones = zones;
}
public void setTriggerPhases(List<PhaseType> phases) {
validPhases = phases;
}

View File

@@ -207,7 +207,7 @@ public class TriggerHandler {
String triggerZones = mapParams.get("TriggerZones");
if (null != triggerZones) {
ret.setTriggerZone(EnumSet.copyOf(ZoneType.listValueOf(triggerZones)));
ret.setActiveZone(EnumSet.copyOf(ZoneType.listValueOf(triggerZones)));
}
String triggerPhases = mapParams.get("Phase");

View File

@@ -39,6 +39,7 @@ import forge.GameEntity;
import forge.Singletons;
import forge.card.cardfactory.CardFactoryUtil;
import forge.card.mana.ManaPool;
import forge.card.replacement.ReplacementResult;
import forge.card.spellability.SpellAbility;
import forge.card.staticability.StaticAbility;
import forge.card.trigger.TriggerType;
@@ -142,7 +143,7 @@ public abstract class Player extends GameEntity {
/** The Constant ALL_ZONES. */
public static final List<ZoneType> ALL_ZONES = Collections.unmodifiableList(Arrays.asList(ZoneType.Battlefield,
ZoneType.Library, ZoneType.Graveyard, ZoneType.Hand, ZoneType.Exile, ZoneType.Command, ZoneType.Ante));
ZoneType.Library, ZoneType.Graveyard, ZoneType.Hand, ZoneType.Exile, ZoneType.Command, ZoneType.Ante, ZoneType.Stack));
/**
* <p>
@@ -349,7 +350,7 @@ public abstract class Player extends GameEntity {
repParams.put("Event", "GainLife");
repParams.put("Affected", this);
repParams.put("LifeGained", toGain);
if (AllZone.getReplacementHandler().run(repParams)) {
if (AllZone.getReplacementHandler().run(repParams) != ReplacementResult.NotReplaced) {
return false;
}
@@ -772,7 +773,7 @@ public abstract class Player extends GameEntity {
repParams.put("DamageAmount", damage);
repParams.put("IsCombat", isCombat);
if (AllZone.getReplacementHandler().run(repParams)) {
if (AllZone.getReplacementHandler().run(repParams) != ReplacementResult.NotReplaced) {
return 0;
}
@@ -822,7 +823,7 @@ public abstract class Player extends GameEntity {
repParams.put("IsCombat", isCombat);
repParams.put("Prevention", true);
if (AllZone.getReplacementHandler().run(repParams)) {
if (AllZone.getReplacementHandler().run(repParams) != ReplacementResult.NotReplaced) {
return 0;
}
@@ -1255,7 +1256,7 @@ public abstract class Player extends GameEntity {
repRunParams.put("Event", "Draw");
repRunParams.put("Affected", this);
if (AllZone.getReplacementHandler().run(repRunParams)) {
if (AllZone.getReplacementHandler().run(repRunParams) != ReplacementResult.NotReplaced) {
return drawn;
}
@@ -1378,10 +1379,19 @@ public abstract class Player extends GameEntity {
public final CardList getCardsIn(final List<ZoneType> zones) {
final CardList result = new CardList();
for (final ZoneType z : zones) {
if(z == ZoneType.Stack) {
for(Card c : AllZone.getStackZone().getCards())
{
if(c.getOwner().equals(this)) {
result.add(c);
}
}
}
if (this.getZone(z) != null) {
result.addAll(this.getZone(z).getCards());
}
}
return result;
}
@@ -2172,7 +2182,7 @@ public abstract class Player extends GameEntity {
runParams.put("Affected", this);
runParams.put("Event", "GameLoss");
if (AllZone.getReplacementHandler().run(runParams)) {
if (AllZone.getReplacementHandler().run(runParams) != ReplacementResult.NotReplaced) {
return false;
}

View File

@@ -68,6 +68,10 @@ public class DefaultPlayerZone extends PlayerZone implements java.io.Serializabl
public void add(final Object o, boolean update) {
final Card c = (Card) o;
if(zoneName == ZoneType.Graveyard && c.getName().equals("Clone")) {
System.out.println("I'm not a freak.");
}
// Immutable cards are usually emblems,effects and the mana pool and we
// don't want to log those.