- Convert Champion keyword to Trigger

This commit is contained in:
Sol
2013-03-19 03:17:33 +00:00
parent 94c36b571a
commit ff4b20236e
5 changed files with 64 additions and 252 deletions

View File

@@ -124,7 +124,6 @@ public class Card extends GameEntity implements Comparable<Card> {
private final ArrayList<Object> rememberedObjects = new ArrayList<Object>();
private final ArrayList<Card> imprintedCards = new ArrayList<Card>();
private final ArrayList<Card> encodedCards = new ArrayList<Card>();
private Card championedCard = null;
private final List<Card> devouredCards = new ArrayList<Card>();
private Map<Player, String> flipResult = new TreeMap<Player, String>();
@@ -796,31 +795,6 @@ public class Card extends GameEntity implements Comparable<Card> {
this.flipResult.clear();
}
/**
* <p>
* Setter for the field <code>championedCard</code>.
* </p>
*
* @param c
* a {@link forge.Card} object.
* @since 1.0.15
*/
public final void setChampionedCard(final Card c) {
this.championedCard = c;
}
/**
* <p>
* Getter for the field <code>championedCard</code>.
* </p>
*
* @return a {@link forge.Card} object.
* @since 1.0.15
*/
public final Card getChampionedCard() {
return this.championedCard;
}
/**
* <p>
* addTrigger.
@@ -2321,27 +2295,6 @@ public class Card extends GameEntity implements Comparable<Card> {
} else if (keyword.startsWith("Kicker")) {
final Cost cost = new Cost(this, keywords.get(i).substring(7), false);
sbLong.append("Kicker " + cost.toSimpleString() + "\r\n");
} else if (keyword.startsWith("Champion")) {
final String k = this.getKeyword().get(i);
final String[] kk = k.split(":");
String types = kk[1];
if (kk.length > 2) {
types = kk[2];
}
if (kk[1].equals("Creature")) {
kk[1] = kk[1].toLowerCase();
}
sbLong.append("Champion a");
if (kk[1].toLowerCase().startsWith("a") || kk[1].toLowerCase().startsWith("e")
|| kk[1].toLowerCase().startsWith("i") || kk[1].toLowerCase().startsWith("o")
|| kk[1].toLowerCase().startsWith("u")) {
sbLong.append("n");
}
sbLong.append(" ").append(types);
sbLong.append(" (When this enters the battlefield, sacrifice it unless you exile another ");
sbLong.append(types);
sbLong.append(" you control. When this leaves the battlefield, ");
sbLong.append("that card returns to the battlefield.)\r\n");
} else if (keyword.endsWith(".") && !keywords.get(i).startsWith("Haunt")) {
sbLong.append(keywords.get(i).toString()).append("\r\n");
} else if (keyword.contains("At the beginning of your upkeep, ")

View File

@@ -1,6 +1,7 @@
package forge.card.ability.ai;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
@@ -27,6 +28,7 @@ import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellPermanent;
import forge.card.spellability.Target;
import forge.card.trigger.TriggerType;
import forge.game.GlobalRuleChange;
import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilBlock;
@@ -1110,6 +1112,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
final List<Card> fetched = new ArrayList<Card>();
final String remember = sa.getParam("RememberChanged");
final String forget = sa.getParam("ForgetChanged");
final boolean champion = sa.hasParam("Champion");
final String imprint = sa.getParam("Imprint");
final String totalcmc = sa.getParam("WithTotalCMC");
int totcmc = AbilityUtils.calculateAmount(card, totalcmc, sa);
@@ -1309,6 +1312,13 @@ public class ChangeZoneAi extends SpellAbilityAi {
movedCard = Singletons.getModel().getGame().getAction().moveTo(destination, c);
}
if (champion) {
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", card);
runParams.put("Championed", c);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Championed, runParams, false);
}
if (remember != null) {
card.addRemembered(movedCard);
}

View File

@@ -1,6 +1,7 @@
package forge.card.ability.effects;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.google.common.base.Predicates;
@@ -18,6 +19,7 @@ import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityStackInstance;
import forge.card.spellability.Target;
import forge.card.trigger.TriggerType;
import forge.game.ai.ComputerUtilCard;
import forge.game.player.Player;
import forge.game.zone.Zone;
@@ -622,6 +624,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
}
final String remember = sa.getParam("RememberChanged");
final boolean champion = sa.hasParam("Champion");
final String forget = sa.getParam("ForgetChanged");
final String imprint = sa.getParam("Imprint");
final String selectPrompt = sa.hasParam("SelectPrompt") ? sa.getParam("SelectPrompt") : "Select a card";
@@ -770,6 +773,13 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
}
movedCards.add(movedCard);
if (champion) {
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", card);
runParams.put("Championed", c);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Championed, runParams, false);
}
if (remember != null) {
card.addRemembered(movedCard);
}

View File

@@ -538,67 +538,6 @@ public class CardFactoryUtil {
return entersBattleFieldWithCounters(sourceCard, CounterType.TIME, power);
} // vanishing
// List<Card> choices are the only cards the user can successful select
/**
* <p>
* inputTargetChampionSac.
* </p>
*
* @param crd
* a {@link forge.Card} object.
* @param spell
* a {@link forge.card.spellability.SpellAbility} object.
* @param choices
* a {@link forge.CardList} object.
* @param message
* a {@link java.lang.String} object.
* @param targeted
* a boolean.
* @param free
* a boolean.
* @return a {@link forge.control.input.Input} object.
*/
public static Input inputTargetChampionSac(final Card crd, final SpellAbility spell, final List<Card> choices,
final String message, final boolean targeted, final boolean free) {
final Input target = new Input() {
private static final long serialVersionUID = -3320425330743678663L;
@Override
public void showMessage() {
CMatchUI.SINGLETON_INSTANCE.showMessage(message);
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
Singletons.getModel().getGame().getAction().sacrifice(crd, null);
this.stop();
}
@Override
public void selectCard(final Card card) {
if (choices.contains(card)) {
if (card == spell.getSourceCard()) {
Singletons.getModel().getGame().getAction().sacrifice(spell.getSourceCard(), null);
this.stop();
} else {
spell.getSourceCard().setChampionedCard(card);
Singletons.getModel().getGame().getAction().exile(card);
this.stop();
// Run triggers
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", spell.getSourceCard());
runParams.put("Championed", card);
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Championed, runParams, false);
}
}
} // selectCard()
};
return target;
} // inputTargetSpecific()
/**
* <p>
* masterOfTheWildHuntInputTargetCreature.
@@ -2708,6 +2647,50 @@ public class CardFactoryUtil {
shiftPos = CardFactoryUtil.hasKeyword(card, "Soulshift", n + 1);
} // Soulshift
final int championPos = CardFactoryUtil.hasKeyword(card, "Champion");
if (championPos != -1) {
String parse = card.getKeyword().get(championPos);
card.removeIntrinsicKeyword(parse);
final String[] k = parse.split(":");
final String[] valid = k[1].split(",");
String desc = k.length > 2 ? k[2] : k[1];
StringBuilder changeType = new StringBuilder();
for(String v : valid) {
if (changeType.length() != 0) {
changeType.append(",");
}
changeType.append(v).append(".YouCtrl+Other");
}
StringBuilder trig = new StringBuilder();
trig.append("Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | ");
trig.append("Execute$ ChampionAbility | TriggerDescription$ Champion a(n) ");
trig.append(desc).append(" (When this enters the battlefield, sacrifice it unless you exile another ");
trig.append(desc).append(" you control. When this leaves the battlefield, that card returns to the battlefield.)");
StringBuilder trigReturn = new StringBuilder();
trigReturn.append("Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | ");
trigReturn.append("Execute$ ChampionReturn | Secondary$ True | TriggerDescription$ When this leaves the battlefield, that card returns to the battlefield.");
StringBuilder ab = new StringBuilder();
ab.append("DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | RememberChanged$ True | Champion$ True | ");
ab.append("Hidden$ True | Optional$ True | SubAbility$ DBSacrifice | ChangeType$ ").append(changeType);
StringBuilder subAb = new StringBuilder();
subAb.append("DB$ Sacrifice | Defined$ Card.Self | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0");
String returnChampion = "DB$ ChangeZone | Defined$ Remembered | Origin$ Exile | Destination$ Battlefield";
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig.toString(), card, true);
final Trigger parsedTrigReturn = TriggerHandler.parseTrigger(trigReturn.toString(), card, true);
card.addTrigger(parsedTrigger);
card.addTrigger(parsedTrigReturn);
card.setSVar("ChampionAbility", ab.toString());
card.setSVar("ChampionReturn", returnChampion);
card.setSVar("DBSacrifice", subAb.toString());
}
final int echoPos = CardFactoryUtil.hasKeyword(card, "Echo");
if (echoPos != -1) {
// card.removeIntrinsicKeyword(parse);

View File

@@ -62,119 +62,6 @@ public class SpellPermanent extends Spell {
/** Constant <code>serialVersionUID=2413495058630644447L</code>. */
private static final long serialVersionUID = 2413495058630644447L;
private boolean willChampion = false;
private String championValid = null;
private String championValidDesc = "";
/** The champion input comes. */
private final Input championInputComes = new Input() {
private static final long serialVersionUID = -7503268232821397107L;
@Override
public void showMessage() {
final List<Card> choice = SpellPermanent.this.championGetCreature.get();
this.stopSetNext(CardFactoryUtil.inputTargetChampionSac(SpellPermanent.this.getSourceCard(),
SpellPermanent.this.championAbilityComes, choice, "Select another "
+ SpellPermanent.this.championValidDesc + " you control to exile", false, false));
ButtonUtil.disableAll(); // target this card means: sacrifice this
// card
}
};
private final Supplier<List<Card>> championGetCreature = new Supplier<List<Card>>() {
@Override
public List<Card> get() {
final List<Card> cards = SpellPermanent.this.getSourceCard().getController().getCardsIn(ZoneType.Battlefield);
return CardLists.getValidCards(cards, SpellPermanent.this.championValid, SpellPermanent.this.getSourceCard()
.getController(), SpellPermanent.this.getSourceCard());
}
}; // CommandReturn
/** The champion ability comes. */
private final SpellAbility championAbilityComes = new Ability(this.getSourceCard(), ManaCost.ZERO) {
@Override
public void resolve() {
final Card source = this.getSourceCard();
final Player controller = source.getController();
final List<Card> creature = SpellPermanent.this.championGetCreature.get();
if (creature.size() == 0) {
Singletons.getModel().getGame().getAction().sacrifice(source, null);
return;
} else if (controller.isHuman()) {
Singletons.getModel().getMatch().getInput().setInput(SpellPermanent.this.championInputComes);
} else { // Computer
List<Card> computer =
CardLists.getValidCards(controller.getCardsIn(ZoneType.Battlefield), SpellPermanent.this.championValid, controller, source);
computer.remove(source);
CardLists.shuffle(computer);
if (computer.size() != 0) {
final Card c = computer.get(0);
source.setChampionedCard(c);
if (c.isInPlay()) {
Singletons.getModel().getGame().getAction().exile(c);
}
// Run triggers
final HashMap<String, Object> runParams = new HashMap<String, Object>();
runParams.put("Card", source);
runParams.put("Championed", source.getChampionedCard());
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Championed, runParams, false);
} else {
Singletons.getModel().getGame().getAction().sacrifice(this.getSourceCard(), null);
}
} // computer
} // resolve()
};
/** The champion command comes. */
private final Command championCommandComes = new Command() {
private static final long serialVersionUID = -3580408066322945328L;
@Override
public void execute() {
final StringBuilder sb = new StringBuilder();
sb.append(SpellPermanent.this.getSourceCard()).append(
" - When CARDNAME enters the battlefield, sacrifice it unless you exile a creature you control.");
SpellPermanent.this.championAbilityComes.setStackDescription(sb.toString());
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(SpellPermanent.this.championAbilityComes);
} // execute()
}; // championCommandComes
/** The champion command leaves play. */
private final Command championCommandLeavesPlay = new Command() {
private static final long serialVersionUID = -5903638227914705191L;
@Override
public void execute() {
final SpellAbility ability = new Ability(SpellPermanent.this.getSourceCard(), ManaCost.ZERO) {
@Override
public void resolve() {
final Card c = this.getSourceCard().getChampionedCard();
if ((c != null) && !c.isToken() && Singletons.getModel().getGame().isCardExiled(c)) {
Singletons.getModel().getGame().getAction().moveToPlay(c);
}
} // resolve()
}; // SpellAbility
final StringBuilder sb = new StringBuilder();
sb.append(SpellPermanent.this.getSourceCard()).append(
" - When CARDNAME leaves the battlefield, exiled card returns to the battlefield.");
ability.setStackDescription(sb.toString());
Singletons.getModel().getGame().getStack().addSimultaneousStackEntry(ability);
} // execute()
}; // championCommandLeavesPlay
// /////
// //////////////////
/**
* <p>
* Constructor for Spell_Permanent.
@@ -219,20 +106,6 @@ public class SpellPermanent extends Spell {
public SpellPermanent(final Card sourceCard, final Cost cost, final Target tgt, final boolean setDesc) {
super(sourceCard, cost, tgt);
if (CardFactoryUtil.hasKeyword(sourceCard, "Champion") != -1) {
final int n = CardFactoryUtil.hasKeyword(sourceCard, "Champion");
final String toParse = sourceCard.getKeyword().get(n).toString();
final String[] parsed = toParse.split(":");
this.willChampion = true;
this.championValid = parsed[1];
if (parsed.length > 2) {
this.championValidDesc = parsed[2];
} else {
this.championValidDesc = this.championValid;
}
}
if (sourceCard.isCreature()) {
final StringBuilder sb = new StringBuilder();
sb.append(sourceCard.getName()).append(" - Creature ").append(sourceCard.getNetAttack());
@@ -246,13 +119,7 @@ public class SpellPermanent extends Spell {
this.setDescription(this.getStackDescription());
}
if (this.willChampion) {
sourceCard.addComesIntoPlayCommand(this.championCommandComes);
sourceCard.addLeavesPlayCommand(this.championCommandLeavesPlay);
}
if (this.getManaCost().countX() > 0) {
if (!this.getSourceCard().getSVar("X").equals("")) {
this.setSVar("X", this.getSourceCard().getSVar("X"));
}
@@ -370,17 +237,6 @@ public class SpellPermanent extends Spell {
return false;
}
if (this.willChampion) {
final Object o = this.championGetCreature.get();
if (o == null) {
return false;
}
final List<Card> cl = this.championGetCreature.get();
if (!(cl.size() > 0) || !this.getSourceCard().isInZone(ZoneType.Hand)) {
return false;
}
}
if (!SpellPermanent.checkETBEffects(card, this, null, ai)) {
return false;
}