mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 02:38:02 +00:00
Merge branch 'triggerDiscardedAll' into 'master'
TriggerDiscardAll: new trigger for Rielle, the Everwise See merge request core-developers/forge!2776
This commit is contained in:
@@ -2,6 +2,7 @@ package forge.game.ability.effects;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.game.GameActionUtil;
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.*;
|
||||
@@ -10,6 +11,7 @@ import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
import forge.game.player.PlayerPredicates;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.trigger.TriggerType;
|
||||
import forge.game.zone.ZoneType;
|
||||
|
||||
import forge.util.Lang;
|
||||
@@ -22,8 +24,8 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DiscardEffect extends SpellAbilityEffect {
|
||||
|
||||
@@ -109,7 +111,7 @@ public class DiscardEffect extends SpellAbilityEffect {
|
||||
final Game game = source.getGame();
|
||||
//final boolean anyNumber = sa.hasParam("AnyNumber");
|
||||
|
||||
final List<Card> discarded = new ArrayList<>();
|
||||
final List<Card> discarded = Lists.newArrayList();
|
||||
final List<Player> targets = getTargetPlayers(sa),
|
||||
discarders;
|
||||
Player firstTarget = null;
|
||||
@@ -127,6 +129,8 @@ public class DiscardEffect extends SpellAbilityEffect {
|
||||
|
||||
final CardZoneTable table = new CardZoneTable();
|
||||
for (final Player p : discarders) {
|
||||
boolean firstDiscard = p.getNumDiscardedThisTurn() == 0;
|
||||
final CardCollection discardedByPlayer = new CardCollection();
|
||||
if ((mode.equals("RevealTgtChoose") && firstTarget != null) || !sa.usesTargeting() || p.canBeTargetedBy(sa)) {
|
||||
if (sa.hasParam("RememberDiscarder") && p.canDiscardBy(sa)) {
|
||||
source.addRemembered(p);
|
||||
@@ -149,35 +153,28 @@ public class DiscardEffect extends SpellAbilityEffect {
|
||||
for (final Card c : toDiscard) {
|
||||
if (p.discard(c, sa, table) != null) {
|
||||
discarded.add(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasParam("RememberDiscarded")) {
|
||||
for (final Card c : discarded) {
|
||||
source.addRemembered(c);
|
||||
discardedByPlayer.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mode.equals("Hand")) {
|
||||
if (!p.canDiscardBy(sa)) {
|
||||
continue;
|
||||
}
|
||||
boolean shouldRemember = sa.hasParam("RememberDiscarded");
|
||||
CardCollectionView toDiscard = new CardCollection(Lists.newArrayList(p.getCardsIn(ZoneType.Hand)));
|
||||
CardCollectionView toDiscard = p.getCardsIn(ZoneType.Hand);
|
||||
|
||||
if (toDiscard.size() > 1) {
|
||||
toDiscard = GameActionUtil.orderCardsByTheirOwners(game, toDiscard, ZoneType.Graveyard);
|
||||
}
|
||||
|
||||
for(Card c : toDiscard) { // without copying will get concurrent modification exception
|
||||
boolean hasDiscarded = p.discard(c, sa, table) != null;
|
||||
if( hasDiscarded && shouldRemember )
|
||||
source.addRemembered(c);
|
||||
for(Card c : Lists.newArrayList(toDiscard)) { // without copying will get concurrent modification exception
|
||||
if (p.discard(c, sa, table) != null) {
|
||||
discarded.add(c);
|
||||
discardedByPlayer.add(c);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mode.equals("NotRemembered")) {
|
||||
@@ -192,6 +189,7 @@ public class DiscardEffect extends SpellAbilityEffect {
|
||||
for (final Card c : dPHand) {
|
||||
if (p.discard(c, sa, table) != null) {
|
||||
discarded.add(c);
|
||||
discardedByPlayer.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -231,6 +229,7 @@ public class DiscardEffect extends SpellAbilityEffect {
|
||||
for (Card c : toDiscardView) {
|
||||
if (p.discard(c, sa, table) != null) {
|
||||
discarded.add(c);
|
||||
discardedByPlayer.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,7 +248,10 @@ public class DiscardEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
for (Card c : toDiscard) {
|
||||
c.getController().discard(c, sa, table);
|
||||
if (c.getController().discard(c, sa, table) != null) {
|
||||
discarded.add(c);
|
||||
discardedByPlayer.add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -282,6 +284,7 @@ public class DiscardEffect extends SpellAbilityEffect {
|
||||
for (final Card c : dPChHand) {
|
||||
if (p.discard(c, sa, table) != null) {
|
||||
discarded.add(c);
|
||||
discardedByPlayer.add(c);
|
||||
}
|
||||
}
|
||||
} else if (mode.equals("RevealYouChoose") || mode.equals("RevealTgtChoose") || mode.equals("TgtChoose")) {
|
||||
@@ -332,11 +335,21 @@ public class DiscardEffect extends SpellAbilityEffect {
|
||||
if (card == null) { continue; }
|
||||
if (p.discard(card, sa, table) != null) {
|
||||
discarded.add(card);
|
||||
discardedByPlayer.add(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!discardedByPlayer.isEmpty()) {
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||
runParams.put(AbilityKey.Player, p);
|
||||
runParams.put(AbilityKey.Cards, discardedByPlayer);
|
||||
runParams.put(AbilityKey.Cause, sa);
|
||||
runParams.put(AbilityKey.FirstTime, firstDiscard);
|
||||
game.getTriggerHandler().runTrigger(TriggerType.DiscardedAll, runParams, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.hasParam("RememberDiscarded")) {
|
||||
|
||||
@@ -42,7 +42,7 @@ public class CardZoneTable extends ForwardingTable<ZoneType, ZoneType, CardColle
|
||||
old.add(value);
|
||||
} else {
|
||||
old = new CardCollection(value);
|
||||
dataMap.put(rowKey, columnKey, old);
|
||||
delegate().put(rowKey, columnKey, old);
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
@@ -6,17 +6,20 @@
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package forge.game.cost;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardCollectionView;
|
||||
@@ -24,6 +27,7 @@ import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.trigger.TriggerType;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
@@ -35,6 +39,8 @@ public class CostDiscard extends CostPartWithList {
|
||||
|
||||
// Inputs
|
||||
|
||||
protected boolean firstTime = false;
|
||||
|
||||
/**
|
||||
* Serializables need a version ID.
|
||||
*/
|
||||
@@ -42,7 +48,7 @@ public class CostDiscard extends CostPartWithList {
|
||||
|
||||
/**
|
||||
* Instantiates a new cost discard.
|
||||
*
|
||||
*
|
||||
* @param amount
|
||||
* the amount
|
||||
* @param type
|
||||
@@ -58,7 +64,7 @@ public class CostDiscard extends CostPartWithList {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see forge.card.cost.CostPart#toString()
|
||||
*/
|
||||
@Override
|
||||
@@ -98,7 +104,7 @@ public class CostDiscard extends CostPartWithList {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see
|
||||
* forge.card.cost.CostPart#canPay(forge.card.spellability.SpellAbility,
|
||||
* forge.Card, forge.Player, forge.card.cost.Cost)
|
||||
@@ -181,4 +187,23 @@ public class CostDiscard extends CostPartWithList {
|
||||
public <T> T accept(ICostVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
protected void handleBeforePayment(Player ai, SpellAbility ability, CardCollectionView targetCards) {
|
||||
firstTime = ai.getNumDiscardedThisTurn() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleChangeZoneTrigger(Player payer, SpellAbility ability, CardCollectionView targetCards) {
|
||||
super.handleChangeZoneTrigger(payer, ability, targetCards);
|
||||
|
||||
if (!targetCards.isEmpty())
|
||||
{
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||
runParams.put(AbilityKey.Player, payer);
|
||||
runParams.put(AbilityKey.Cards, new CardCollection(targetCards));
|
||||
runParams.put(AbilityKey.Cause, ability);
|
||||
runParams.put(AbilityKey.FirstTime, firstTime);
|
||||
payer.getGame().getTriggerHandler().runTrigger(TriggerType.DiscardedAll, runParams, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -45,7 +45,7 @@ public abstract class CostPartWithList extends CostPart {
|
||||
public final CardCollectionView getLKIList() {
|
||||
return lkiList;
|
||||
}
|
||||
|
||||
|
||||
public final CardCollectionView getCardList() {
|
||||
return cardList;
|
||||
}
|
||||
@@ -61,13 +61,16 @@ public abstract class CostPartWithList extends CostPart {
|
||||
|
||||
/**
|
||||
* Adds the list to hash.
|
||||
*
|
||||
*
|
||||
* @param sa
|
||||
* the sa
|
||||
* @param hash
|
||||
* the hash
|
||||
*/
|
||||
public final void reportPaidCardsTo(final SpellAbility sa) {
|
||||
if (sa == null) {
|
||||
return;
|
||||
}
|
||||
final String lkiPaymentMethod = getHashForLKIList();
|
||||
for (final Card card : lkiList) {
|
||||
sa.addCostToHashList(card, lkiPaymentMethod);
|
||||
@@ -77,18 +80,18 @@ public abstract class CostPartWithList extends CostPart {
|
||||
sa.addCostToHashList(card, cardPaymentMethod);
|
||||
}
|
||||
}
|
||||
|
||||
// public abstract List<Card> getValidCards();
|
||||
|
||||
// public abstract List<Card> getValidCards();
|
||||
|
||||
/**
|
||||
* Instantiates a new cost part with list.
|
||||
*/
|
||||
public CostPartWithList() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Instantiates a new cost part with list.
|
||||
*
|
||||
*
|
||||
* @param amount
|
||||
* the amount
|
||||
* @param type
|
||||
@@ -121,19 +124,19 @@ public abstract class CostPartWithList extends CostPart {
|
||||
}
|
||||
|
||||
// always returns true, made this to inline with return
|
||||
public boolean executePayment(SpellAbility ability, CardCollectionView targetCards) {
|
||||
protected boolean executePayment(Player payer, SpellAbility ability, CardCollectionView targetCards) {
|
||||
handleBeforePayment(payer, ability, targetCards);
|
||||
if (canPayListAtOnce()) { // This is used by reveal. Without it when opponent would reveal hand, you'll get N message boxes.
|
||||
for (Card c: targetCards) {
|
||||
lkiList.add(CardUtil.getLKICopy(c));
|
||||
}
|
||||
cardList.addAll(doListPayment(ability, targetCards));
|
||||
handleChangeZoneTrigger(ability);
|
||||
return true;
|
||||
} else {
|
||||
for (Card c: targetCards) {
|
||||
executePayment(ability, c);
|
||||
}
|
||||
}
|
||||
for (Card c: targetCards) {
|
||||
executePayment(ability, c);
|
||||
}
|
||||
handleChangeZoneTrigger(ability);
|
||||
handleChangeZoneTrigger(payer, ability, targetCards);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -154,15 +157,19 @@ public abstract class CostPartWithList extends CostPart {
|
||||
*/
|
||||
public abstract String getHashForLKIList();
|
||||
public abstract String getHashForCardList();
|
||||
|
||||
|
||||
@Override
|
||||
public boolean payAsDecided(Player ai, PaymentDecision decision, SpellAbility ability) {
|
||||
executePayment(ability, decision.cards);
|
||||
executePayment(ai, ability, decision.cards);
|
||||
reportPaidCardsTo(ability);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void handleChangeZoneTrigger(SpellAbility ability) {
|
||||
protected void handleBeforePayment(Player ai, SpellAbility ability, CardCollectionView targetCards) {
|
||||
|
||||
}
|
||||
|
||||
protected void handleChangeZoneTrigger(Player payer, SpellAbility ability, CardCollectionView targetCards) {
|
||||
if (table.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -170,7 +177,7 @@ public abstract class CostPartWithList extends CostPart {
|
||||
// copy table because the original get cleaned after the cost is done
|
||||
final CardZoneTable copyTable = new CardZoneTable();
|
||||
copyTable.putAll(table);
|
||||
copyTable.triggerChangesZoneAll(ability.getHostCard().getGame());
|
||||
copyTable.triggerChangesZoneAll(payer.getGame());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ public class CostPutCounter extends CostPartWithList {
|
||||
if (this.payCostFromSource()) {
|
||||
executePayment(ability, ability.getHostCard());
|
||||
} else {
|
||||
executePayment(ability, decision.cards);
|
||||
executePayment(ai, ability, decision.cards);
|
||||
}
|
||||
triggerCounterPutAll(ability);
|
||||
return true;
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -59,7 +59,7 @@ import java.util.*;
|
||||
* <p>
|
||||
* Phase class.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id: PhaseHandler.java 13001 2012-01-08 12:25:25Z Sloth $
|
||||
*/
|
||||
@@ -369,10 +369,23 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
|
||||
if (numDiscard > 0) {
|
||||
final CardZoneTable table = new CardZoneTable();
|
||||
final CardCollection discarded = new CardCollection();
|
||||
boolean firstDiscarded = playerTurn.getNumDiscardedThisTurn() == 0;
|
||||
for (Card c : playerTurn.getController().chooseCardsToDiscardToMaximumHandSize(numDiscard)){
|
||||
playerTurn.discard(c, null, table);
|
||||
if (playerTurn.discard(c, null, table) != null) {
|
||||
discarded.add(c);
|
||||
}
|
||||
}
|
||||
table.triggerChangesZoneAll(game);
|
||||
|
||||
if (!discarded.isEmpty()) {
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||
runParams.put(AbilityKey.Player, playerTurn);
|
||||
runParams.put(AbilityKey.Cards, discarded);
|
||||
runParams.put(AbilityKey.Cause, null);
|
||||
runParams.put(AbilityKey.FirstTime, firstDiscarded);
|
||||
game.getTriggerHandler().runTrigger(TriggerType.DiscardedAll, runParams, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Rule 514.2
|
||||
@@ -387,7 +400,6 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
game.getEndOfTurn().registerUntilEndCommand(playerTurn);
|
||||
|
||||
for (Player player : game.getPlayers()) {
|
||||
player.onCleanupPhase();
|
||||
player.getController().autoPassCancel(); // autopass won't wrap to next turn
|
||||
}
|
||||
for (Player player : game.getLostPlayers()) {
|
||||
@@ -439,7 +451,7 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
|
||||
for (Player p : game.getPlayers()) {
|
||||
int burn = p.getManaPool().clearPool(true).size();
|
||||
|
||||
|
||||
boolean manaBurns = game.getRules().hasManaBurn();
|
||||
if (manaBurns) {
|
||||
p.loseLife(burn,true);
|
||||
@@ -488,6 +500,10 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
case CLEANUP:
|
||||
bPreventCombatDamageThisTurn = false;
|
||||
if (!bRepeatCleanup) {
|
||||
// only call onCleanupPhase when Cleanup is not repeated
|
||||
for (Player player : game.getPlayers()) {
|
||||
player.onCleanupPhase();
|
||||
}
|
||||
setPlayerTurn(handleNextTurn());
|
||||
// "Trigger" for begin turn to get around a phase skipping
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||
@@ -736,7 +752,7 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
runParams.put(AbilityKey.DefendingPlayer, combat.getDefenderPlayerByAttacker(a));
|
||||
game.getTriggerHandler().runTrigger(TriggerType.AttackerBlocked, runParams, false);
|
||||
}
|
||||
|
||||
|
||||
// Run this trigger once for each blocker
|
||||
for (final Card b : blockers) {
|
||||
|
||||
@@ -836,7 +852,7 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
|
||||
if (nextPlayer.hasKeyword("Skip your next turn.")) {
|
||||
nextPlayer.removeKeyword("Skip your next turn.", false);
|
||||
if (extraTurn == null) {
|
||||
if (extraTurn == null) {
|
||||
setPlayerTurn(nextPlayer);
|
||||
}
|
||||
return getNextActivePlayer();
|
||||
@@ -861,7 +877,7 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
return getNextActivePlayer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (extraTurn != null) {
|
||||
if (extraTurn.isSkipUntap()) {
|
||||
nextPlayer.addKeyword("Skip the untap step of this turn.");
|
||||
@@ -1015,7 +1031,7 @@ public class PhaseHandler implements java.io.Serializable {
|
||||
triggerList.put(originZone.getZoneType(), currentZone.getZoneType(), saHost);
|
||||
triggerList.triggerChangesZoneAll(game);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
loopCount++;
|
||||
} while (loopCount < 999 || !pPlayerPriority.getController().isAI());
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package forge.game.trigger;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.util.Localizer;
|
||||
|
||||
public class TriggerDiscardedAll extends Trigger {
|
||||
|
||||
public TriggerDiscardedAll(Map<String, String> params, Card host, boolean intrinsic) {
|
||||
super(params, host, intrinsic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performTest(Map<AbilityKey, Object> runParams) {
|
||||
if (hasParam("ValidPlayer")) {
|
||||
if (!matchesValid(runParams.get(AbilityKey.Player), getParam("ValidPlayer").split(","),
|
||||
this.getHostCard())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasParam("ValidCause")) {
|
||||
if (runParams.get(AbilityKey.Cause) == null) {
|
||||
return false;
|
||||
}
|
||||
if (!matchesValid(runParams.get(AbilityKey.Cause), getParam("ValidCause").split(","),
|
||||
this.getHostCard())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasParam("FirstTime")) {
|
||||
if (!(boolean) runParams.get(AbilityKey.FirstTime)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTriggeringObjects(SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
||||
final CardCollection cards = (CardCollection) runParams.get(AbilityKey.Cards);
|
||||
|
||||
sa.setTriggeringObject(AbilityKey.Cards, cards);
|
||||
sa.setTriggeringObject(AbilityKey.Amount, cards.size());
|
||||
sa.setTriggeringObjectsFrom(runParams, AbilityKey.Player, AbilityKey.Cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImportantStackObjects(SpellAbility sa) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(Localizer.getInstance().getMessage("lblPlayer")).append(": ").append(sa.getTriggeringObject(AbilityKey.Player)).append(", ");
|
||||
sb.append(Localizer.getInstance().getMessage("lblAmount")).append(": ").append(sa.getTriggeringObject(AbilityKey.Amount));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -52,6 +52,7 @@ public enum TriggerType {
|
||||
Destroyed(TriggerDestroyed.class),
|
||||
Devoured(TriggerDevoured.class),
|
||||
Discarded(TriggerDiscarded.class),
|
||||
DiscardedAll(TriggerDiscardedAll.class),
|
||||
Drawn(TriggerDrawn.class),
|
||||
Evolved(TriggerEvolved.class),
|
||||
Exerted(TriggerExerted.class),
|
||||
|
||||
10
forge-gui/res/cardsfolder/upcoming/rielle_the_everwise.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/rielle_the_everwise.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Rielle, the Everwise
|
||||
ManaCost:1 U R
|
||||
Types:Legendary Creature Human Wizard
|
||||
PT:0/3
|
||||
S:Mode$ Continuous | EffectZone$ Battlefield | AddPower$ X | References$ X | Description$ CARDNAME gets +1/+0 for each instant and sorcery card in your graveyard.
|
||||
SVar:X:Count$ValidGraveyard Instant.YouOwn,Sorcery.YouOwn
|
||||
T:Mode$ DiscardedAll | FirstTime$ True | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever you discard one or more cards for the first time each turn, draw that many cards.
|
||||
SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ Y | References$ Y
|
||||
SVar:Y:TriggerCount$Amount
|
||||
Oracle:Rielle, the Everwise gets +1/+0 for each instant and sorcery card in your graveyard.\nWhenever you discard one or more cards for the first time each turn, draw that many cards.
|
||||
@@ -380,7 +380,7 @@ public class HumanPlay {
|
||||
return false;
|
||||
}
|
||||
CardCollectionView listmill = p.getCardsIn(ZoneType.Library, amount);
|
||||
((CostMill) part).executePayment(sourceAbility, listmill);
|
||||
((CostMill) part).payAsDecided(p, PaymentDecision.card(listmill), sourceAbility);
|
||||
}
|
||||
else if (part instanceof CostFlipCoin) {
|
||||
final int amount = getAmountFromPart(part, source, sourceAbility);
|
||||
@@ -488,7 +488,7 @@ public class HumanPlay {
|
||||
return false;
|
||||
}
|
||||
|
||||
costExile.executePayment(sourceAbility, p.getCardsIn(ZoneType.Graveyard));
|
||||
costExile.payAsDecided(p, PaymentDecision.card(p.getCardsIn(ZoneType.Graveyard)), sourceAbility);
|
||||
}
|
||||
else {
|
||||
from = costExile.getFrom();
|
||||
@@ -502,7 +502,7 @@ public class HumanPlay {
|
||||
return false;
|
||||
}
|
||||
list = list.subList(0, nNeeded);
|
||||
costExile.executePayment(sourceAbility, list);
|
||||
costExile.payAsDecided(p, PaymentDecision.card(list), sourceAbility);
|
||||
} else {
|
||||
// replace this with input
|
||||
CardCollection newList = new CardCollection();
|
||||
@@ -515,7 +515,7 @@ public class HumanPlay {
|
||||
list.remove(c);
|
||||
newList.add(c);
|
||||
}
|
||||
costExile.executePayment(sourceAbility, newList);
|
||||
costExile.payAsDecided(p, PaymentDecision.card(newList), sourceAbility);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -567,7 +567,7 @@ public class HumanPlay {
|
||||
}
|
||||
}
|
||||
else { // Tainted Specter, Gurzigost, etc.
|
||||
boolean hasPaid = payCostPart(controller, sourceAbility, (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblPutIntoLibrary") + orString);
|
||||
boolean hasPaid = payCostPart(controller, p, sourceAbility, (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblPutIntoLibrary") + orString);
|
||||
if (!hasPaid) {
|
||||
return false;
|
||||
}
|
||||
@@ -584,13 +584,13 @@ public class HumanPlay {
|
||||
else if (part instanceof CostGainControl) {
|
||||
int amount = Integer.parseInt(part.getAmount());
|
||||
CardCollectionView list = CardLists.getValidCards(p.getGame().getCardsIn(ZoneType.Battlefield), part.getType(), p, source);
|
||||
boolean hasPaid = payCostPart(controller, sourceAbility, (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblGainControl") + orString);
|
||||
boolean hasPaid = payCostPart(controller, p, sourceAbility, (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblGainControl") + orString);
|
||||
if (!hasPaid) { return false; }
|
||||
}
|
||||
else if (part instanceof CostReturn) {
|
||||
CardCollectionView list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source);
|
||||
int amount = getAmountFromPartX(part, source, sourceAbility);
|
||||
boolean hasPaid = payCostPart(controller, sourceAbility, (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblReturnToHand") + orString);
|
||||
boolean hasPaid = payCostPart(controller, p, sourceAbility, (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblReturnToHand") + orString);
|
||||
if (!hasPaid) { return false; }
|
||||
}
|
||||
else if (part instanceof CostDiscard) {
|
||||
@@ -599,11 +599,11 @@ public class HumanPlay {
|
||||
return false;
|
||||
}
|
||||
|
||||
((CostDiscard)part).executePayment(sourceAbility, p.getCardsIn(ZoneType.Hand));
|
||||
((CostDiscard)part).payAsDecided(p, PaymentDecision.card(p.getCardsIn(ZoneType.Hand)), sourceAbility);
|
||||
} else {
|
||||
CardCollectionView list = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), part.getType(), p, source);
|
||||
int amount = getAmountFromPartX(part, source, sourceAbility);
|
||||
boolean hasPaid = payCostPart(controller, sourceAbility, (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lbldiscard") + orString);
|
||||
boolean hasPaid = payCostPart(controller, p, sourceAbility, (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lbldiscard") + orString);
|
||||
if (!hasPaid) { return false; }
|
||||
}
|
||||
}
|
||||
@@ -611,14 +611,14 @@ public class HumanPlay {
|
||||
CostReveal costReveal = (CostReveal) part;
|
||||
CardCollectionView list = CardLists.getValidCards(p.getCardsIn(costReveal.getRevealFrom()), part.getType(), p, source);
|
||||
int amount = getAmountFromPartX(part, source, sourceAbility);
|
||||
boolean hasPaid = payCostPart(controller, sourceAbility, (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblReveal") + orString);
|
||||
boolean hasPaid = payCostPart(controller, p, sourceAbility, (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblReveal") + orString);
|
||||
if (!hasPaid) { return false; }
|
||||
}
|
||||
else if (part instanceof CostTapType) {
|
||||
CardCollectionView list = CardLists.getValidCards(p.getCardsIn(ZoneType.Battlefield), part.getType(), p, source);
|
||||
list = CardLists.filter(list, Presets.UNTAPPED);
|
||||
int amount = getAmountFromPartX(part, source, sourceAbility);
|
||||
boolean hasPaid = payCostPart(controller, sourceAbility, (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblTap") + orString);
|
||||
boolean hasPaid = payCostPart(controller, p, sourceAbility, (CostPartWithList)part, amount, list, Localizer.getInstance().getMessage("lblTap") + orString);
|
||||
if (!hasPaid) { return false; }
|
||||
}
|
||||
else if (part instanceof CostPartMana) {
|
||||
@@ -677,7 +677,7 @@ public class HumanPlay {
|
||||
return paid;
|
||||
}
|
||||
|
||||
private static boolean payCostPart(final PlayerControllerHuman controller, SpellAbility sourceAbility, CostPartWithList cpl, int amount, CardCollectionView list, String actionName) {
|
||||
private static boolean payCostPart(final PlayerControllerHuman controller, Player p, SpellAbility sourceAbility, CostPartWithList cpl, int amount, CardCollectionView list, String actionName) {
|
||||
if (list.size() < amount) { return false; } // unable to pay (not enough cards)
|
||||
|
||||
InputSelectCardsFromList inp = new InputSelectCardsFromList(controller, amount, amount, list, sourceAbility);
|
||||
@@ -689,11 +689,8 @@ public class HumanPlay {
|
||||
return false;
|
||||
}
|
||||
|
||||
cpl.executePayment(sourceAbility, new CardCollection(inp.getSelected()));
|
||||
cpl.payAsDecided(p, PaymentDecision.card(inp.getSelected()), sourceAbility);
|
||||
|
||||
if (sourceAbility != null) {
|
||||
cpl.reportPaidCardsTo(sourceAbility);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user