mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-13 01:08:06 +00:00
Merge branch '1842-panharmonicon-trigger-lingering' into 'master'
Resolve "Panharmonicon trigger lingering" Closes #1842 See merge request core-developers/forge!4708
This commit is contained in:
@@ -1880,7 +1880,7 @@ public class ComputerUtilMana {
|
|||||||
final Card offering = sa.getSacrificedAsOffering();
|
final Card offering = sa.getSacrificedAsOffering();
|
||||||
offering.setUsedToPay(false);
|
offering.setUsedToPay(false);
|
||||||
if (costIsPaid && !test) {
|
if (costIsPaid && !test) {
|
||||||
sa.getHostCard().getGame().getAction().sacrifice(offering, sa, null);
|
sa.getHostCard().getGame().getAction().sacrifice(offering, sa, null, null);
|
||||||
}
|
}
|
||||||
sa.resetSacrificedAsOffering();
|
sa.resetSacrificedAsOffering();
|
||||||
}
|
}
|
||||||
@@ -1888,7 +1888,7 @@ public class ComputerUtilMana {
|
|||||||
final Card emerge = sa.getSacrificedAsEmerge();
|
final Card emerge = sa.getSacrificedAsEmerge();
|
||||||
emerge.setUsedToPay(false);
|
emerge.setUsedToPay(false);
|
||||||
if (costIsPaid && !test) {
|
if (costIsPaid && !test) {
|
||||||
sa.getHostCard().getGame().getAction().sacrifice(emerge, sa, null);
|
sa.getHostCard().getGame().getAction().sacrifice(emerge, sa, null, null);
|
||||||
}
|
}
|
||||||
sa.resetSacrificedAsEmerge();
|
sa.resetSacrificedAsEmerge();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import forge.game.zone.ZoneType;
|
|||||||
public class DestroyAi extends SpellAbilityAi {
|
public class DestroyAi extends SpellAbilityAi {
|
||||||
@Override
|
@Override
|
||||||
public boolean chkAIDrawback(SpellAbility sa, Player ai) {
|
public boolean chkAIDrawback(SpellAbility sa, Player ai) {
|
||||||
return canPlayAI(ai, sa);
|
return checkApiLogic(ai, sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -488,7 +488,32 @@ public class PumpAi extends PumpAiBase {
|
|||||||
// each player sacrifices one permanent, e.g. Vaevictis, Asmadi the Dire - grab the worst for allied and
|
// each player sacrifices one permanent, e.g. Vaevictis, Asmadi the Dire - grab the worst for allied and
|
||||||
// the best for opponents
|
// the best for opponents
|
||||||
return SacrificeAi.doSacOneEachLogic(ai, sa);
|
return SacrificeAi.doSacOneEachLogic(ai, sa);
|
||||||
|
} else if (sa.getParam("AILogic").equals("Destroy")) {
|
||||||
|
List<Card> tgts = CardLists.getTargetableCards(game.getCardsIn(ZoneType.Battlefield), sa);
|
||||||
|
if (tgts.isEmpty()) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Card> alliedTgts = CardLists.filter(tgts, Predicates.or(CardPredicates.isControlledByAnyOf(ai.getAllies()), CardPredicates.isController(ai)));
|
||||||
|
List<Card> oppTgts = CardLists.filter(tgts, CardPredicates.isControlledByAnyOf(ai.getRegisteredOpponents()));
|
||||||
|
|
||||||
|
Card destroyTgt = null;
|
||||||
|
if (!oppTgts.isEmpty()) {
|
||||||
|
destroyTgt = ComputerUtilCard.getBestAI(oppTgts);
|
||||||
|
} else {
|
||||||
|
// TODO: somehow limit this so that the AI doesn't always destroy own stuff when able?
|
||||||
|
destroyTgt = ComputerUtilCard.getWorstAI(alliedTgts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destroyTgt != null) {
|
||||||
|
sa.resetTargets();
|
||||||
|
sa.getTargets().add(destroyTgt);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (isFight) {
|
if (isFight) {
|
||||||
return FightAi.canFightAi(ai, sa, attack, defense);
|
return FightAi.canFightAi(ai, sa, attack, defense);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,6 +197,15 @@ public class Game {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CardCollectionView copyLastStateBattlefield() {
|
||||||
|
CardCollection result = new CardCollection();
|
||||||
|
Map<Integer, Card> cachedMap = Maps.newHashMap();
|
||||||
|
for (final Player p : getPlayers()) {
|
||||||
|
result.addAll(p.getZone(ZoneType.Battlefield).getLKICopy(cachedMap));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public void updateLastStateForCard(Card c) {
|
public void updateLastStateForCard(Card c) {
|
||||||
if (c == null || c.getZone() == null) {
|
if (c == null || c.getZone() == null) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1278,7 +1278,7 @@ public class GameAction {
|
|||||||
orderedNoRegCreats = true;
|
orderedNoRegCreats = true;
|
||||||
}
|
}
|
||||||
for (Card c : noRegCreats) {
|
for (Card c : noRegCreats) {
|
||||||
sacrificeDestroy(c, null, table);
|
sacrificeDestroy(c, null, table, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (desCreats != null) {
|
if (desCreats != null) {
|
||||||
@@ -1290,7 +1290,7 @@ public class GameAction {
|
|||||||
orderedDesCreats = true;
|
orderedDesCreats = true;
|
||||||
}
|
}
|
||||||
for (Card c : desCreats) {
|
for (Card c : desCreats) {
|
||||||
destroy(c, null, true, table);
|
destroy(c, null, true, table, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setHoldCheckingStaticAbilities(false);
|
setHoldCheckingStaticAbilities(false);
|
||||||
@@ -1376,7 +1376,7 @@ public class GameAction {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!game.getStack().hasSourceOnStack(c, SpellAbilityPredicates.isChapter())) {
|
if (!game.getStack().hasSourceOnStack(c, SpellAbilityPredicates.isChapter())) {
|
||||||
sacrifice(c, null, table);
|
sacrifice(c, null, table, null);
|
||||||
checkAgain = true;
|
checkAgain = true;
|
||||||
}
|
}
|
||||||
return checkAgain;
|
return checkAgain;
|
||||||
@@ -1404,7 +1404,7 @@ public class GameAction {
|
|||||||
|
|
||||||
// cleanup aura
|
// cleanup aura
|
||||||
if (c.isAura() && c.isInPlay() && !c.isEnchanting()) {
|
if (c.isAura() && c.isInPlay() && !c.isEnchanting()) {
|
||||||
sacrificeDestroy(c, null, table);
|
sacrificeDestroy(c, null, table, null);
|
||||||
checkAgain = true;
|
checkAgain = true;
|
||||||
}
|
}
|
||||||
return checkAgain;
|
return checkAgain;
|
||||||
@@ -1556,7 +1556,7 @@ public class GameAction {
|
|||||||
|
|
||||||
for (Card c : list) {
|
for (Card c : list) {
|
||||||
if (c.getCounters(CounterEnumType.LOYALTY) <= 0) {
|
if (c.getCounters(CounterEnumType.LOYALTY) <= 0) {
|
||||||
sacrificeDestroy(c, null, table);
|
sacrificeDestroy(c, null, table, null);
|
||||||
// Play the Destroy sound
|
// Play the Destroy sound
|
||||||
game.fireEvent(new GameEventCardDestroyed());
|
game.fireEvent(new GameEventCardDestroyed());
|
||||||
recheck = true;
|
recheck = true;
|
||||||
@@ -1619,7 +1619,7 @@ public class GameAction {
|
|||||||
"You have multiple legendary permanents named \""+name+"\" in play.\n\nChoose the one to stay on battlefield (the rest will be moved to graveyard)", null);
|
"You have multiple legendary permanents named \""+name+"\" in play.\n\nChoose the one to stay on battlefield (the rest will be moved to graveyard)", null);
|
||||||
for (Card c: cc) {
|
for (Card c: cc) {
|
||||||
if (c != toKeep) {
|
if (c != toKeep) {
|
||||||
sacrificeDestroy(c, null, table);
|
sacrificeDestroy(c, null, table, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
game.fireEvent(new GameEventCardDestroyed());
|
game.fireEvent(new GameEventCardDestroyed());
|
||||||
@@ -1653,28 +1653,24 @@ public class GameAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Card c : worlds) {
|
for (Card c : worlds) {
|
||||||
sacrificeDestroy(c, null, table);
|
sacrificeDestroy(c, null, table, null);
|
||||||
game.fireEvent(new GameEventCardDestroyed());
|
game.fireEvent(new GameEventCardDestroyed());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
public final Card sacrifice(final Card c, final SpellAbility source, CardZoneTable table, Map<AbilityKey, Object> params) {
|
||||||
public final Card sacrifice(final Card c, final SpellAbility source) {
|
|
||||||
return sacrifice(c, source, null);
|
|
||||||
}
|
|
||||||
public final Card sacrifice(final Card c, final SpellAbility source, CardZoneTable table) {
|
|
||||||
if (!c.canBeSacrificedBy(source)) {
|
if (!c.canBeSacrificedBy(source)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.getController().addSacrificedThisTurn(c, source);
|
c.getController().addSacrificedThisTurn(c, source);
|
||||||
|
|
||||||
return sacrificeDestroy(c, source, table);
|
return sacrificeDestroy(c, source, table, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean destroy(final Card c, final SpellAbility sa, final boolean regenerate, CardZoneTable table) {
|
public final boolean destroy(final Card c, final SpellAbility sa, final boolean regenerate, CardZoneTable table, Map<AbilityKey, Object> params) {
|
||||||
Player activator = null;
|
Player activator = null;
|
||||||
if (!c.canBeDestroyed()) {
|
if (!c.canBeDestroyed()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1685,6 +1681,9 @@ public class GameAction {
|
|||||||
repRunParams.put(AbilityKey.Source, sa);
|
repRunParams.put(AbilityKey.Source, sa);
|
||||||
repRunParams.put(AbilityKey.Affected, c);
|
repRunParams.put(AbilityKey.Affected, c);
|
||||||
repRunParams.put(AbilityKey.Regeneration, regenerate);
|
repRunParams.put(AbilityKey.Regeneration, regenerate);
|
||||||
|
if (params != null) {
|
||||||
|
repRunParams.putAll(params);
|
||||||
|
}
|
||||||
|
|
||||||
if (game.getReplacementHandler().run(ReplacementType.Destroy, repRunParams) != ReplacementResult.NotReplaced) {
|
if (game.getReplacementHandler().run(ReplacementType.Destroy, repRunParams) != ReplacementResult.NotReplaced) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1701,11 +1700,14 @@ public class GameAction {
|
|||||||
// Run triggers
|
// Run triggers
|
||||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(c);
|
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromCard(c);
|
||||||
runParams.put(AbilityKey.Causer, activator);
|
runParams.put(AbilityKey.Causer, activator);
|
||||||
|
if (params != null) {
|
||||||
|
runParams.putAll(params);
|
||||||
|
}
|
||||||
game.getTriggerHandler().runTrigger(TriggerType.Destroyed, runParams, false);
|
game.getTriggerHandler().runTrigger(TriggerType.Destroyed, runParams, false);
|
||||||
// in case the destroyed card has such a trigger
|
// in case the destroyed card has such a trigger
|
||||||
game.getTriggerHandler().registerActiveLTBTrigger(c);
|
game.getTriggerHandler().registerActiveLTBTrigger(c);
|
||||||
|
|
||||||
final Card sacrificed = sacrificeDestroy(c, sa, table);
|
final Card sacrificed = sacrificeDestroy(c, sa, table, params);
|
||||||
return sacrificed != null;
|
return sacrificed != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1713,12 +1715,12 @@ public class GameAction {
|
|||||||
* @return the sacrificed Card in its new location, or {@code null} if the
|
* @return the sacrificed Card in its new location, or {@code null} if the
|
||||||
* sacrifice wasn't successful.
|
* sacrifice wasn't successful.
|
||||||
*/
|
*/
|
||||||
protected final Card sacrificeDestroy(final Card c, SpellAbility cause, CardZoneTable table) {
|
protected final Card sacrificeDestroy(final Card c, SpellAbility cause, CardZoneTable table, Map<AbilityKey, Object> params) {
|
||||||
if (!c.isInPlay()) {
|
if (!c.isInPlay()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Card newCard = moveToGraveyard(c, cause, null);
|
final Card newCard = moveToGraveyard(c, cause, params);
|
||||||
if (table != null && newCard != null && newCard.getZone() != null) {
|
if (table != null && newCard != null && newCard.getZone() != null) {
|
||||||
table.put(ZoneType.Battlefield, newCard.getZone().getZoneType(), newCard);
|
table.put(ZoneType.Battlefield, newCard.getZone().getZoneType(), newCard);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -638,6 +638,9 @@ public final class GameActionUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static CardCollectionView orderCardsByTheirOwners(Game game, CardCollectionView list, ZoneType dest, SpellAbility sa) {
|
public static CardCollectionView orderCardsByTheirOwners(Game game, CardCollectionView list, ZoneType dest, SpellAbility sa) {
|
||||||
|
if (list.size() <= 1) {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
CardCollection completeList = new CardCollection();
|
CardCollection completeList = new CardCollection();
|
||||||
for (Player p : game.getPlayers()) {
|
for (Player p : game.getPlayers()) {
|
||||||
CardCollection subList = new CardCollection();
|
CardCollection subList = new CardCollection();
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ public enum AbilityKey {
|
|||||||
IsCombatDamage("IsCombatDamage"),
|
IsCombatDamage("IsCombatDamage"),
|
||||||
IndividualCostPaymentInstance("IndividualCostPaymentInstance"),
|
IndividualCostPaymentInstance("IndividualCostPaymentInstance"),
|
||||||
IsMadness("IsMadness"),
|
IsMadness("IsMadness"),
|
||||||
|
LastStateBattlefield("LastStateBattlefield"),
|
||||||
LifeAmount("LifeAmount"), //TODO confirm that this and LifeGained can be merged
|
LifeAmount("LifeAmount"), //TODO confirm that this and LifeGained can be merged
|
||||||
LifeGained("LifeGained"),
|
LifeGained("LifeGained"),
|
||||||
Mana("Mana"),
|
Mana("Mana"),
|
||||||
|
|||||||
@@ -173,15 +173,13 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (defined.equals("Targeted") && sa instanceof SpellAbility) {
|
else if (defined.equals("Targeted") && sa instanceof SpellAbility) {
|
||||||
final SpellAbility saTargeting = ((SpellAbility)sa).getSATargetingCard();
|
for (TargetChoices tc : ((SpellAbility)sa).getAllTargetChoices()) {
|
||||||
if (saTargeting != null) {
|
Iterables.addAll(cards, tc.getTargetCards());
|
||||||
Iterables.addAll(cards, saTargeting.getTargets().getTargetCards());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (defined.equals("TargetedSource") && sa instanceof SpellAbility) {
|
else if (defined.equals("TargetedSource") && sa instanceof SpellAbility) {
|
||||||
final SpellAbility saTargeting = ((SpellAbility)sa).getSATargetingSA();
|
for (TargetChoices tc : ((SpellAbility)sa).getAllTargetChoices()) {
|
||||||
if (saTargeting != null) {
|
for (SpellAbility s : tc.getTargetSpells()) {
|
||||||
for (SpellAbility s : saTargeting.getTargets().getTargetSpells()) {
|
|
||||||
cards.add(s.getHostCard());
|
cards.add(s.getHostCard());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1008,9 +1006,8 @@ public class AbilityUtils {
|
|||||||
players.addAll(getDefinedPlayers(card, "TargetedController", sa));
|
players.addAll(getDefinedPlayers(card, "TargetedController", sa));
|
||||||
}
|
}
|
||||||
else if ((defined.equals("Targeted") || defined.equals("TargetedPlayer")) && sa instanceof SpellAbility) {
|
else if ((defined.equals("Targeted") || defined.equals("TargetedPlayer")) && sa instanceof SpellAbility) {
|
||||||
final SpellAbility saTargeting = ((SpellAbility)sa).getSATargetingPlayer();
|
for (TargetChoices tc : ((SpellAbility)sa).getAllTargetChoices()) {
|
||||||
if (saTargeting != null) {
|
players.addAll(tc.getTargetPlayers());
|
||||||
players.addAll(saTargeting.getTargets().getTargetPlayers());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (defined.equals("ParentTarget") && sa instanceof SpellAbility) {
|
else if (defined.equals("ParentTarget") && sa instanceof SpellAbility) {
|
||||||
@@ -1298,9 +1295,8 @@ public class AbilityUtils {
|
|||||||
s = ((SpellAbility)sa).getRootAbility();
|
s = ((SpellAbility)sa).getRootAbility();
|
||||||
}
|
}
|
||||||
else if (defined.equals("Targeted") && sa instanceof SpellAbility) {
|
else if (defined.equals("Targeted") && sa instanceof SpellAbility) {
|
||||||
final SpellAbility saTargeting = ((SpellAbility)sa).getSATargetingSA();
|
for (TargetChoices tc : ((SpellAbility)sa).getAllTargetChoices()) {
|
||||||
if (saTargeting != null) {
|
for (SpellAbility targetSpell : tc.getTargetSpells()) {
|
||||||
for (SpellAbility targetSpell : saTargeting.getTargets().getTargetSpells()) {
|
|
||||||
SpellAbilityStackInstance stackInstance = game.getStack().getInstanceFromSpellAbility(targetSpell);
|
SpellAbilityStackInstance stackInstance = game.getStack().getInstanceFromSpellAbility(targetSpell);
|
||||||
if (stackInstance != null) {
|
if (stackInstance != null) {
|
||||||
SpellAbility instanceSA = stackInstance.getSpellAbility(true);
|
SpellAbility instanceSA = stackInstance.getSpellAbility(true);
|
||||||
@@ -1412,7 +1408,6 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbilityUtils.resolveApiAbility(sa, game);
|
AbilityUtils.resolveApiAbility(sa, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import java.util.Map;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardCollection;
|
import forge.game.card.CardCollection;
|
||||||
@@ -47,6 +48,7 @@ public class BalanceEffect extends SpellAbilityEffect {
|
|||||||
min = Math.min(min, validCards.get(i).size());
|
min = Math.min(min, validCards.get(i).size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<AbilityKey, Object> params = AbilityKey.newMap();
|
||||||
CardZoneTable table = new CardZoneTable();
|
CardZoneTable table = new CardZoneTable();
|
||||||
for (int i = 0; i < players.size(); i++) {
|
for (int i = 0; i < players.size(); i++) {
|
||||||
Player p = players.get(i);
|
Player p = players.get(i);
|
||||||
@@ -59,7 +61,7 @@ public class BalanceEffect extends SpellAbilityEffect {
|
|||||||
} else { // Battlefield
|
} else { // Battlefield
|
||||||
for (Card card : p.getController().choosePermanentsToSacrifice(sa, numToBalance, numToBalance, validCards.get(i), valid)) {
|
for (Card card : p.getController().choosePermanentsToSacrifice(sa, numToBalance, numToBalance, validCards.get(i), valid)) {
|
||||||
if ( null == card ) continue;
|
if ( null == card ) continue;
|
||||||
game.getAction().sacrifice(card, sa, table);
|
game.getAction().sacrifice(card, sa, table, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import forge.game.ability.AbilityKey;
|
|||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardFactoryUtil;
|
import forge.game.card.CardFactoryUtil;
|
||||||
|
import forge.game.card.CardZoneTable;
|
||||||
import forge.game.replacement.ReplacementResult;
|
import forge.game.replacement.ReplacementResult;
|
||||||
import forge.game.replacement.ReplacementType;
|
import forge.game.replacement.ReplacementType;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
@@ -113,6 +114,8 @@ public class CounterEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<AbilityKey, Object> params = AbilityKey.newMap();
|
||||||
|
CardZoneTable table = new CardZoneTable();
|
||||||
for (final SpellAbility tgtSA : sas) {
|
for (final SpellAbility tgtSA : sas) {
|
||||||
final Card tgtSACard = tgtSA.getHostCard();
|
final Card tgtSACard = tgtSA.getHostCard();
|
||||||
// should remember even that spell cannot be countered, e.g. Dovescape
|
// should remember even that spell cannot be countered, e.g. Dovescape
|
||||||
@@ -137,7 +140,7 @@ public class CounterEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
// Destroy Permanent may be able to be turned into a SubAbility
|
// Destroy Permanent may be able to be turned into a SubAbility
|
||||||
if (tgtSA.isAbility() && sa.hasParam("DestroyPermanent")) {
|
if (tgtSA.isAbility() && sa.hasParam("DestroyPermanent")) {
|
||||||
game.getAction().destroy(tgtSACard, sa, true, null);
|
game.getAction().destroy(tgtSACard, sa, true, table, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.hasParam("RememberCountered")) {
|
if (sa.hasParam("RememberCountered")) {
|
||||||
@@ -152,6 +155,7 @@ public class CounterEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
table.triggerChangesZoneAll(game, sa);
|
||||||
} // end counterResolve
|
} // end counterResolve
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.google.common.collect.Maps;
|
|||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameActionUtil;
|
import forge.game.GameActionUtil;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
@@ -90,10 +91,12 @@ public class DestroyAllEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CardZoneTable table = new CardZoneTable();
|
CardZoneTable table = new CardZoneTable();
|
||||||
|
Map<AbilityKey, Object> params = AbilityKey.newMap();
|
||||||
|
params.put(AbilityKey.LastStateBattlefield, game.copyLastStateBattlefield());
|
||||||
|
|
||||||
Map<Integer, Card> cachedMap = Maps.newHashMap();
|
Map<Integer, Card> cachedMap = Maps.newHashMap();
|
||||||
for (Card c : list) {
|
for (Card c : list) {
|
||||||
if (game.getAction().destroy(c, sa, !noRegen, table) && remDestroyed) {
|
if (game.getAction().destroy(c, sa, !noRegen, table, params) && remDestroyed) {
|
||||||
card.addRemembered(CardUtil.getLKICopy(c, cachedMap));
|
card.addRemembered(CardUtil.getLKICopy(c, cachedMap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ import com.google.common.collect.Maps;
|
|||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameActionUtil;
|
import forge.game.GameActionUtil;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardCollection;
|
import forge.game.card.CardCollectionView;
|
||||||
import forge.game.card.CardUtil;
|
import forge.game.card.CardUtil;
|
||||||
import forge.game.card.CardZoneTable;
|
import forge.game.card.CardZoneTable;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
@@ -72,13 +73,16 @@ public class DestroyEffect extends SpellAbilityEffect {
|
|||||||
card.clearRemembered();
|
card.clearRemembered();
|
||||||
}
|
}
|
||||||
|
|
||||||
CardCollection tgtCards = getTargetCards(sa);
|
CardCollectionView tgtCards = getTargetCards(sa);
|
||||||
CardCollection untargetedCards = CardUtil.getRadiance(sa);
|
CardCollectionView untargetedCards = CardUtil.getRadiance(sa);
|
||||||
|
|
||||||
if (tgtCards.size() > 1) {
|
if (tgtCards.size() > 1) {
|
||||||
tgtCards = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, tgtCards, ZoneType.Graveyard, sa);
|
tgtCards = GameActionUtil.orderCardsByTheirOwners(game, tgtCards, ZoneType.Graveyard, sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<AbilityKey, Object> params = AbilityKey.newMap();
|
||||||
|
params.put(AbilityKey.LastStateBattlefield, game.copyLastStateBattlefield());
|
||||||
|
|
||||||
CardZoneTable table = new CardZoneTable();
|
CardZoneTable table = new CardZoneTable();
|
||||||
Map<Integer, Card> cachedMap = Maps.newHashMap();
|
Map<Integer, Card> cachedMap = Maps.newHashMap();
|
||||||
for (final Card tgtC : tgtCards) {
|
for (final Card tgtC : tgtCards) {
|
||||||
@@ -90,24 +94,24 @@ public class DestroyEffect extends SpellAbilityEffect {
|
|||||||
if (gameCard == null || !tgtC.equalsWithTimestamp(gameCard)) {
|
if (gameCard == null || !tgtC.equalsWithTimestamp(gameCard)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
internalDestroy(gameCard, sa, table, cachedMap);
|
internalDestroy(gameCard, sa, table, cachedMap, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (untargetedCards.size() > 1) {
|
if (untargetedCards.size() > 1) {
|
||||||
untargetedCards = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, untargetedCards, ZoneType.Graveyard, sa);
|
untargetedCards = GameActionUtil.orderCardsByTheirOwners(game, untargetedCards, ZoneType.Graveyard, sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final Card unTgtC : untargetedCards) {
|
for (final Card unTgtC : untargetedCards) {
|
||||||
if (unTgtC.isInPlay()) {
|
if (unTgtC.isInPlay()) {
|
||||||
internalDestroy(unTgtC, sa, table, cachedMap);
|
internalDestroy(unTgtC, sa, table, cachedMap, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
table.triggerChangesZoneAll(game, sa);
|
table.triggerChangesZoneAll(game, sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void internalDestroy(Card gameCard, SpellAbility sa, CardZoneTable table, Map<Integer, Card> cachedMap) {
|
protected void internalDestroy(Card gameCard, SpellAbility sa, CardZoneTable table, Map<Integer, Card> cachedMap, Map<AbilityKey, Object> params) {
|
||||||
final Card card = sa.getHostCard();
|
final Card card = sa.getHostCard();
|
||||||
final Game game = card.getGame();
|
final Game game = card.getGame();
|
||||||
|
|
||||||
@@ -122,9 +126,9 @@ public class DestroyEffect extends SpellAbilityEffect {
|
|||||||
card.addRemembered(gameCard.getAttachedCards());
|
card.addRemembered(gameCard.getAttachedCards());
|
||||||
}
|
}
|
||||||
if (sac) {
|
if (sac) {
|
||||||
destroyed = game.getAction().sacrifice(gameCard, sa, table) != null;
|
destroyed = game.getAction().sacrifice(gameCard, sa, table, params) != null;
|
||||||
} else {
|
} else {
|
||||||
destroyed = game.getAction().destroy(gameCard, sa, !noRegen, table);
|
destroyed = game.getAction().destroy(gameCard, sa, !noRegen, table, params);
|
||||||
}
|
}
|
||||||
if (destroyed && remDestroyed) {
|
if (destroyed && remDestroyed) {
|
||||||
card.addRemembered(gameCard);
|
card.addRemembered(gameCard);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.google.common.collect.Maps;
|
|||||||
|
|
||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.GameActionUtil;
|
import forge.game.GameActionUtil;
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
@@ -86,9 +87,12 @@ public class SacrificeAllEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
CardZoneTable table = new CardZoneTable();
|
CardZoneTable table = new CardZoneTable();
|
||||||
Map<Integer, Card> cachedMap = Maps.newHashMap();
|
Map<Integer, Card> cachedMap = Maps.newHashMap();
|
||||||
|
Map<AbilityKey, Object> params = AbilityKey.newMap();
|
||||||
|
params.put(AbilityKey.LastStateBattlefield, game.copyLastStateBattlefield());
|
||||||
|
|
||||||
for (Card sac : list) {
|
for (Card sac : list) {
|
||||||
final Card lKICopy = CardUtil.getLKICopy(sac, cachedMap);
|
final Card lKICopy = CardUtil.getLKICopy(sac, cachedMap);
|
||||||
if (game.getAction().sacrifice(sac, sa, table) != null) {
|
if (game.getAction().sacrifice(sac, sa, table, params) != null) {
|
||||||
if (remSacrificed) {
|
if (remSacrificed) {
|
||||||
card.addRemembered(lKICopy);
|
card.addRemembered(lKICopy);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,10 +106,12 @@ public class SacrificeEffect extends SpellAbilityEffect {
|
|||||||
final String remSVar = sa.getParam("RememberSacrificedSVar");
|
final String remSVar = sa.getParam("RememberSacrificedSVar");
|
||||||
int countSacrificed = 0;
|
int countSacrificed = 0;
|
||||||
CardZoneTable table = new CardZoneTable();
|
CardZoneTable table = new CardZoneTable();
|
||||||
|
Map<AbilityKey, Object> params = AbilityKey.newMap();
|
||||||
|
params.put(AbilityKey.LastStateBattlefield, game.copyLastStateBattlefield());
|
||||||
|
|
||||||
if (valid.equals("Self") && game.getZoneOf(card) != null) {
|
if (valid.equals("Self") && game.getZoneOf(card) != null) {
|
||||||
if (game.getZoneOf(card).is(ZoneType.Battlefield)) {
|
if (game.getZoneOf(card).is(ZoneType.Battlefield)) {
|
||||||
if (game.getAction().sacrifice(card, sa, table) != null) {
|
if (game.getAction().sacrifice(card, sa, table, params) != null) {
|
||||||
countSacrificed++;
|
countSacrificed++;
|
||||||
if (remSacrificed) {
|
if (remSacrificed) {
|
||||||
card.addRemembered(card);
|
card.addRemembered(card);
|
||||||
@@ -152,8 +154,8 @@ public class SacrificeEffect extends SpellAbilityEffect {
|
|||||||
Map<Integer, Card> cachedMap = Maps.newHashMap();
|
Map<Integer, Card> cachedMap = Maps.newHashMap();
|
||||||
for (Card sac : choosenToSacrifice) {
|
for (Card sac : choosenToSacrifice) {
|
||||||
final Card lKICopy = CardUtil.getLKICopy(sac, cachedMap);
|
final Card lKICopy = CardUtil.getLKICopy(sac, cachedMap);
|
||||||
boolean wasSacrificed = !destroy && game.getAction().sacrifice(sac, sa, table) != null;
|
boolean wasSacrificed = !destroy && game.getAction().sacrifice(sac, sa, table, params) != null;
|
||||||
boolean wasDestroyed = destroy && game.getAction().destroy(sac, sa, true, table);
|
boolean wasDestroyed = destroy && game.getAction().destroy(sac, sa, true, table, params);
|
||||||
// Run Devour Trigger
|
// Run Devour Trigger
|
||||||
if (devour) {
|
if (devour) {
|
||||||
card.addDevoured(lKICopy);
|
card.addDevoured(lKICopy);
|
||||||
|
|||||||
@@ -519,28 +519,6 @@ public class CardFactoryUtil {
|
|||||||
return types.size();
|
return types.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getNeededXDamage.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param ability
|
|
||||||
* a {@link forge.game.spellability.SpellAbility} object.
|
|
||||||
* @return a int.
|
|
||||||
*/
|
|
||||||
public static int getNeededXDamage(final SpellAbility ability) {
|
|
||||||
// when targeting a creature, make sure the AI won't overkill on X
|
|
||||||
// damage
|
|
||||||
final Card target = ability.getTargetCard();
|
|
||||||
int neededDamage = -1;
|
|
||||||
|
|
||||||
if ((target != null)) {
|
|
||||||
neededDamage = target.getNetToughness() - target.getDamage();
|
|
||||||
}
|
|
||||||
|
|
||||||
return neededDamage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the ability factory abilities.
|
* Adds the ability factory abilities.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ public class CostSacrifice extends CostPartWithList {
|
|||||||
@Override
|
@Override
|
||||||
protected Card doPayment(SpellAbility ability, Card targetCard) {
|
protected Card doPayment(SpellAbility ability, Card targetCard) {
|
||||||
// no table there, it is already handled by CostPartWithList
|
// no table there, it is already handled by CostPartWithList
|
||||||
return targetCard.getGame().getAction().sacrifice(targetCard, ability, null);
|
return targetCard.getGame().getAction().sacrifice(targetCard, ability, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import forge.game.Game;
|
import forge.game.Game;
|
||||||
import forge.game.ability.AbilityKey;
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardCollectionView;
|
||||||
import forge.game.card.CardZoneTable;
|
import forge.game.card.CardZoneTable;
|
||||||
|
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
@@ -22,8 +23,17 @@ public class StaticAbilityPanharmonicon {
|
|||||||
public static int handlePanharmonicon(final Game game, final Trigger t, final Map<AbilityKey, Object> runParams) {
|
public static int handlePanharmonicon(final Game game, final Trigger t, final Map<AbilityKey, Object> runParams) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
|
CardCollectionView cardList = null;
|
||||||
|
// currently only used for leave the battlefield trigger
|
||||||
|
if (runParams.containsKey(AbilityKey.LastStateBattlefield)) {
|
||||||
|
cardList = (CardCollectionView) runParams.get(AbilityKey.LastStateBattlefield);
|
||||||
|
}
|
||||||
|
if (cardList == null) {
|
||||||
|
cardList = t.getMode() == TriggerType.ChangesZone && "Battlefield".equals(t.getParam("Origin")) ? game.getLastStateBattlefield() : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES);
|
||||||
|
}
|
||||||
|
|
||||||
// Checks only the battlefield, as those effects only work from there
|
// Checks only the battlefield, as those effects only work from there
|
||||||
for (final Card ca : t.getMode() == TriggerType.ChangesZone ? game.getLastStateBattlefield() : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) {
|
for (final Card ca : cardList) {
|
||||||
for (final StaticAbility stAb : ca.getStaticAbilities()) {
|
for (final StaticAbility stAb : ca.getStaticAbilities()) {
|
||||||
if (!stAb.getParam("Mode").equals(MODE) || stAb.isSuppressed() || !stAb.checkConditions()) {
|
if (!stAb.getParam("Mode").equals(MODE) || stAb.isSuppressed() || !stAb.checkConditions()) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ Name:Boom
|
|||||||
ManaCost:1 R
|
ManaCost:1 R
|
||||||
AlternateMode: Split
|
AlternateMode: Split
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Destroy | Cost$ 1 R | TgtPrompt$ Choose target land you control to destroy | ValidTgts$ Land.YouCtrl | SubAbility$ DestroyOpp | SpellDescription$ Destroy target land you control and target land you don't control.
|
A:SP$ Pump | Cost$ 1 R | TgtPrompt$ Choose target land you control to destroy | ValidTgts$ Land.YouCtrl | AILogic$ Destroy | Curse$ True | SubAbility$ DestroyOpp | SpellDescription$ Destroy target land you control and target land you don't control.
|
||||||
SVar:DestroyOpp:DB$ Destroy | TgtPrompt$ Choose target land you don't control to destroy | ValidTgts$ Land.YouDontCtrl
|
SVar:DestroyOpp:DB$ Pump | TgtPrompt$ Choose target land you don't control to destroy | ValidTgts$ Land.YouDontCtrl | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroy
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/boombust.jpg
|
SVar:DBDestroy:DB$ Destroy | Defined$ Targeted
|
||||||
Oracle:Destroy target land you control and target land you don't control.
|
Oracle:Destroy target land you control and target land you don't control.
|
||||||
|
|
||||||
ALTERNATE
|
ALTERNATE
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
Name:Decimate
|
Name:Decimate
|
||||||
ManaCost:2 R G
|
ManaCost:2 R G
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Destroy | Cost$ 2 R G | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | SubAbility$ DestroyCreature | SpellDescription$ Destroy target artifact, target creature, target enchantment, and target land.
|
A:SP$ Pump | Cost$ 2 R G | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | SubAbility$ DestroyCreature | AILogic$ Destroy | Curse$ True | SpellDescription$ Destroy target artifact, target creature, target enchantment, and target land.
|
||||||
SVar:DestroyCreature:DB$ Destroy | ValidTgts$ Creature | SubAbility$ DestroyEnch | TgtPrompt$ Select target creature
|
SVar:DestroyCreature:DB$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | AILogic$ Destroy | Curse$ True | SubAbility$ DestroyEnch
|
||||||
SVar:DestroyEnch:DB$ Destroy | ValidTgts$ Enchantment | SubAbility$ DestroyLand | TgtPrompt$ Select target enchantment
|
SVar:DestroyEnch:DB$ Pump | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment | AILogic$ Destroy | Curse$ True | SubAbility$ DestroyLand
|
||||||
SVar:DestroyLand:DB$ Destroy | ValidTgts$ Land | TgtPrompt$ Select target land
|
SVar:DestroyLand:DB$ Pump | ValidTgts$ Land | TgtPrompt$ Select target land | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroy
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/decimate.jpg
|
SVar:DBDestroy:DB$ Destroy | Defined$ Targeted
|
||||||
Oracle:Destroy target artifact, target creature, target enchantment, and target land.
|
Oracle:Destroy target artifact, target creature, target enchantment, and target land.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Fumarole
|
Name:Fumarole
|
||||||
ManaCost:3 B R
|
ManaCost:3 B R
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Destroy | Cost$ 3 B R PayLife<3> | ValidTgts$ Creature | TgtPrompt$ Select target creature | SubAbility$ DBDestroy | SpellDescription$ Destroy target creature and target land.
|
A:SP$ Pump | Cost$ 3 B R PayLife<3> | ValidTgts$ Creature | TgtPrompt$ Select target creature | AILogic$ Destroy | Curse$ True | SubAbility$ DBLand | SpellDescription$ Destroy target creature and target land.
|
||||||
SVar:DBDestroy:DB$ Destroy | ValidTgts$ Land | TgtPrompt$ Select target land
|
SVar:DBLand:DB$ Destroy | ValidTgts$ Land | TgtPrompt$ Select target land | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroy
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/fumarole.jpg
|
SVar:DBDestroy:DB$ Destroy | Defined$ Targeted
|
||||||
Oracle:As an additional cost to cast this spell, pay 3 life.\nDestroy target creature and target land.
|
Oracle:As an additional cost to cast this spell, pay 3 life.\nDestroy target creature and target land.
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ ManaCost:3 R
|
|||||||
Types:Creature Goblin
|
Types:Creature Goblin
|
||||||
PT:2/2
|
PT:2/2
|
||||||
T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDestroyCreature | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may sacrifice it. If you do, destroy target creature and target land.
|
T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDestroyCreature | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may sacrifice it. If you do, destroy target creature and target land.
|
||||||
SVar:TrigDestroyCreature:AB$ Destroy | Cost$ Sac<1/CARDNAME> | ValidTgts$ Creature | TgtPrompt$ Select target creature | SubAbility$ DBDestroyLand
|
SVar:TrigDestroyCreature:AB$ Pump | Cost$ Sac<1/CARDNAME> | ValidTgts$ Creature | TgtPrompt$ Select target creature | AILogic$ Destroy | Curse$ True | SubAbility$ DBLand
|
||||||
SVar:DBDestroyLand:DB$ Destroy | ValidTgts$ Land | TgtPrompt$ Select target land
|
SVar:DBLand:DB$ Pump | ValidTgts$ Land | TgtPrompt$ Select target land | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroy
|
||||||
|
SVar:DBDestroy:DB$ Destroy | Defined$ Targeted
|
||||||
Oracle:Whenever Goblin Grenadiers attacks and isn't blocked, you may sacrifice it. If you do, destroy target creature and target land.
|
Oracle:Whenever Goblin Grenadiers attacks and isn't blocked, you may sacrifice it. If you do, destroy target creature and target land.
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ Types:Sorcery
|
|||||||
A:SP$ Charm | Cost$ R G | Choices$ DBDestroy1,DBDestroy2,DBDestroy3 | CharmNum$ 1
|
A:SP$ Charm | Cost$ R G | Choices$ DBDestroy1,DBDestroy2,DBDestroy3 | CharmNum$ 1
|
||||||
SVar:DBDestroy1:DB$ Destroy | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | SpellDescription$ Destroy target artifact.
|
SVar:DBDestroy1:DB$ Destroy | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | SpellDescription$ Destroy target artifact.
|
||||||
SVar:DBDestroy2:DB$ Destroy | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment | SpellDescription$ Destroy target enchantment.
|
SVar:DBDestroy2:DB$ Destroy | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment | SpellDescription$ Destroy target enchantment.
|
||||||
SVar:DBDestroy3:DB$ Destroy | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | SpellDescription$ Destroy target artifact and target enchantment. | SubAbility$ DestroyEnch
|
SVar:DBDestroy3:DB$ Pump | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | AILogic$ Destroy | Curse$ True | SubAbility$ DestroyEnch | SpellDescription$ Destroy target artifact and target enchantment.
|
||||||
SVar:DestroyEnch:DB$ Destroy | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment
|
SVar:DestroyEnch:DB$ Pump | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroy
|
||||||
|
SVar:DBDestroy:DB$ Destroy | Defined$ Targeted
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/hull_breach.jpg
|
|
||||||
Oracle:Choose one —\n• Destroy target artifact.\n• Destroy target enchantment.\n• Destroy target artifact and target enchantment.
|
Oracle:Choose one —\n• Destroy target artifact.\n• Destroy target enchantment.\n• Destroy target artifact and target enchantment.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Plague Spores
|
Name:Plague Spores
|
||||||
ManaCost:4 B R
|
ManaCost:4 B R
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Destroy | Cost$ 4 B R | ValidTgts$ Creature.nonBlack | TgtPrompt$ Select nonblack creature | NoRegen$ True | SubAbility$ DestroyLand | SpellDescription$ Destroy target nonblack creature and target land. They can't be regenerated.
|
A:SP$ Pump | Cost$ 4 B R | ValidTgts$ Creature.nonBlack | TgtPrompt$ Select nonblack creature | AILogic$ Destroy | Curse$ True | SubAbility$ DBLand | SpellDescription$ Destroy target nonblack creature and target land. They can't be regenerated.
|
||||||
SVar:DestroyLand:DB$ Destroy | ValidTgts$ Land | NoRegen$ True | TgtPrompt$ Select target land
|
SVar:DBLand:DB$ Pump | ValidTgts$ Land | TgtPrompt$ Select target land | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroy
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/plague_spores.jpg
|
SVar:DBDestroy:DB$ Destroy | Defined$ Targeted | NoRegen$ True
|
||||||
Oracle:Destroy target nonblack creature and target land. They can't be regenerated.
|
Oracle:Destroy target nonblack creature and target land. They can't be regenerated.
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ Name:Reign of Chaos
|
|||||||
ManaCost:2 R R
|
ManaCost:2 R R
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Charm | Cost$ 2 R R | Choices$ DBDestroy1,DBDestroy2 | CharmNum$ 1
|
A:SP$ Charm | Cost$ 2 R R | Choices$ DBDestroy1,DBDestroy2 | CharmNum$ 1
|
||||||
SVar:DBDestroy1:DB$ Destroy | ValidTgts$ Plains | TgtPrompt$ Select target Plains | SubAbility$ DBDestroyWhite | SpellDescription$ Destroy target Plains and target white creature.
|
SVar:DBDestroy1:DB$ Pump | ValidTgts$ Plains | TgtPrompt$ Select target Plains | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroyWhite | SpellDescription$ Destroy target Plains and target white creature.
|
||||||
SVar:DBDestroy2:DB$ Destroy | ValidTgts$ Island | TgtPrompt$ Select target Island | SubAbility$ DBDestroyBlue | SpellDescription$ Destroy target Island and target blue creature.
|
SVar:DBDestroy2:DB$ Pump | ValidTgts$ Island | TgtPrompt$ Select target Island | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroyBlue | SpellDescription$ Destroy target Island and target blue creature.
|
||||||
SVar:DBDestroyWhite:DB$ Destroy | ValidTgts$ Creature.White | TgtPrompt$ Select target white creature
|
SVar:DBDestroyWhite:DB$ Pump | ValidTgts$ Creature.White | TgtPrompt$ Select target white creature | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroy
|
||||||
SVar:DBDestroyBlue:DB$ Destroy | ValidTgts$ Creature.Blue | TgtPrompt$ Select target blue creature
|
SVar:DBDestroyBlue:DB$ Pump | ValidTgts$ Creature.Blue | TgtPrompt$ Select target blue creature | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroy
|
||||||
|
SVar:DBDestroy:DB$ Destroy | Defined$ Targeted
|
||||||
AI:RemoveDeck:Random
|
AI:RemoveDeck:Random
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/reign_of_chaos.jpg
|
|
||||||
Oracle:Choose one —\n• Destroy target Plains and target white creature.\n• Destroy target Island and target blue creature.
|
Oracle:Choose one —\n• Destroy target Plains and target white creature.\n• Destroy target Island and target blue creature.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Spiteful Blow
|
Name:Spiteful Blow
|
||||||
ManaCost:4 B B
|
ManaCost:4 B B
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Destroy | Cost$ 4 B B | ValidTgts$ Creature | TgtPrompt$ Select target creature | SubAbility$ DBDestroy | SpellDescription$ Destroy target creature and target land.
|
A:SP$ Pump | Cost$ 4 B B | ValidTgts$ Creature | TgtPrompt$ Select target creature | SubAbility$ DBLand | AILogic$ Destroy | Curse$ True | SpellDescription$ Destroy target creature and target land.
|
||||||
SVar:DBDestroy:DB$ Destroy | ValidTgts$ Land | TgtPrompt$ Select target land
|
SVar:DBLand:DB$ Pump | ValidTgts$ Land | TgtPrompt$ Select target land | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroy
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/spiteful_blow.jpg
|
SVar:DBDestroy:DB$ Destroy | Defined$ Targeted
|
||||||
Oracle:Destroy target creature and target land.
|
Oracle:Destroy target creature and target land.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
Name:Stomp and Howl
|
Name:Stomp and Howl
|
||||||
ManaCost:2 G
|
ManaCost:2 G
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Destroy | Cost$ 2 G | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | SpellDescription$ Destroy target artifact and target enchantment. | SubAbility$ DestroyEnch
|
A:SP$ Pump | Cost$ 2 G | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | AILogic$ Destroy | Curse$ True | SubAbility$ DestroyEnch | SpellDescription$ Destroy target artifact and target enchantment.
|
||||||
SVar:DestroyEnch:DB$ Destroy | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment
|
SVar:DestroyEnch:DB$ Pump | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroy
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/stomp_and_howl.jpg
|
SVar:DBDestroy:DB$ Destroy | Defined$ Targeted
|
||||||
Oracle:Destroy target artifact and target enchantment.
|
Oracle:Destroy target artifact and target enchantment.
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
Name:Volcanic Offering
|
Name:Volcanic Offering
|
||||||
ManaCost:4 R
|
ManaCost:4 R
|
||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ Destroy | Cost$ 4 R | ValidTgts$ Land.nonBasic+YouDontCtrl | TgtPrompt$ Select target nonbasic land you don't control | SubAbility$ DBDestroyLand | SpellDescription$ Destroy target nonbasic land you don't control and target nonbasic land of an opponent's choice you don't control.
|
A:SP$ Pump | Cost$ 4 R | ValidTgts$ Land.nonBasic+YouDontCtrl | TgtPrompt$ Select target nonbasic land you don't control | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroyLand | SpellDescription$ Destroy target nonbasic land you don't control and target nonbasic land of an opponent's choice you don't control.
|
||||||
SVar:DBDestroyLand:DB$ Destroy | TargetingPlayer$ Player.Opponent | ValidTgts$ Land.nonBasic+YouDontCtrl | TgtPrompt$ Select target nonbasic land the caster of this spell don't control | SubAbility$ DBDamage
|
SVar:DBDestroyLand:DB$ Pump | TargetingPlayer$ Player.Opponent | ValidTgts$ Land.nonBasic+YouDontCtrl | TgtPrompt$ Select target nonbasic land the caster of this spell don't control | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroy
|
||||||
|
SVar:DBDestroy:DB$ Destroy | Defined$ Targeted | SubAbility$ DBDamage
|
||||||
SVar:DBDamage:DB$ DealDamage | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature you don't control | NumDmg$ 7 | SubAbility$ DBDamage2 | SpellDescription$ CARDNAME deals 7 damage to target creature you don't control and 7 damage to target creature of an opponent's choice you don't control.
|
SVar:DBDamage:DB$ DealDamage | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature you don't control | NumDmg$ 7 | SubAbility$ DBDamage2 | SpellDescription$ CARDNAME deals 7 damage to target creature you don't control and 7 damage to target creature of an opponent's choice you don't control.
|
||||||
SVar:DBDamage2:DB$ DealDamage | TargetingPlayer$ Player.Opponent | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature the caster of this spell don't control | NumDmg$ 7
|
SVar:DBDamage2:DB$ DealDamage | TargetingPlayer$ Player.Opponent | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature the caster of this spell don't control | NumDmg$ 7
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/volcanic_offering.jpg
|
|
||||||
Oracle:Destroy target nonbasic land you don't control and target nonbasic land of an opponent's choice you don't control.\nVolcanic Offering deals 7 damage to target creature you don't control and 7 damage to target creature of an opponent's choice you don't control.
|
Oracle:Destroy target nonbasic land you don't control and target nonbasic land of an opponent's choice you don't control.\nVolcanic Offering deals 7 damage to target creature you don't control and 7 damage to target creature of an opponent's choice you don't control.
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ ManaCost:2 B
|
|||||||
Types:Creature Snake Wall
|
Types:Creature Snake Wall
|
||||||
PT:2/4
|
PT:2/4
|
||||||
K:Defender
|
K:Defender
|
||||||
A:AB$ Destroy | Cost$ 3 | Defined$ Self | Activator$ Player | SubAbility$ SnakeBite | SpellDescription$ Destroy CARDNAME and target creature it's blocking. Any player may activate this ability.
|
A:AB$ Pump | Cost$ 3 | Defined$ Self | Activator$ Player | AILogic$ Destroy | Curse$ True | SubAbility$ SnakeBite | SpellDescription$ Destroy CARDNAME and target creature it's blocking. Any player may activate this ability.
|
||||||
SVar:SnakeBite:DB$ Destroy | ValidTgts$ Creature.blockedBySource
|
SVar:SnakeBite:DB$ Pump | ValidTgts$ Creature.blockedBySource | AILogic$ Destroy | Curse$ True | SubAbility$ DBDestroy
|
||||||
|
SVar:DBDestroy:DB$ Destroy | Defined$ Targeted
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/wall_of_vipers.jpg
|
|
||||||
Oracle:Defender (This creature can't attack.)\n{3}: Destroy Wall of Vipers and target creature it's blocking. Any player may activate this ability.
|
Oracle:Defender (This creature can't attack.)\n{3}: Destroy Wall of Vipers and target creature it's blocking. Any player may activate this ability.
|
||||||
|
|||||||
@@ -673,7 +673,7 @@ public class HumanPlay {
|
|||||||
final Card offering = ability.getSacrificedAsOffering();
|
final Card offering = ability.getSacrificedAsOffering();
|
||||||
offering.setUsedToPay(false);
|
offering.setUsedToPay(false);
|
||||||
if (!manaInputCancelled) {
|
if (!manaInputCancelled) {
|
||||||
game.getAction().sacrifice(offering, ability, table);
|
game.getAction().sacrifice(offering, ability, table, null);
|
||||||
}
|
}
|
||||||
ability.resetSacrificedAsOffering();
|
ability.resetSacrificedAsOffering();
|
||||||
}
|
}
|
||||||
@@ -681,7 +681,7 @@ public class HumanPlay {
|
|||||||
final Card emerge = ability.getSacrificedAsEmerge();
|
final Card emerge = ability.getSacrificedAsEmerge();
|
||||||
emerge.setUsedToPay(false);
|
emerge.setUsedToPay(false);
|
||||||
if (!manaInputCancelled) {
|
if (!manaInputCancelled) {
|
||||||
game.getAction().sacrifice(emerge, ability, table);
|
game.getAction().sacrifice(emerge, ability, table, null);
|
||||||
}
|
}
|
||||||
ability.resetSacrificedAsEmerge();
|
ability.resetSacrificedAsEmerge();
|
||||||
}
|
}
|
||||||
@@ -785,7 +785,7 @@ public class HumanPlay {
|
|||||||
if (ability.getSacrificedAsOffering() != null) {
|
if (ability.getSacrificedAsOffering() != null) {
|
||||||
System.out.println("Finishing up Offering");
|
System.out.println("Finishing up Offering");
|
||||||
offering.setUsedToPay(false);
|
offering.setUsedToPay(false);
|
||||||
activator.getGame().getAction().sacrifice(offering, ability, null);
|
activator.getGame().getAction().sacrifice(offering, ability, null, null);
|
||||||
ability.resetSacrificedAsOffering();
|
ability.resetSacrificedAsOffering();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -796,7 +796,7 @@ public class HumanPlay {
|
|||||||
if (ability.getSacrificedAsEmerge() != null) {
|
if (ability.getSacrificedAsEmerge() != null) {
|
||||||
System.out.println("Finishing up Emerge");
|
System.out.println("Finishing up Emerge");
|
||||||
emerge.setUsedToPay(false);
|
emerge.setUsedToPay(false);
|
||||||
activator.getGame().getAction().sacrifice(emerge, ability, null);
|
activator.getGame().getAction().sacrifice(emerge, ability, null, null);
|
||||||
ability.resetSacrificedAsEmerge();
|
ability.resetSacrificedAsEmerge();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user