mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
Some cleanup
This commit is contained in:
@@ -1090,7 +1090,6 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
// Exile and bounce opponents stuff
|
// Exile and bounce opponents stuff
|
||||||
if (destination.equals(ZoneType.Exile) || origin.contains(ZoneType.Battlefield)) {
|
if (destination.equals(ZoneType.Exile) || origin.contains(ZoneType.Battlefield)) {
|
||||||
|
|
||||||
// don't rush bouncing stuff when not going to attack
|
// don't rush bouncing stuff when not going to attack
|
||||||
if (!immediately && game.getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)
|
if (!immediately && game.getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)
|
||||||
&& game.getPhaseHandler().isPlayerTurn(ai)
|
&& game.getPhaseHandler().isPlayerTurn(ai)
|
||||||
@@ -1433,17 +1432,14 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
|
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
|
||||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||||
|
|
||||||
CardCollection list = CardLists.getValidCards(ai.getGame().getCardsIn(tgt.getZone()), tgt.getValidTgts(), ai, source, sa);
|
CardCollection list = new CardCollection(CardUtil.getValidCardsToTarget(tgt, sa));
|
||||||
list = CardLists.getTargetableCards(list, sa);
|
|
||||||
|
|
||||||
list.removeAll(sa.getTargets().getTargetCards());
|
|
||||||
|
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// target loop
|
// target loop
|
||||||
while (sa.getTargets().size() < tgt.getMinTargets(sa.getHostCard(), sa)) {
|
while (!sa.isMinTargetChosen()) {
|
||||||
// AI Targeting
|
// AI Targeting
|
||||||
Card choice = null;
|
Card choice = null;
|
||||||
|
|
||||||
|
|||||||
@@ -757,7 +757,7 @@ public class DamageDealAi extends DamageAiBase {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// TODO: Improve Damage, we shouldn't just target the player just because we can
|
// TODO: Improve Damage, we shouldn't just target the player just because we can
|
||||||
if (sa.canTarget(enemy) && tcs.size() < tgt.getMaxTargets(source, sa)) {
|
if (sa.canTarget(enemy) && sa.canAddMoreTarget()) {
|
||||||
if (((phase.is(PhaseType.END_OF_TURN) && phase.getNextTurn().equals(ai))
|
if (((phase.is(PhaseType.END_OF_TURN) && phase.getNextTurn().equals(ai))
|
||||||
|| (SpellAbilityAi.isSorcerySpeed(sa, ai) && phase.is(PhaseType.MAIN2))
|
|| (SpellAbilityAi.isSorcerySpeed(sa, ai) && phase.is(PhaseType.MAIN2))
|
||||||
|| ("PingAfterAttack".equals(logic) && phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) && phase.isPlayerTurn(ai))
|
|| ("PingAfterAttack".equals(logic) && phase.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS) && phase.isPlayerTurn(ai))
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ public class DamagePreventAi extends SpellAbilityAi {
|
|||||||
ComputerUtilCard.sortByEvaluateCreature(combatants);
|
ComputerUtilCard.sortByEvaluateCreature(combatants);
|
||||||
|
|
||||||
for (final Card c : combatants) {
|
for (final Card c : combatants) {
|
||||||
if (ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat) && tcs.size() < tgt.getMaxTargets(hostCard, sa)) {
|
if (ComputerUtilCombat.combatantWouldBeDestroyed(ai, c, combat) && sa.canAddMoreTarget()) {
|
||||||
tcs.add(c);
|
tcs.add(c);
|
||||||
chance = true;
|
chance = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import forge.game.ability.AbilityUtils;
|
|||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardCollection;
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
|
import forge.game.card.CardUtil;
|
||||||
import forge.game.combat.Combat;
|
import forge.game.combat.Combat;
|
||||||
import forge.game.cost.Cost;
|
import forge.game.cost.Cost;
|
||||||
import forge.game.phase.PhaseHandler;
|
import forge.game.phase.PhaseHandler;
|
||||||
@@ -24,7 +25,6 @@ import forge.game.phase.PhaseType;
|
|||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.TargetRestrictions;
|
import forge.game.spellability.TargetRestrictions;
|
||||||
import forge.game.zone.ZoneType;
|
|
||||||
|
|
||||||
public class DebuffAi extends SpellAbilityAi {
|
public class DebuffAi extends SpellAbilityAi {
|
||||||
|
|
||||||
@@ -195,16 +195,13 @@ public class DebuffAi extends SpellAbilityAi {
|
|||||||
*/
|
*/
|
||||||
private boolean debuffMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) {
|
private boolean debuffMandatoryTarget(final Player ai, final SpellAbility sa, final boolean mandatory) {
|
||||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||||
CardCollection list = CardLists.getTargetableCards(ai.getGame().getCardsIn(ZoneType.Battlefield), sa);
|
List<Card> list = CardUtil.getValidCardsToTarget(tgt, sa);
|
||||||
|
|
||||||
if (list.size() < tgt.getMinTargets(sa.getHostCard(), sa)) {
|
if (list.size() < tgt.getMinTargets(sa.getHostCard(), sa)) {
|
||||||
sa.resetTargets();
|
sa.resetTargets();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove anything that's already been targeted
|
|
||||||
list.removeAll(sa.getTargets().getTargetCards());
|
|
||||||
|
|
||||||
final CardCollection pref = CardLists.filterControlledBy(list, ai.getOpponents());
|
final CardCollection pref = CardLists.filterControlledBy(list, ai.getOpponents());
|
||||||
final CardCollection forced = CardLists.filterControlledBy(list, ai);
|
final CardCollection forced = CardLists.filterControlledBy(list, ai);
|
||||||
final Card source = sa.getHostCard();
|
final Card source = sa.getHostCard();
|
||||||
@@ -219,7 +216,7 @@ public class DebuffAi extends SpellAbilityAi {
|
|||||||
sa.getTargets().add(c);
|
sa.getTargets().add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (sa.getTargets().size() < tgt.getMinTargets(source, sa)) {
|
while (!sa.isMinTargetChosen()) {
|
||||||
if (forced.isEmpty()) {
|
if (forced.isEmpty()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -237,13 +234,13 @@ public class DebuffAi extends SpellAbilityAi {
|
|||||||
sa.getTargets().add(c);
|
sa.getTargets().add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.getTargets().size() < tgt.getMinTargets(source, sa)) {
|
if (!sa.isMinTargetChosen()) {
|
||||||
sa.resetTargets();
|
sa.resetTargets();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} // pumpMandatoryTarget()
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
protected boolean doTriggerAINoCost(Player ai, SpellAbility sa, boolean mandatory) {
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ import forge.game.ability.effects.ProtectEffect;
|
|||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardCollection;
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
|
import forge.game.card.CardUtil;
|
||||||
import forge.game.combat.Combat;
|
import forge.game.combat.Combat;
|
||||||
import forge.game.phase.PhaseHandler;
|
import forge.game.phase.PhaseHandler;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.TargetRestrictions;
|
import forge.game.spellability.TargetRestrictions;
|
||||||
import forge.game.zone.ZoneType;
|
|
||||||
import forge.util.MyRandom;
|
import forge.util.MyRandom;
|
||||||
|
|
||||||
public class ProtectAi extends SpellAbilityAi {
|
public class ProtectAi extends SpellAbilityAi {
|
||||||
@@ -168,23 +168,23 @@ public class ProtectAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean checkApiLogic(final Player ai, final SpellAbility sa) {
|
protected boolean checkApiLogic(final Player ai, final SpellAbility sa) {
|
||||||
if (!sa.usesTargeting()) {
|
if (sa.usesTargeting()) {
|
||||||
final List<Card> cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa);
|
|
||||||
if (cards.size() == 0) {
|
|
||||||
return false;
|
|
||||||
} else if (cards.size() == 1) {
|
|
||||||
// Affecting single card
|
|
||||||
return getProtectCreatures(ai, sa).contains(cards.get(0));
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* when this happens we need to expand AI to consider if its ok
|
|
||||||
* for everything? for (Card card : cards) { // TODO if AI doesn't
|
|
||||||
* control Card and Pump is a Curse, than maybe use?
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
} else {
|
|
||||||
return protectTgtAI(ai, sa, false);
|
return protectTgtAI(ai, sa, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final List<Card> cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa);
|
||||||
|
if (cards.size() == 0) {
|
||||||
|
return false;
|
||||||
|
} else if (cards.size() == 1) {
|
||||||
|
// Affecting single card
|
||||||
|
return getProtectCreatures(ai, sa).contains(cards.get(0));
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* when this happens we need to expand AI to consider if its ok
|
||||||
|
* for everything? for (Card card : cards) { // TODO if AI doesn't
|
||||||
|
* control Card and Pump is a Curse, than maybe use?
|
||||||
|
* }
|
||||||
|
*/
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,21 +256,15 @@ public class ProtectAi extends SpellAbilityAi {
|
|||||||
} // protectTgtAI()
|
} // protectTgtAI()
|
||||||
|
|
||||||
private static boolean protectMandatoryTarget(final Player ai, final SpellAbility sa) {
|
private static boolean protectMandatoryTarget(final Player ai, final SpellAbility sa) {
|
||||||
final Game game = ai.getGame();
|
|
||||||
|
|
||||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||||
CardCollection list = CardLists.getTargetableCards(game.getCardsIn(ZoneType.Battlefield), sa);
|
final Card source = sa.getHostCard();
|
||||||
|
final List<Card> list = CardUtil.getValidCardsToTarget(tgt, sa);
|
||||||
|
|
||||||
if (list.size() < tgt.getMinTargets(sa.getHostCard(), sa)) {
|
if (list.size() < tgt.getMinTargets(source, sa)) {
|
||||||
sa.resetTargets();
|
sa.resetTargets();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove anything that's already been targeted
|
|
||||||
for (final Card c : sa.getTargets().getTargetCards()) {
|
|
||||||
list.remove(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardCollection pref = CardLists.filterControlledBy(list, ai);
|
CardCollection pref = CardLists.filterControlledBy(list, ai);
|
||||||
pref = CardLists.filter(pref, new Predicate<Card>() {
|
pref = CardLists.filter(pref, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -286,7 +280,6 @@ public class ProtectAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
final List<Card> forced = CardLists.filterControlledBy(list, ai);
|
final List<Card> forced = CardLists.filterControlledBy(list, ai);
|
||||||
final Card source = sa.getHostCard();
|
|
||||||
|
|
||||||
while (sa.canAddMoreTarget()) {
|
while (sa.canAddMoreTarget()) {
|
||||||
if (pref.isEmpty()) {
|
if (pref.isEmpty()) {
|
||||||
@@ -308,13 +301,13 @@ public class ProtectAi extends SpellAbilityAi {
|
|||||||
sa.getTargets().add(c);
|
sa.getTargets().add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (sa.getTargets().size() < tgt.getMinTargets(source, sa)) {
|
while (!sa.isMinTargetChosen()) {
|
||||||
if (forced.isEmpty()) {
|
if (forced.isEmpty()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Card c;
|
Card c;
|
||||||
if (CardLists.getNotType(forced, "Creature").size() == 0) {
|
if (CardLists.getNotType(forced, "Creature").isEmpty()) {
|
||||||
c = ComputerUtilCard.getWorstCreatureAI(forced);
|
c = ComputerUtilCard.getWorstCreatureAI(forced);
|
||||||
} else {
|
} else {
|
||||||
c = ComputerUtilCard.getCheapestPermanentAI(forced, sa, false);
|
c = ComputerUtilCard.getCheapestPermanentAI(forced, sa, false);
|
||||||
@@ -323,7 +316,7 @@ public class ProtectAi extends SpellAbilityAi {
|
|||||||
sa.getTargets().add(c);
|
sa.getTargets().add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.getTargets().size() < tgt.getMinTargets(source, sa)) {
|
if (!sa.isMinTargetChosen()) {
|
||||||
sa.resetTargets();
|
sa.resetTargets();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -616,23 +616,16 @@ public class PumpAi extends PumpAiBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean pumpMandatoryTarget(final Player ai, final SpellAbility sa) {
|
private boolean pumpMandatoryTarget(final Player ai, final SpellAbility sa) {
|
||||||
final Game game = ai.getGame();
|
|
||||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||||
CardCollection list = CardLists.getTargetableCards(game.getCardsIn(ZoneType.Battlefield), sa);
|
List<Card> list = CardUtil.getValidCardsToTarget(tgt, sa);
|
||||||
|
|
||||||
if (list.size() < tgt.getMinTargets(sa.getHostCard(), sa)) {
|
if (list.size() < tgt.getMinTargets(sa.getHostCard(), sa)) {
|
||||||
sa.resetTargets();
|
sa.resetTargets();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove anything that's already been targeted
|
|
||||||
for (final Card c : sa.getTargets().getTargetCards()) {
|
|
||||||
list.remove(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardCollection pref;
|
CardCollection pref;
|
||||||
CardCollection forced;
|
CardCollection forced;
|
||||||
final Card source = sa.getHostCard();
|
|
||||||
|
|
||||||
if (sa.isCurse()) {
|
if (sa.isCurse()) {
|
||||||
pref = CardLists.filterControlledBy(list, ai.getOpponents());
|
pref = CardLists.filterControlledBy(list, ai.getOpponents());
|
||||||
@@ -652,7 +645,7 @@ public class PumpAi extends PumpAiBase {
|
|||||||
sa.getTargets().add(c);
|
sa.getTargets().add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (sa.getTargets().size() < tgt.getMinTargets(source, sa)) {
|
while (!sa.isMinTargetChosen()) {
|
||||||
if (forced.isEmpty()) {
|
if (forced.isEmpty()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -668,7 +661,7 @@ public class PumpAi extends PumpAiBase {
|
|||||||
sa.getTargets().add(c);
|
sa.getTargets().add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sa.getTargets().size() < tgt.getMinTargets(source, sa)) {
|
if (!sa.isMinTargetChosen()) {
|
||||||
sa.resetTargets();
|
sa.resetTargets();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,13 +97,13 @@ public class SetStateAi extends SpellAbilityAi {
|
|||||||
for (final Card c : list) {
|
for (final Card c : list) {
|
||||||
if (shouldTransformCard(c, ai, ph) || "Always".equals(logic)) {
|
if (shouldTransformCard(c, ai, ph) || "Always".equals(logic)) {
|
||||||
sa.getTargets().add(c);
|
sa.getTargets().add(c);
|
||||||
if (sa.getTargets().size() == tgt.getMaxTargets(source, sa)) {
|
if (sa.isMaxTargetChosen()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sa.getTargets().size() >= tgt.getMinTargets(source, sa);
|
return sa.isMinTargetChosen();
|
||||||
}
|
}
|
||||||
} else if ("TurnFace".equals(mode)) {
|
} else if ("TurnFace".equals(mode)) {
|
||||||
if (!sa.usesTargeting()) {
|
if (!sa.usesTargeting()) {
|
||||||
|
|||||||
@@ -96,6 +96,13 @@ public class AbilityUtils {
|
|||||||
final Game game = hostCard.getGame();
|
final Game game = hostCard.getGame();
|
||||||
|
|
||||||
Card c = null;
|
Card c = null;
|
||||||
|
Player player = null;
|
||||||
|
if (sa instanceof SpellAbility) {
|
||||||
|
player = ((SpellAbility)sa).getActivatingPlayer();
|
||||||
|
}
|
||||||
|
if (player == null) {
|
||||||
|
player = hostCard.getController();
|
||||||
|
}
|
||||||
|
|
||||||
if (defined.equals("Self")) {
|
if (defined.equals("Self")) {
|
||||||
c = hostCard;
|
c = hostCard;
|
||||||
@@ -143,7 +150,7 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (defined.equals("TopOfGraveyard")) {
|
} else if (defined.equals("TopOfGraveyard")) {
|
||||||
final CardCollectionView grave = hostCard.getController().getCardsIn(ZoneType.Graveyard);
|
final CardCollectionView grave = player.getCardsIn(ZoneType.Graveyard);
|
||||||
|
|
||||||
if (grave.size() > 0) {
|
if (grave.size() > 0) {
|
||||||
c = grave.getLast();
|
c = grave.getLast();
|
||||||
@@ -153,7 +160,7 @@ public class AbilityUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (defined.endsWith("OfLibrary")) {
|
else if (defined.endsWith("OfLibrary")) {
|
||||||
final CardCollectionView lib = hostCard.getController().getCardsIn(ZoneType.Library);
|
final CardCollectionView lib = player.getCardsIn(ZoneType.Library);
|
||||||
int libSize = lib.size();
|
int libSize = lib.size();
|
||||||
if (libSize > 0) { // TopOfLibrary or BottomOfLibrary
|
if (libSize > 0) { // TopOfLibrary or BottomOfLibrary
|
||||||
if (defined.startsWith("TopThird")) {
|
if (defined.startsWith("TopThird")) {
|
||||||
@@ -354,7 +361,7 @@ public class AbilityUtils {
|
|||||||
candidates = game.getCardsIn(ZoneType.smartValueOf(zone));
|
candidates = game.getCardsIn(ZoneType.smartValueOf(zone));
|
||||||
validDefined = s[1];
|
validDefined = s[1];
|
||||||
}
|
}
|
||||||
cards.addAll(CardLists.getValidCards(candidates, validDefined, hostCard.getController(), hostCard, sa));
|
cards.addAll(CardLists.getValidCards(candidates, validDefined, player, hostCard, sa));
|
||||||
return cards;
|
return cards;
|
||||||
} else if (defined.startsWith("ExiledWith")) {
|
} else if (defined.startsWith("ExiledWith")) {
|
||||||
cards.addAll(hostCard.getExiledCards());
|
cards.addAll(hostCard.getExiledCards());
|
||||||
@@ -375,7 +382,7 @@ public class AbilityUtils {
|
|||||||
for (int i = 0; i < valids.length; i++) {
|
for (int i = 0; i < valids.length; i++) {
|
||||||
valids[i] = "Card." + valids[i];
|
valids[i] = "Card." + valids[i];
|
||||||
}
|
}
|
||||||
cards = CardLists.getValidCards(cards, valids, hostCard.getController(), hostCard, sa);
|
cards = CardLists.getValidCards(cards, valids, player, hostCard, sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cards;
|
return cards;
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public class PumpAllEffect extends SpellAbilityEffect {
|
|||||||
sb.append(desc);
|
sb.append(desc);
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
} // pumpAllStackDescription()
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resolve(final SpellAbility sa) {
|
public void resolve(final SpellAbility sa) {
|
||||||
|
|||||||
@@ -415,10 +415,7 @@ public class PumpEffect extends SpellAbilityEffect {
|
|||||||
final ZoneType pumpZone = sa.hasParam("PumpZone") ? ZoneType.smartValueOf(sa.getParam("PumpZone"))
|
final ZoneType pumpZone = sa.hasParam("PumpZone") ? ZoneType.smartValueOf(sa.getParam("PumpZone"))
|
||||||
: ZoneType.Battlefield;
|
: ZoneType.Battlefield;
|
||||||
|
|
||||||
final int size = tgtCards.size();
|
for (Card tgtC : tgtCards) {
|
||||||
for (int j = 0; j < size; j++) {
|
|
||||||
final Card tgtC = tgtCards.get(j);
|
|
||||||
|
|
||||||
// CR 702.26e
|
// CR 702.26e
|
||||||
if (tgtC.isPhasedOut()) {
|
if (tgtC.isPhasedOut()) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -32,14 +32,6 @@ public class RepeatEachEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
final SpellAbility repeat = sa.getAdditionalAbility("RepeatSubAbility");
|
final SpellAbility repeat = sa.getAdditionalAbility("RepeatSubAbility");
|
||||||
|
|
||||||
if (repeat != null && !repeat.getHostCard().equalsWithTimestamp(source)) {
|
|
||||||
// TODO: for some reason, the host card of the original additional SA is set to the cloned card when
|
|
||||||
// the ability is copied (e.g. Clone Legion + Swarm Intelligence). Couldn't figure out why this happens,
|
|
||||||
// so this hack is necessary for now to work around this issue.
|
|
||||||
System.out.println("Warning: RepeatSubAbility had the wrong host set (potentially after cloning the root SA or changing zones), attempting to correct...");
|
|
||||||
repeat.setHostCard(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Player player = sa.getActivatingPlayer();
|
final Player player = sa.getActivatingPlayer();
|
||||||
final Game game = player.getGame();
|
final Game game = player.getGame();
|
||||||
if (sa.hasParam("Optional") && sa.hasParam("OptionPrompt") && //for now, OptionPrompt is needed
|
if (sa.hasParam("Optional") && sa.hasParam("OptionPrompt") && //for now, OptionPrompt is needed
|
||||||
@@ -74,10 +66,6 @@ public class RepeatEachEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
else if (sa.hasParam("DefinedCards")) {
|
else if (sa.hasParam("DefinedCards")) {
|
||||||
repeatCards = AbilityUtils.getDefinedCards(source, sa.getParam("DefinedCards"), sa);
|
repeatCards = AbilityUtils.getDefinedCards(source, sa.getParam("DefinedCards"), sa);
|
||||||
if (sa.hasParam("AdditionalRestriction")) { // lki cards might not be in game
|
|
||||||
repeatCards = CardLists.getValidCards(repeatCards,
|
|
||||||
sa.getParam("AdditionalRestriction"), source.getController(), source, sa);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
boolean loopOverCards = repeatCards != null && !repeatCards.isEmpty();
|
boolean loopOverCards = repeatCards != null && !repeatCards.isEmpty();
|
||||||
|
|
||||||
@@ -125,13 +113,10 @@ public class RepeatEachEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
// for a mixed list of target permanents and players, e.g. Soulfire Eruption
|
// for a mixed list of target permanents and players, e.g. Soulfire Eruption
|
||||||
if (sa.hasParam("RepeatTargeted")) {
|
if (sa.hasParam("RepeatTargeted")) {
|
||||||
final List <GameObject> tgts = getTargets(sa);
|
for (final GameObject o : getTargets(sa)) {
|
||||||
if (tgts != null) {
|
source.addRemembered(o);
|
||||||
for (final Object o : tgts) {
|
AbilityUtils.resolve(repeat);
|
||||||
source.addRemembered(o);
|
source.removeRemembered(o);
|
||||||
AbilityUtils.resolve(repeat);
|
|
||||||
source.removeRemembered(o);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,17 +26,9 @@ public class RepeatEffect extends SpellAbilityEffect {
|
|||||||
// setup subability to repeat
|
// setup subability to repeat
|
||||||
SpellAbility repeat = sa.getAdditionalAbility("RepeatSubAbility");
|
SpellAbility repeat = sa.getAdditionalAbility("RepeatSubAbility");
|
||||||
|
|
||||||
if (repeat != null && !repeat.getHostCard().equals(source)) {
|
|
||||||
// TODO: for some reason, the host card of the original additional SA is set to the cloned card when
|
|
||||||
// the ability is copied (e.g. Clone Legion + Swarm Intelligence). Couldn't figure out why this happens,
|
|
||||||
// so this hack is necessary for now to work around this issue.
|
|
||||||
System.out.println("Warning: RepeatSubAbility had the wrong host set (potentially after cloning the root SA), attempting to correct...");
|
|
||||||
repeat.setHostCard(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
Integer maxRepeat = null;
|
Integer maxRepeat = null;
|
||||||
if (sa.hasParam("MaxRepeat")) {
|
if (sa.hasParam("MaxRepeat")) {
|
||||||
maxRepeat = AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("MaxRepeat"), sa);
|
maxRepeat = AbilityUtils.calculateAmount(source, sa.getParam("MaxRepeat"), sa);
|
||||||
if (maxRepeat.intValue() == 0) return; // do nothing if maxRepeat is 0. the next loop will execute at least once
|
if (maxRepeat.intValue() == 0) return; // do nothing if maxRepeat is 0. the next loop will execute at least once
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +42,7 @@ public class RepeatEffect extends SpellAbilityEffect {
|
|||||||
// Helm of Obedience vs Graveyard to Library replacement effect
|
// Helm of Obedience vs Graveyard to Library replacement effect
|
||||||
|
|
||||||
if (source.getName().equals("Helm of Obedience")) {
|
if (source.getName().equals("Helm of Obedience")) {
|
||||||
StringBuilder infLoop = new StringBuilder(sa.getHostCard().toString());
|
StringBuilder infLoop = new StringBuilder(source.toString());
|
||||||
infLoop.append(" - To avoid an infinite loop, this repeat has been broken ");
|
infLoop.append(" - To avoid an infinite loop, this repeat has been broken ");
|
||||||
infLoop.append(" and the game will now continue in the current state, ending the loop early. ");
|
infLoop.append(" and the game will now continue in the current state, ending the loop early. ");
|
||||||
infLoop.append("Once Draws are available this probably should change to a Draw.");
|
infLoop.append("Once Draws are available this probably should change to a Draw.");
|
||||||
@@ -84,7 +76,7 @@ public class RepeatEffect extends SpellAbilityEffect {
|
|||||||
} else {
|
} else {
|
||||||
list = game.getCardsIn(ZoneType.Battlefield);
|
list = game.getCardsIn(ZoneType.Battlefield);
|
||||||
}
|
}
|
||||||
list = CardLists.getValidCards(list, repeatPresent, sa.getActivatingPlayer(), sa.getHostCard(), sa);
|
list = CardLists.getValidCards(list, repeatPresent, activator, sa.getHostCard(), sa);
|
||||||
|
|
||||||
final String rightString = repeatCompare.substring(2);
|
final String rightString = repeatCompare.substring(2);
|
||||||
int right = AbilityUtils.calculateAmount(sa.getHostCard(), rightString, sa);
|
int right = AbilityUtils.calculateAmount(sa.getHostCard(), rightString, sa);
|
||||||
@@ -114,7 +106,7 @@ public class RepeatEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("RepeatOptional")) {
|
if (sa.hasParam("RepeatOptional")) {
|
||||||
Player decider = sa.hasParam("RepeatOptionalDecider")
|
Player decider = sa.hasParam("RepeatOptionalDecider")
|
||||||
? AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("RepeatOptionalDecider"), sa).get(0)
|
? AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("RepeatOptionalDecider"), sa).get(0)
|
||||||
: sa.getActivatingPlayer();
|
: activator;
|
||||||
return decider.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantRepeatProcessAgain"), null);
|
return decider.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantRepeatProcessAgain"), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ ManaCost:1 B B
|
|||||||
Types:Enchantment
|
Types:Enchantment
|
||||||
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ At the beginning of each end step, each player who tapped a land for mana this turn sacrifices a land. Desolation deals 2 damage to each player who sacrificed a Plains this way.
|
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ At the beginning of each end step, each player who tapped a land for mana this turn sacrifices a land. Desolation deals 2 damage to each player who sacrificed a Plains this way.
|
||||||
SVar:TrigSac:DB$ Sacrifice | SacValid$ Land | Defined$ Player.TappedLandForManaThisTurn | RememberSacrificed$ True | SubAbility$ DBRepeat
|
SVar:TrigSac:DB$ Sacrifice | SacValid$ Land | Defined$ Player.TappedLandForManaThisTurn | RememberSacrificed$ True | SubAbility$ DBRepeat
|
||||||
SVar:DBRepeat:DB$ RepeatEach | DefinedCards$ Remembered | AdditionalRestriction$ Plains | UseImprinted$ True | RepeatSubAbility$ DBDamage | SubAbility$ DBCleanup
|
SVar:DBRepeat:DB$ RepeatEach | DefinedCards$ Remembered.Plains | UseImprinted$ True | RepeatSubAbility$ DBDamage | SubAbility$ DBCleanup
|
||||||
SVar:DBDamage:DB$ DealDamage | Defined$ ImprintedController | NumDmg$ 2
|
SVar:DBDamage:DB$ DealDamage | Defined$ ImprintedController | NumDmg$ 2
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Name:Wave of Vitriol
|
|||||||
ManaCost:5 G G
|
ManaCost:5 G G
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ SacrificeAll | Cost$ 5 G G | ValidCards$ Artifact,Enchantment,Land.nonBasic | RememberSacrificed$ True | SubAbility$ DBRepeat | SpellDescription$ Each player sacrifices all artifacts, enchantments, and nonbasic lands they control. For each land sacrificed this way, its controller may search their library for a basic land card and put it onto the battlefield tapped. Then each player who searched their library this way shuffles.
|
A:SP$ SacrificeAll | Cost$ 5 G G | ValidCards$ Artifact,Enchantment,Land.nonBasic | RememberSacrificed$ True | SubAbility$ DBRepeat | SpellDescription$ Each player sacrifices all artifacts, enchantments, and nonbasic lands they control. For each land sacrificed this way, its controller may search their library for a basic land card and put it onto the battlefield tapped. Then each player who searched their library this way shuffles.
|
||||||
SVar:DBRepeat:DB$ RepeatEach | DefinedCards$ DirectRemembered | AdditionalRestriction$ Land | UseImprinted$ True | RepeatSubAbility$ DBSearch | ClearRemembered$ True | SubAbility$ DBShuffle
|
SVar:DBRepeat:DB$ RepeatEach | DefinedCards$ DirectRemembered.Land | UseImprinted$ True | RepeatSubAbility$ DBSearch | ClearRemembered$ True | SubAbility$ DBShuffle
|
||||||
SVar:DBSearch:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Land.Basic | ChangeNum$ 1 | Tapped$ True | RememberChanged$ True | DefinedPlayer$ ImprintedController | Chooser$ ImprintedController | NoShuffle$ True | Optional$ True
|
SVar:DBSearch:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Land.Basic | ChangeNum$ 1 | Tapped$ True | RememberChanged$ True | DefinedPlayer$ ImprintedController | Chooser$ ImprintedController | NoShuffle$ True | Optional$ True
|
||||||
SVar:DBShuffle:DB$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ ShuffleSearched | SubAbility$ DBCleanup
|
SVar:DBShuffle:DB$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ ShuffleSearched | SubAbility$ DBCleanup
|
||||||
SVar:ShuffleSearched:DB$ Shuffle | Defined$ Player.IsRemembered | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1
|
SVar:ShuffleSearched:DB$ Shuffle | Defined$ Player.IsRemembered | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1
|
||||||
|
|||||||
Reference in New Issue
Block a user