mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
removed the 'currentdefender' field from Combat, each user has to track himself the defenders
canAttack and addAttacker methods now require a defender.
This commit is contained in:
@@ -16,7 +16,6 @@ import forge.CardPredicates;
|
|||||||
import forge.CardPredicates.Presets;
|
import forge.CardPredicates.Presets;
|
||||||
import forge.Constant;
|
import forge.Constant;
|
||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.Singletons;
|
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.ApiType;
|
import forge.card.ability.ApiType;
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
@@ -28,6 +27,7 @@ import forge.card.spellability.AbilitySub;
|
|||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.card.trigger.TriggerType;
|
import forge.card.trigger.TriggerType;
|
||||||
|
import forge.game.GameState;
|
||||||
import forge.game.GlobalRuleChange;
|
import forge.game.GlobalRuleChange;
|
||||||
import forge.game.ai.ComputerUtil;
|
import forge.game.ai.ComputerUtil;
|
||||||
import forge.game.ai.ComputerUtilBlock;
|
import forge.game.ai.ComputerUtilBlock;
|
||||||
@@ -191,17 +191,17 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
//Ninjutsu
|
//Ninjutsu
|
||||||
if (sa.hasParam("Ninjutsu")) {
|
if (sa.hasParam("Ninjutsu")) {
|
||||||
if (source.isType("Legendary")
|
if (source.isType("Legendary")
|
||||||
&& !Singletons.getModel().getGame().getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noLegendRule)) {
|
&& !ai.getGame().getStaticEffects().getGlobalRuleChange(GlobalRuleChange.noLegendRule)) {
|
||||||
final List<Card> list = ai.getCardsIn(ZoneType.Battlefield);
|
final List<Card> list = ai.getCardsIn(ZoneType.Battlefield);
|
||||||
if (Iterables.any(list, CardPredicates.nameEquals(source.getName()))) {
|
if (Iterables.any(list, CardPredicates.nameEquals(source.getName()))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Singletons.getModel().getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DAMAGE)) {
|
if (ai.getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DAMAGE)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
List<Card> attackers = new ArrayList<Card>();
|
List<Card> attackers = new ArrayList<Card>();
|
||||||
attackers.addAll(Singletons.getModel().getGame().getCombat().getUnblockedAttackers());
|
attackers.addAll(ai.getGame().getCombat().getUnblockedAttackers());
|
||||||
boolean lowerCMC = false;
|
boolean lowerCMC = false;
|
||||||
for (Card attacker : attackers) {
|
for (Card attacker : attackers) {
|
||||||
if (attacker.getCMC() < source.getCMC()) {
|
if (attacker.getCMC() < source.getCMC()) {
|
||||||
@@ -284,7 +284,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// don't use fetching to top of library/graveyard before main2
|
// don't use fetching to top of library/graveyard before main2
|
||||||
if (Singletons.getModel().getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)
|
if (ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)
|
||||||
&& !sa.hasParam("ActivationPhases")) {
|
&& !sa.hasParam("ActivationPhases")) {
|
||||||
if (!destination.equals("Battlefield") && !destination.equals("Hand")) {
|
if (!destination.equals("Battlefield") && !destination.equals("Hand")) {
|
||||||
return false;
|
return false;
|
||||||
@@ -495,7 +495,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
combat.initiatePossibleDefenders(ai);
|
combat.initiatePossibleDefenders(ai);
|
||||||
List<Card> attackers = ai.getOpponent().getCreaturesInPlay();
|
List<Card> attackers = ai.getOpponent().getCreaturesInPlay();
|
||||||
for (Card att : attackers) {
|
for (Card att : attackers) {
|
||||||
combat.addAttacker(att);
|
combat.addAttacker(att, ai);
|
||||||
}
|
}
|
||||||
combat = ComputerUtilBlock.getBlockers(ai, combat, ai.getCreaturesInPlay());
|
combat = ComputerUtilBlock.getBlockers(ai, combat, ai.getCreaturesInPlay());
|
||||||
|
|
||||||
@@ -589,7 +589,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
// in general this should only be used to protect from Imminent Harm
|
// in general this should only be used to protect from Imminent Harm
|
||||||
// (dying or losing control of)
|
// (dying or losing control of)
|
||||||
if (origin.equals(ZoneType.Battlefield)) {
|
if (origin.equals(ZoneType.Battlefield)) {
|
||||||
if (Singletons.getModel().getGame().getStack().size() == 0) {
|
if (ai.getGame().getStack().size() == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -620,14 +620,14 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
// don't return something to your hand if your hand is full of good stuff
|
// don't return something to your hand if your hand is full of good stuff
|
||||||
if (destination.equals(ZoneType.Hand) && origin.equals(ZoneType.Graveyard)) {
|
if (destination.equals(ZoneType.Hand) && origin.equals(ZoneType.Graveyard)) {
|
||||||
final int handSize = ai.getCardsIn(ZoneType.Hand).size();
|
final int handSize = ai.getCardsIn(ZoneType.Hand).size();
|
||||||
if (Singletons.getModel().getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN1)) {
|
if (ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN1)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (Singletons.getModel().getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)
|
if (ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)
|
||||||
&& handSize > 1) {
|
&& handSize > 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (Singletons.getModel().getGame().getPhaseHandler().isPlayerTurn(ai)
|
if (ai.getGame().getPhaseHandler().isPlayerTurn(ai)
|
||||||
&& handSize >= ai.getMaxHandSize()) {
|
&& handSize >= ai.getMaxHandSize()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -688,7 +688,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tgt.resetTargets();
|
tgt.resetTargets();
|
||||||
List<Card> list = CardLists.getValidCards(Singletons.getModel().getGame().getCardsIn(origin), tgt.getValidTgts(), ai, source);
|
List<Card> list = CardLists.getValidCards(ai.getGame().getCardsIn(origin), tgt.getValidTgts(), ai, source);
|
||||||
if (sa.hasParam("AITgts")) {
|
if (sa.hasParam("AITgts")) {
|
||||||
list = CardLists.getValidCards(list, sa.getParam("AITgts"), sa.getActivatingPlayer(), source);
|
list = CardLists.getValidCards(list, sa.getParam("AITgts"), sa.getActivatingPlayer(), source);
|
||||||
}
|
}
|
||||||
@@ -721,7 +721,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
// check stack for something on the stack that will kill
|
// check stack for something on the stack that will kill
|
||||||
// anything i control
|
// anything i control
|
||||||
if (Singletons.getModel().getGame().getStack().size() > 0) {
|
if (ai.getGame().getStack().size() > 0) {
|
||||||
final ArrayList<Object> objects = ComputerUtil.predictThreatenedObjects(ai, sa);
|
final ArrayList<Object> objects = ComputerUtil.predictThreatenedObjects(ai, sa);
|
||||||
|
|
||||||
final List<Card> threatenedTargets = new ArrayList<Card>();
|
final List<Card> threatenedTargets = new ArrayList<Card>();
|
||||||
@@ -739,7 +739,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Save combatants
|
// Save combatants
|
||||||
else if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
|
else if (ai.getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
|
||||||
final List<Card> combatants = CardLists.filter(aiPermanents, CardPredicates.Presets.CREATURES);
|
final List<Card> combatants = CardLists.filter(aiPermanents, CardPredicates.Presets.CREATURES);
|
||||||
CardLists.sortByEvaluateCreature(combatants);
|
CardLists.sortByEvaluateCreature(combatants);
|
||||||
|
|
||||||
@@ -795,7 +795,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
if (origin.equals(ZoneType.Battlefield)
|
if (origin.equals(ZoneType.Battlefield)
|
||||||
&& destination.equals(ZoneType.Exile)
|
&& destination.equals(ZoneType.Exile)
|
||||||
&& (subApi == ApiType.DelayedTrigger || (subApi == ApiType.ChangeZone && subAffected.equals("Remembered")))
|
&& (subApi == ApiType.DelayedTrigger || (subApi == ApiType.ChangeZone && subAffected.equals("Remembered")))
|
||||||
&& !(Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || sa
|
&& !(ai.getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) || sa
|
||||||
.isAbility())) {
|
.isAbility())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -805,8 +805,8 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
// don't rush bouncing stuff when not going to attack
|
// don't rush bouncing stuff when not going to attack
|
||||||
if (!sa.isTrigger() && sa.getPayCosts() != null
|
if (!sa.isTrigger() && sa.getPayCosts() != null
|
||||||
&& Singletons.getModel().getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)
|
&& ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)
|
||||||
&& Singletons.getModel().getGame().getPhaseHandler().isPlayerTurn(ai)
|
&& ai.getGame().getPhaseHandler().isPlayerTurn(ai)
|
||||||
&& ai.getCreaturesInPlay().isEmpty()) {
|
&& ai.getCreaturesInPlay().isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -825,7 +825,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only care about combatants during combat
|
// Only care about combatants during combat
|
||||||
if (Singletons.getModel().getGame().getPhaseHandler().inCombat()) {
|
if (ai.getGame().getPhaseHandler().inCombat()) {
|
||||||
CardLists.getValidCards(list, "Card.attacking,Card.blocking", null, null);
|
CardLists.getValidCards(list, "Card.attacking,Card.blocking", null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -931,7 +931,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
|
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
|
||||||
final Target tgt = sa.getTarget();
|
final Target tgt = sa.getTarget();
|
||||||
|
|
||||||
List<Card> list = CardLists.getValidCards(Singletons.getModel().getGame().getCardsIn(origin), tgt.getValidTgts(), ai, source);
|
List<Card> list = CardLists.getValidCards(ai.getGame().getCardsIn(origin), tgt.getValidTgts(), ai, source);
|
||||||
|
|
||||||
// Narrow down the list:
|
// Narrow down the list:
|
||||||
if (origin.equals(ZoneType.Battlefield)) {
|
if (origin.equals(ZoneType.Battlefield)) {
|
||||||
@@ -1070,6 +1070,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
final Card card = sa.getSourceCard();
|
final Card card = sa.getSourceCard();
|
||||||
final boolean defined = sa.hasParam("Defined");
|
final boolean defined = sa.hasParam("Defined");
|
||||||
final Player activator = sa.getActivatingPlayer();
|
final Player activator = sa.getActivatingPlayer();
|
||||||
|
final GameState game = ai.getGame();
|
||||||
|
|
||||||
if (tgt != null) {
|
if (tgt != null) {
|
||||||
if (!tgt.getTargetPlayers().isEmpty()) {
|
if (!tgt.getTargetPlayers().isEmpty()) {
|
||||||
@@ -1101,7 +1102,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
} else if (!origin.contains(ZoneType.Library) && !origin.contains(ZoneType.Hand)
|
} else if (!origin.contains(ZoneType.Library) && !origin.contains(ZoneType.Hand)
|
||||||
&& !sa.hasParam("DefinedPlayer")) {
|
&& !sa.hasParam("DefinedPlayer")) {
|
||||||
fetchList = Singletons.getModel().getGame().getCardsIn(origin);
|
fetchList = game.getCardsIn(origin);
|
||||||
fetchList = AbilityUtils.filterListByType(fetchList, type, sa);
|
fetchList = AbilityUtils.filterListByType(fetchList, type, sa);
|
||||||
} else {
|
} else {
|
||||||
fetchList = player.getCardsIn(origin);
|
fetchList = player.getCardsIn(origin);
|
||||||
@@ -1253,7 +1254,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
Card movedCard = null;
|
Card movedCard = null;
|
||||||
if (ZoneType.Library.equals(destination)) {
|
if (ZoneType.Library.equals(destination)) {
|
||||||
final int libraryPos = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : 0;
|
final int libraryPos = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : 0;
|
||||||
movedCard = Singletons.getModel().getGame().getAction().moveToLibrary(c, libraryPos);
|
movedCard = game.getAction().moveToLibrary(c, libraryPos);
|
||||||
} else if (ZoneType.Battlefield.equals(destination)) {
|
} else if (ZoneType.Battlefield.equals(destination)) {
|
||||||
if (sa.hasParam("Tapped")) {
|
if (sa.hasParam("Tapped")) {
|
||||||
c.setTapped(true);
|
c.setTapped(true);
|
||||||
@@ -1261,9 +1262,9 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
if (sa.hasParam("GainControl")) {
|
if (sa.hasParam("GainControl")) {
|
||||||
if (sa.hasParam("NewController")) {
|
if (sa.hasParam("NewController")) {
|
||||||
final Player p = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("DefinedPlayer"), sa).get(0);
|
final Player p = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("DefinedPlayer"), sa).get(0);
|
||||||
c.setController(p, Singletons.getModel().getGame().getNextTimestamp());
|
c.setController(p, game.getNextTimestamp());
|
||||||
} else {
|
} else {
|
||||||
c.setController(sa.getActivatingPlayer(), Singletons.getModel().getGame().getNextTimestamp());
|
c.setController(sa.getActivatingPlayer(), game.getNextTimestamp());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1271,7 +1272,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
List<Card> list = AbilityUtils.getDefinedCards(sa.getSourceCard(),
|
List<Card> list = AbilityUtils.getDefinedCards(sa.getSourceCard(),
|
||||||
sa.getParam("AttachedTo"), sa);
|
sa.getParam("AttachedTo"), sa);
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
list = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield);
|
list = game.getCardsIn(ZoneType.Battlefield);
|
||||||
list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), c.getController(), c);
|
list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), c.getController(), c);
|
||||||
}
|
}
|
||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
@@ -1289,7 +1290,9 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sa.hasParam("Attacking")) {
|
if (sa.hasParam("Attacking")) {
|
||||||
Singletons.getModel().getGame().getCombat().addAttacker(c);
|
List<GameEntity> defenders = game.getCombat().getDefenders();
|
||||||
|
if ( !defenders.isEmpty() )
|
||||||
|
game.getCombat().addAttacker(c, defenders.get(0));
|
||||||
}
|
}
|
||||||
// Auras without Candidates stay in their current location
|
// Auras without Candidates stay in their current location
|
||||||
if (c.isAura()) {
|
if (c.isAura()) {
|
||||||
@@ -1299,24 +1302,24 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
movedCard = Singletons.getModel().getGame().getAction().moveTo(c.getController().getZone(destination), c);
|
movedCard = game.getAction().moveTo(c.getController().getZone(destination), c);
|
||||||
if (sa.hasParam("Tapped")) {
|
if (sa.hasParam("Tapped")) {
|
||||||
movedCard.setTapped(true);
|
movedCard.setTapped(true);
|
||||||
}
|
}
|
||||||
} else if (destination.equals(ZoneType.Exile)) {
|
} else if (destination.equals(ZoneType.Exile)) {
|
||||||
movedCard = Singletons.getModel().getGame().getAction().exile(c);
|
movedCard = game.getAction().exile(c);
|
||||||
if (sa.hasParam("ExileFaceDown")) {
|
if (sa.hasParam("ExileFaceDown")) {
|
||||||
movedCard.setState(CardCharacteristicName.FaceDown);
|
movedCard.setState(CardCharacteristicName.FaceDown);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
movedCard = Singletons.getModel().getGame().getAction().moveTo(destination, c);
|
movedCard = game.getAction().moveTo(destination, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (champion) {
|
if (champion) {
|
||||||
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
||||||
runParams.put("Card", card);
|
runParams.put("Card", card);
|
||||||
runParams.put("Championed", c);
|
runParams.put("Championed", c);
|
||||||
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Championed, runParams, false);
|
game.getTriggerHandler().runTrigger(TriggerType.Championed, runParams, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remember != null) {
|
if (remember != null) {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import forge.CardCharacteristicName;
|
|||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.CardPredicates;
|
import forge.CardPredicates;
|
||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.Singletons;
|
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
import forge.card.ability.ai.ChangeZoneAi;
|
import forge.card.ability.ai.ChangeZoneAi;
|
||||||
@@ -20,6 +19,7 @@ import forge.card.spellability.SpellAbility;
|
|||||||
import forge.card.spellability.SpellAbilityStackInstance;
|
import forge.card.spellability.SpellAbilityStackInstance;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.card.trigger.TriggerType;
|
import forge.card.trigger.TriggerType;
|
||||||
|
import forge.game.GameState;
|
||||||
import forge.game.ai.ComputerUtilCard;
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.player.HumanPlayer;
|
import forge.game.player.HumanPlayer;
|
||||||
@@ -375,6 +375,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
final Target tgt = sa.getTarget();
|
final Target tgt = sa.getTarget();
|
||||||
final Player player = sa.getActivatingPlayer();
|
final Player player = sa.getActivatingPlayer();
|
||||||
final Card hostCard = sa.getSourceCard();
|
final Card hostCard = sa.getSourceCard();
|
||||||
|
final GameState game = player.getGame();
|
||||||
|
|
||||||
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
|
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
|
||||||
final List<ZoneType> origin = ZoneType.listValueOf(sa.getParam("Origin"));
|
final List<ZoneType> origin = ZoneType.listValueOf(sa.getParam("Origin"));
|
||||||
@@ -400,12 +401,12 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final SpellAbilityStackInstance si = Singletons.getModel().getGame().getStack().getInstanceFromSpellAbility(tgtSA);
|
final SpellAbilityStackInstance si = game.getStack().getInstanceFromSpellAbility(tgtSA);
|
||||||
if (si == null) {
|
if (si == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFromStack(tgtSA, sa, si);
|
removeFromStack(tgtSA, sa, si, game);
|
||||||
} // End of change from stack
|
} // End of change from stack
|
||||||
|
|
||||||
final String remember = sa.getParam("RememberChanged");
|
final String remember = sa.getParam("RememberChanged");
|
||||||
@@ -431,7 +432,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (player.isHuman() && optional && !GuiDialog.confirm(hostCard, prompt)) {
|
if (player.isHuman() && optional && !GuiDialog.confirm(hostCard, prompt)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final Zone originZone = Singletons.getModel().getGame().getZoneOf(tgtC);
|
final Zone originZone = game.getZoneOf(tgtC);
|
||||||
|
|
||||||
// if Target isn't in the expected Zone, continue
|
// if Target isn't in the expected Zone, continue
|
||||||
|
|
||||||
@@ -445,7 +446,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
// library position is zero indexed
|
// library position is zero indexed
|
||||||
final int libraryPosition = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : 0;
|
final int libraryPosition = sa.hasParam("LibraryPosition") ? Integer.parseInt(sa.getParam("LibraryPosition")) : 0;
|
||||||
|
|
||||||
movedCard = Singletons.getModel().getGame().getAction().moveToLibrary(tgtC, libraryPosition);
|
movedCard = game.getAction().moveToLibrary(tgtC, libraryPosition);
|
||||||
|
|
||||||
// for things like Gaea's Blessing
|
// for things like Gaea's Blessing
|
||||||
if (sa.hasParam("Shuffle")) {
|
if (sa.hasParam("Shuffle")) {
|
||||||
@@ -459,16 +460,16 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("GainControl")) {
|
if (sa.hasParam("GainControl")) {
|
||||||
if (sa.hasParam("NewController")) {
|
if (sa.hasParam("NewController")) {
|
||||||
final Player p = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("NewController"), sa).get(0);
|
final Player p = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("NewController"), sa).get(0);
|
||||||
tgtC.setController(p, Singletons.getModel().getGame().getNextTimestamp());
|
tgtC.setController(p, game.getNextTimestamp());
|
||||||
} else {
|
} else {
|
||||||
tgtC.setController(sa.getActivatingPlayer(), Singletons.getModel().getGame().getNextTimestamp());
|
tgtC.setController(sa.getActivatingPlayer(), game.getNextTimestamp());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sa.hasParam("AttachedTo")) {
|
if (sa.hasParam("AttachedTo")) {
|
||||||
List<Card> list = AbilityUtils.getDefinedCards(hostCard,
|
List<Card> list = AbilityUtils.getDefinedCards(hostCard,
|
||||||
sa.getParam("AttachedTo"), sa);
|
sa.getParam("AttachedTo"), sa);
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
list = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield);
|
list = game.getCardsIn(ZoneType.Battlefield);
|
||||||
list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), tgtC.getController(), tgtC);
|
list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), tgtC.getController(), tgtC);
|
||||||
}
|
}
|
||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
@@ -511,25 +512,28 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
movedCard = Singletons.getModel().getGame().getAction()
|
movedCard = game.getAction().moveTo(tgtC.getController().getZone(destination), tgtC);
|
||||||
.moveTo(tgtC.getController().getZone(destination), tgtC);
|
|
||||||
|
|
||||||
if (sa.hasParam("Ninjutsu") || sa.hasParam("Attacking")) {
|
if (sa.hasParam("Ninjutsu") || sa.hasParam("Attacking")) {
|
||||||
Singletons.getModel().getGame().getCombat().addAttacker(tgtC);
|
// What should they attack?
|
||||||
Singletons.getModel().getGame().getCombat().addUnblockedAttacker(tgtC);
|
List<GameEntity> defenders = game.getCombat().getDefenders();
|
||||||
|
if (!defenders.isEmpty()) {
|
||||||
|
game.getCombat().addAttacker(tgtC, defenders.get(0));
|
||||||
|
game.getCombat().addUnblockedAttacker(tgtC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (sa.hasParam("Tapped") || sa.hasParam("Ninjutsu")) {
|
if (sa.hasParam("Tapped") || sa.hasParam("Ninjutsu")) {
|
||||||
tgtC.setTapped(true);
|
tgtC.setTapped(true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
movedCard = Singletons.getModel().getGame().getAction().moveTo(destination, tgtC);
|
movedCard = game.getAction().moveTo(destination, tgtC);
|
||||||
// If a card is Exiled from the stack, remove its spells from the stack
|
// If a card is Exiled from the stack, remove its spells from the stack
|
||||||
if (sa.hasParam("Fizzle")) {
|
if (sa.hasParam("Fizzle")) {
|
||||||
ArrayList<SpellAbility> spells = tgtC.getSpellAbilities();
|
ArrayList<SpellAbility> spells = tgtC.getSpellAbilities();
|
||||||
for (SpellAbility spell : spells) {
|
for (SpellAbility spell : spells) {
|
||||||
if (tgtC.isInZone(ZoneType.Exile)) {
|
if (tgtC.isInZone(ZoneType.Exile)) {
|
||||||
final SpellAbilityStackInstance si = Singletons.getModel().getGame().getStack().getInstanceFromSpellAbility(spell);
|
final SpellAbilityStackInstance si = game.getStack().getInstanceFromSpellAbility(spell);
|
||||||
Singletons.getModel().getGame().getStack().remove(si);
|
game.getStack().remove(si);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -615,6 +619,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
final List<Card> movedCards = new ArrayList<Card>();
|
final List<Card> movedCards = new ArrayList<Card>();
|
||||||
final boolean defined = sa.hasParam("Defined");
|
final boolean defined = sa.hasParam("Defined");
|
||||||
final boolean optional = sa.hasParam("Optional");
|
final boolean optional = sa.hasParam("Optional");
|
||||||
|
final GameState game = player.getGame();
|
||||||
|
|
||||||
final Target tgt = sa.getTarget();
|
final Target tgt = sa.getTarget();
|
||||||
if (tgt != null) {
|
if (tgt != null) {
|
||||||
@@ -675,7 +680,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
} else if (!origin.contains(ZoneType.Library) && !origin.contains(ZoneType.Hand)
|
} else if (!origin.contains(ZoneType.Library) && !origin.contains(ZoneType.Hand)
|
||||||
&& !sa.hasParam("DefinedPlayer")) {
|
&& !sa.hasParam("DefinedPlayer")) {
|
||||||
fetchList = Singletons.getModel().getGame().getCardsIn(origin);
|
fetchList = game.getCardsIn(origin);
|
||||||
} else {
|
} else {
|
||||||
fetchList = player.getCardsIn(origin);
|
fetchList = player.getCardsIn(origin);
|
||||||
}
|
}
|
||||||
@@ -744,7 +749,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (origin.contains(ZoneType.Library) && (i < 1) && !"False".equals(sa.getParam("Shuffle"))) {
|
if (origin.contains(ZoneType.Library) && (i < 1) && !"False".equals(sa.getParam("Shuffle"))) {
|
||||||
player.shuffle();
|
player.shuffle();
|
||||||
}
|
}
|
||||||
movedCard = Singletons.getModel().getGame().getAction().moveToLibrary(c, libraryPos);
|
movedCard = game.getAction().moveToLibrary(c, libraryPos);
|
||||||
} else if (destination.equals(ZoneType.Battlefield)) {
|
} else if (destination.equals(ZoneType.Battlefield)) {
|
||||||
if (sa.hasParam("Tapped")) {
|
if (sa.hasParam("Tapped")) {
|
||||||
c.setTapped(true);
|
c.setTapped(true);
|
||||||
@@ -752,9 +757,9 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("GainControl")) {
|
if (sa.hasParam("GainControl")) {
|
||||||
if (sa.hasParam("NewController")) {
|
if (sa.hasParam("NewController")) {
|
||||||
final Player p = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("NewController"), sa).get(0);
|
final Player p = AbilityUtils.getDefinedPlayers(sa.getSourceCard(), sa.getParam("NewController"), sa).get(0);
|
||||||
c.setController(p, Singletons.getModel().getGame().getNextTimestamp());
|
c.setController(p, game.getNextTimestamp());
|
||||||
} else {
|
} else {
|
||||||
c.setController(sa.getActivatingPlayer(), Singletons.getModel().getGame().getNextTimestamp());
|
c.setController(sa.getActivatingPlayer(), game.getNextTimestamp());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -762,7 +767,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
List<Card> list = AbilityUtils.getDefinedCards(sa.getSourceCard(),
|
List<Card> list = AbilityUtils.getDefinedCards(sa.getSourceCard(),
|
||||||
sa.getParam("AttachedTo"), sa);
|
sa.getParam("AttachedTo"), sa);
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
list = Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield);
|
list = game.getCardsIn(ZoneType.Battlefield);
|
||||||
list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), c.getController(), c);
|
list = CardLists.getValidCards(list, sa.getParam("AttachedTo"), c.getController(), c);
|
||||||
}
|
}
|
||||||
if (!list.isEmpty()) {
|
if (!list.isEmpty()) {
|
||||||
@@ -826,20 +831,20 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("Attacking")) {
|
if (sa.hasParam("Attacking")) {
|
||||||
final List<GameEntity> e = c.getController().getGame().getCombat().getDefenders();
|
final List<GameEntity> e = c.getController().getGame().getCombat().getDefenders();
|
||||||
final GameEntity defender = e.size() == 1 ? e.get(0) : GuiChoose.one("Declare " + c, e);
|
final GameEntity defender = e.size() == 1 ? e.get(0) : GuiChoose.one("Declare " + c, e);
|
||||||
Singletons.getModel().getGame().getCombat().addAttacker(c, defender);
|
game.getCombat().addAttacker(c, defender);
|
||||||
}
|
}
|
||||||
|
|
||||||
movedCard = Singletons.getModel().getGame().getAction().moveTo(c.getController().getZone(destination), c);
|
movedCard = game.getAction().moveTo(c.getController().getZone(destination), c);
|
||||||
if (sa.hasParam("Tapped")) {
|
if (sa.hasParam("Tapped")) {
|
||||||
movedCard.setTapped(true);
|
movedCard.setTapped(true);
|
||||||
}
|
}
|
||||||
} else if (destination.equals(ZoneType.Exile)) {
|
} else if (destination.equals(ZoneType.Exile)) {
|
||||||
movedCard = Singletons.getModel().getGame().getAction().exile(c);
|
movedCard = game.getAction().exile(c);
|
||||||
if (sa.hasParam("ExileFaceDown")) {
|
if (sa.hasParam("ExileFaceDown")) {
|
||||||
movedCard.setState(CardCharacteristicName.FaceDown);
|
movedCard.setState(CardCharacteristicName.FaceDown);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
movedCard = Singletons.getModel().getGame().getAction().moveTo(destination, c);
|
movedCard = game.getAction().moveTo(destination, c);
|
||||||
}
|
}
|
||||||
movedCards.add(movedCard);
|
movedCards.add(movedCard);
|
||||||
|
|
||||||
@@ -847,7 +852,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
final HashMap<String, Object> runParams = new HashMap<String, Object>();
|
||||||
runParams.put("Card", card);
|
runParams.put("Card", card);
|
||||||
runParams.put("Championed", c);
|
runParams.put("Championed", c);
|
||||||
Singletons.getModel().getGame().getTriggerHandler().runTrigger(TriggerType.Championed, runParams, false);
|
game.getTriggerHandler().runTrigger(TriggerType.Championed, runParams, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remember != null) {
|
if (remember != null) {
|
||||||
@@ -895,28 +900,29 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
* @param si
|
* @param si
|
||||||
* a {@link forge.card.spellability.SpellAbilityStackInstance}
|
* a {@link forge.card.spellability.SpellAbilityStackInstance}
|
||||||
* object.
|
* object.
|
||||||
|
* @param game
|
||||||
*/
|
*/
|
||||||
private static void removeFromStack(final SpellAbility tgtSA, final SpellAbility srcSA, final SpellAbilityStackInstance si) {
|
private static void removeFromStack(final SpellAbility tgtSA, final SpellAbility srcSA, final SpellAbilityStackInstance si, final GameState game) {
|
||||||
Singletons.getModel().getGame().getStack().remove(si);
|
game.getStack().remove(si);
|
||||||
|
|
||||||
if (srcSA.hasParam("Destination")) {
|
if (srcSA.hasParam("Destination")) {
|
||||||
final boolean remember = srcSA.hasParam("RememberChanged");
|
final boolean remember = srcSA.hasParam("RememberChanged");
|
||||||
if (tgtSA.isAbility()) {
|
if (tgtSA.isAbility()) {
|
||||||
// Shouldn't be able to target Abilities but leaving this in for now
|
// Shouldn't be able to target Abilities but leaving this in for now
|
||||||
} else if (tgtSA.isFlashBackAbility()) {
|
} else if (tgtSA.isFlashBackAbility()) {
|
||||||
Singletons.getModel().getGame().getAction().exile(tgtSA.getSourceCard());
|
game.getAction().exile(tgtSA.getSourceCard());
|
||||||
} else if (srcSA.getParam("Destination").equals("Graveyard")) {
|
} else if (srcSA.getParam("Destination").equals("Graveyard")) {
|
||||||
Singletons.getModel().getGame().getAction().moveToGraveyard(tgtSA.getSourceCard());
|
game.getAction().moveToGraveyard(tgtSA.getSourceCard());
|
||||||
} else if (srcSA.getParam("Destination").equals("Exile")) {
|
} else if (srcSA.getParam("Destination").equals("Exile")) {
|
||||||
Singletons.getModel().getGame().getAction().exile(tgtSA.getSourceCard());
|
game.getAction().exile(tgtSA.getSourceCard());
|
||||||
} else if (srcSA.getParam("Destination").equals("TopOfLibrary")) {
|
} else if (srcSA.getParam("Destination").equals("TopOfLibrary")) {
|
||||||
Singletons.getModel().getGame().getAction().moveToLibrary(tgtSA.getSourceCard());
|
game.getAction().moveToLibrary(tgtSA.getSourceCard());
|
||||||
} else if (srcSA.getParam("Destination").equals("Hand")) {
|
} else if (srcSA.getParam("Destination").equals("Hand")) {
|
||||||
Singletons.getModel().getGame().getAction().moveToHand(tgtSA.getSourceCard());
|
game.getAction().moveToHand(tgtSA.getSourceCard());
|
||||||
} else if (srcSA.getParam("Destination").equals("BottomOfLibrary")) {
|
} else if (srcSA.getParam("Destination").equals("BottomOfLibrary")) {
|
||||||
Singletons.getModel().getGame().getAction().moveToBottomOfLibrary(tgtSA.getSourceCard());
|
game.getAction().moveToBottomOfLibrary(tgtSA.getSourceCard());
|
||||||
} else if (srcSA.getParam("Destination").equals("ShuffleIntoLibrary")) {
|
} else if (srcSA.getParam("Destination").equals("ShuffleIntoLibrary")) {
|
||||||
Singletons.getModel().getGame().getAction().moveToBottomOfLibrary(tgtSA.getSourceCard());
|
game.getAction().moveToBottomOfLibrary(tgtSA.getSourceCard());
|
||||||
tgtSA.getSourceCard().getController().shuffle();
|
tgtSA.getSourceCard().getController().shuffle();
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("AbilityFactory_ChangeZone: Invalid Destination argument for card "
|
throw new IllegalArgumentException("AbilityFactory_ChangeZone: Invalid Destination argument for card "
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.Singletons;
|
|
||||||
import forge.card.ability.AbilityFactory;
|
import forge.card.ability.AbilityFactory;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.SpellAbilityEffect;
|
import forge.card.ability.SpellAbilityEffect;
|
||||||
@@ -30,6 +30,7 @@ import forge.card.cardfactory.CardFactory;
|
|||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.trigger.Trigger;
|
import forge.card.trigger.Trigger;
|
||||||
import forge.card.trigger.TriggerHandler;
|
import forge.card.trigger.TriggerHandler;
|
||||||
|
import forge.game.GameState;
|
||||||
import forge.game.event.TokenCreatedEvent;
|
import forge.game.event.TokenCreatedEvent;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.gui.GuiChoose;
|
import forge.gui.GuiChoose;
|
||||||
@@ -206,9 +207,9 @@ public class TokenEffect extends SpellAbilityEffect {
|
|||||||
final List<Card> tokens = CardFactory.makeToken(substitutedName, imageName, controller, cost,
|
final List<Card> tokens = CardFactory.makeToken(substitutedName, imageName, controller, cost,
|
||||||
substitutedTypes, finalPower, finalToughness, this.tokenKeywords);
|
substitutedTypes, finalPower, finalToughness, this.tokenKeywords);
|
||||||
for(Card tok : tokens) {
|
for(Card tok : tokens) {
|
||||||
Singletons.getModel().getGame().getAction().moveToPlay(tok);
|
controller.getGame().getAction().moveToPlay(tok);
|
||||||
}
|
}
|
||||||
Singletons.getModel().getGame().getEvents().post(new TokenCreatedEvent());
|
controller.getGame().getEvents().post(new TokenCreatedEvent());
|
||||||
|
|
||||||
// Grant rule changes
|
// Grant rule changes
|
||||||
if (this.tokenHiddenKeywords != null) {
|
if (this.tokenHiddenKeywords != null) {
|
||||||
@@ -274,25 +275,25 @@ public class TokenEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final GameState game = controller.getGame();
|
||||||
for (final Card c : tokens) {
|
for (final Card c : tokens) {
|
||||||
if (this.tokenTapped) {
|
if (this.tokenTapped) {
|
||||||
c.setTapped(true);
|
c.setTapped(true);
|
||||||
}
|
}
|
||||||
if (this.tokenAttacking) {
|
if (this.tokenAttacking) {
|
||||||
|
final List<GameEntity> defs = c.getController().getGame().getCombat().getDefenders();
|
||||||
if (c.getController().isHuman()) {
|
if (c.getController().isHuman()) {
|
||||||
final List<GameEntity> e = c.getController().getGame().getCombat().getDefenders();
|
final GameEntity defender = defs.size() == 1 ? defs.get(0) : GuiChoose.one("Declare " + c, defs);
|
||||||
final GameEntity defender = e.size() == 1
|
game.getCombat().addAttacker(c, defender);
|
||||||
? e.get(0) : GuiChoose.one("Declare " + c, e);
|
|
||||||
Singletons.getModel().getGame().getCombat().addAttacker(c, defender);
|
|
||||||
} else {
|
} else {
|
||||||
Singletons.getModel().getGame().getCombat().addAttacker(c);
|
game.getCombat().addAttacker(c, defs.get(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (remember != null) {
|
if (remember != null) {
|
||||||
Singletons.getModel().getGame().getCardState(sa.getSourceCard()).addRemembered(c);
|
game.getCardState(sa.getSourceCard()).addRemembered(c);
|
||||||
}
|
}
|
||||||
if (sa.getParam("RememberSource") != null) {
|
if (sa.getParam("RememberSource") != null) {
|
||||||
Singletons.getModel().getGame().getCardState(c).addRemembered(host);
|
game.getCardState(c).addRemembered(host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,8 +76,14 @@ public class InputAttack extends InputBase {
|
|||||||
|
|
||||||
List<Card> possibleAttackers = player.getCardsIn(ZoneType.Battlefield);
|
List<Card> possibleAttackers = player.getCardsIn(ZoneType.Battlefield);
|
||||||
for (Card c : Iterables.filter(possibleAttackers, CardPredicates.Presets.CREATURES)) {
|
for (Card c : Iterables.filter(possibleAttackers, CardPredicates.Presets.CREATURES)) {
|
||||||
if (c.hasKeyword("CARDNAME attacks each turn if able.") && CombatUtil.canAttack(c, game.getCombat()) ) {
|
if (!c.hasKeyword("CARDNAME attacks each turn if able."))
|
||||||
|
continue; // do not force
|
||||||
|
|
||||||
|
for(GameEntity def : defenders ) {
|
||||||
|
if( CombatUtil.canAttack(c, def, game.getCombat()) ) {
|
||||||
game.getCombat().addAttacker(c, currentDefender);
|
game.getCombat().addAttacker(c, currentDefender);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,7 +131,7 @@ public class InputAttack extends InputBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Zone zone = game.getZoneOf(card);
|
Zone zone = game.getZoneOf(card);
|
||||||
if (zone.is(ZoneType.Battlefield, player) && CombatUtil.canAttack(card, game.getCombat())) {
|
if (zone.is(ZoneType.Battlefield, player) && CombatUtil.canAttack(card, currentDefender, game.getCombat())) {
|
||||||
|
|
||||||
// TODO add the propaganda code here and remove it in
|
// TODO add the propaganda code here and remove it in
|
||||||
// Phase.nextPhase()
|
// Phase.nextPhase()
|
||||||
|
|||||||
@@ -445,7 +445,7 @@ public class AiAttackController {
|
|||||||
* @param bAssault
|
* @param bAssault
|
||||||
* a boolean.
|
* a boolean.
|
||||||
*/
|
*/
|
||||||
public final void chooseDefender(final Combat c, final boolean bAssault) {
|
public final GameEntity chooseDefender(final Combat c, final Combat gameCombat, final boolean bAssault) {
|
||||||
final List<GameEntity> defs = c.getDefenders();
|
final List<GameEntity> defs = c.getDefenders();
|
||||||
|
|
||||||
// Start with last planeswalker
|
// Start with last planeswalker
|
||||||
@@ -453,25 +453,19 @@ public class AiAttackController {
|
|||||||
|
|
||||||
final GameEntity entity = ai.getMustAttackEntity();
|
final GameEntity entity = ai.getMustAttackEntity();
|
||||||
if (null != entity) {
|
if (null != entity) {
|
||||||
final List<GameEntity> defenders = Singletons.getModel().getGame().getCombat().getDefenders();
|
final List<GameEntity> defenders = gameCombat.getDefenders();
|
||||||
n = defenders.indexOf(entity);
|
n = defenders.indexOf(entity);
|
||||||
if (-1 == n) {
|
if (-1 == n) {
|
||||||
System.out.println("getMustAttackEntity() returned something not in defenders.");
|
System.out.println("getMustAttackEntity() returned something not in defenders.");
|
||||||
c.setCurrentDefenderNumber(0);
|
return defs.get(0);
|
||||||
} else {
|
} else {
|
||||||
c.setCurrentDefenderNumber(n);
|
return entity;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (bAssault) {
|
return defs.get(bAssault ? 0 : n);
|
||||||
c.setCurrentDefenderNumber(0);
|
|
||||||
} else {
|
|
||||||
c.setCurrentDefenderNumber(n);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Getter for the field <code>attackers</code>.
|
* Getter for the field <code>attackers</code>.
|
||||||
@@ -501,11 +495,11 @@ public class AiAttackController {
|
|||||||
|
|
||||||
final boolean bAssault = this.doAssault(ai);
|
final boolean bAssault = this.doAssault(ai);
|
||||||
// Determine who will be attacked
|
// Determine who will be attacked
|
||||||
this.chooseDefender(combat, bAssault);
|
GameEntity defender = this.chooseDefender(combat, game.getCombat(), bAssault);
|
||||||
List<Card> attackersLeft = new ArrayList<Card>(this.attackers);
|
List<Card> attackersLeft = new ArrayList<Card>(this.attackers);
|
||||||
// Attackers that don't really have a choice
|
// Attackers that don't really have a choice
|
||||||
for (final Card attacker : this.attackers) {
|
for (final Card attacker : this.attackers) {
|
||||||
if (!CombatUtil.canAttack(attacker, combat)) {
|
if (!CombatUtil.canAttack(attacker, defender, combat)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
boolean mustAttack = false;
|
boolean mustAttack = false;
|
||||||
@@ -521,7 +515,7 @@ public class AiAttackController {
|
|||||||
if (mustAttack || attacker.getSacrificeAtEOT()
|
if (mustAttack || attacker.getSacrificeAtEOT()
|
||||||
|| attacker.getController().getMustAttackEntity() != null
|
|| attacker.getController().getMustAttackEntity() != null
|
||||||
|| attacker.getSVar("MustAttack").equals("True")) {
|
|| attacker.getSVar("MustAttack").equals("True")) {
|
||||||
combat.addAttacker(attacker);
|
combat.addAttacker(attacker, defender);
|
||||||
attackersLeft.remove(attacker);
|
attackersLeft.remove(attacker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -532,8 +526,8 @@ public class AiAttackController {
|
|||||||
System.out.println("Assault");
|
System.out.println("Assault");
|
||||||
CardLists.sortByPowerDesc(attackersLeft);
|
CardLists.sortByPowerDesc(attackersLeft);
|
||||||
for (Card attacker : attackersLeft) {
|
for (Card attacker : attackersLeft) {
|
||||||
if (CombatUtil.canAttack(attacker, combat) && this.isEffectiveAttacker(ai, attacker, combat)) {
|
if (CombatUtil.canAttack(attacker, defender, combat) && this.isEffectiveAttacker(ai, attacker, combat)) {
|
||||||
combat.addAttacker(attacker);
|
combat.addAttacker(attacker, defender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return combat;
|
return combat;
|
||||||
@@ -566,8 +560,8 @@ public class AiAttackController {
|
|||||||
System.out.println("Exalted");
|
System.out.println("Exalted");
|
||||||
this.aiAggression = 6;
|
this.aiAggression = 6;
|
||||||
for (Card attacker : this.attackers) {
|
for (Card attacker : this.attackers) {
|
||||||
if (CombatUtil.canAttack(attacker, combat) && this.shouldAttack(ai, attacker, this.blockers, combat)) {
|
if (CombatUtil.canAttack(attacker, defender, combat) && this.shouldAttack(ai, attacker, this.blockers, combat)) {
|
||||||
combat.addAttacker(attacker);
|
combat.addAttacker(attacker, defender);
|
||||||
return combat;
|
return combat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -780,6 +774,7 @@ public class AiAttackController {
|
|||||||
|
|
||||||
attackersLeft = this.sortAttackers(attackersLeft);
|
attackersLeft = this.sortAttackers(attackersLeft);
|
||||||
|
|
||||||
|
int iDefender = combat.getDefenders().indexOf(defender);
|
||||||
for (int i = 0; i < attackersLeft.size(); i++) {
|
for (int i = 0; i < attackersLeft.size(); i++) {
|
||||||
final Card attacker = attackersLeft.get(i);
|
final Card attacker = attackersLeft.get(i);
|
||||||
if (this.aiAggression < 5 && !attacker.hasFirstStrike() && !attacker.hasDoubleStrike()
|
if (this.aiAggression < 5 && !attacker.hasFirstStrike() && !attacker.hasDoubleStrike()
|
||||||
@@ -788,16 +783,15 @@ public class AiAttackController {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.shouldAttack(ai, attacker, this.blockers, combat)
|
if (this.shouldAttack(ai, attacker, this.blockers, combat) && CombatUtil.canAttack(attacker, defender, combat)) {
|
||||||
&& CombatUtil.canAttack(attacker, combat)) {
|
combat.addAttacker(attacker, defender);
|
||||||
combat.addAttacker(attacker);
|
|
||||||
// check if attackers are enough to finish the attacked planeswalker
|
// check if attackers are enough to finish the attacked planeswalker
|
||||||
if (combat.getCurrentDefenderNumber() > 0) {
|
if (iDefender > 0) {
|
||||||
Card pw = (Card) combat.getDefender();
|
Card pw = (Card) defender;
|
||||||
final int blockNum = this.blockers.size();
|
final int blockNum = this.blockers.size();
|
||||||
int attackNum = 0;
|
int attackNum = 0;
|
||||||
int damage = 0;
|
int damage = 0;
|
||||||
List<Card> attacking = combat.getAttackersByDefenderSlot(combat.getCurrentDefenderNumber());
|
List<Card> attacking = combat.getAttackersByDefenderSlot(iDefender);
|
||||||
CardLists.sortByPowerAsc(attacking);
|
CardLists.sortByPowerAsc(attacking);
|
||||||
for (Card atta : attacking) {
|
for (Card atta : attacking) {
|
||||||
if (attackNum >= blockNum || !CombatUtil.canBeBlocked(attacker, this.blockers)) {
|
if (attackNum >= blockNum || !CombatUtil.canBeBlocked(attacker, this.blockers)) {
|
||||||
@@ -808,7 +802,8 @@ public class AiAttackController {
|
|||||||
}
|
}
|
||||||
// if enough damage: switch to next planeswalker or player
|
// if enough damage: switch to next planeswalker or player
|
||||||
if (damage >= pw.getCounters(CounterType.LOYALTY)) {
|
if (damage >= pw.getCounters(CounterType.LOYALTY)) {
|
||||||
combat.setCurrentDefenderNumber(combat.getCurrentDefenderNumber() - 1);
|
iDefender--;
|
||||||
|
defender = combat.getDefenders().get(iDefender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -917,7 +917,7 @@ public class ComputerUtil {
|
|||||||
List<Card> attackers = ai.getOpponent().getCreaturesInPlay();
|
List<Card> attackers = ai.getOpponent().getCreaturesInPlay();
|
||||||
for (Card att : attackers) {
|
for (Card att : attackers) {
|
||||||
if (CombatUtil.canAttackNextTurn(att)) {
|
if (CombatUtil.canAttackNextTurn(att)) {
|
||||||
combat.addAttacker(att);
|
combat.addAttacker(att, att.getController().getOpponent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
combat = ComputerUtilBlock.getBlockers(ai, combat, ai.getCreaturesInPlay());
|
combat = ComputerUtilBlock.getBlockers(ai, combat, ai.getCreaturesInPlay());
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ public class Combat {
|
|||||||
// Defenders are the Defending Player + Each controlled Planeswalker
|
// Defenders are the Defending Player + Each controlled Planeswalker
|
||||||
private List<GameEntity> defenders = new ArrayList<GameEntity>();
|
private List<GameEntity> defenders = new ArrayList<GameEntity>();
|
||||||
private Map<GameEntity, List<Card>> defenderMap = new HashMap<GameEntity, List<Card>>();
|
private Map<GameEntity, List<Card>> defenderMap = new HashMap<GameEntity, List<Card>>();
|
||||||
private int currentDefender = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// This Hash keeps track of
|
// This Hash keeps track of
|
||||||
@@ -87,7 +86,6 @@ public class Combat {
|
|||||||
this.defendingDamageMap.clear();
|
this.defendingDamageMap.clear();
|
||||||
|
|
||||||
this.attackingPlayer = null;
|
this.attackingPlayer = null;
|
||||||
this.currentDefender = 0;
|
|
||||||
|
|
||||||
this.initiatePossibleDefenders(Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn().getOpponents());
|
this.initiatePossibleDefenders(Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn().getOpponents());
|
||||||
}
|
}
|
||||||
@@ -125,40 +123,6 @@ public class Combat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* getDefender.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @return a {@link java.lang.Object} object.
|
|
||||||
*/
|
|
||||||
public final GameEntity getDefender() {
|
|
||||||
return this.defenders.get(this.currentDefender);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Setter for the field <code>currentDefender</code>.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param def
|
|
||||||
* a int.
|
|
||||||
*/
|
|
||||||
public final void setCurrentDefenderNumber(final int def) {
|
|
||||||
this.currentDefender = def;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Setter for the field <code>currentDefender</code>.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @return a int.
|
|
||||||
*/
|
|
||||||
public final int getCurrentDefenderNumber() {
|
|
||||||
return this.currentDefender;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Getter for the field <code>defenders</code>.
|
* Getter for the field <code>defenders</code>.
|
||||||
@@ -304,18 +268,6 @@ public class Combat {
|
|||||||
return this.attackerMap.containsKey(c);
|
return this.attackerMap.containsKey(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* addAttacker.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param c
|
|
||||||
* a {@link forge.Card} object.
|
|
||||||
*/
|
|
||||||
public final void addAttacker(final Card c) {
|
|
||||||
this.addAttacker(c, defenders.get(this.currentDefender));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* addAttacker.
|
* addAttacker.
|
||||||
|
|||||||
@@ -765,10 +765,9 @@ public class CombatUtil {
|
|||||||
* a {@link forge.game.phase.Combat} object.
|
* a {@link forge.game.phase.Combat} object.
|
||||||
* @return a boolean.
|
* @return a boolean.
|
||||||
*/
|
*/
|
||||||
public static boolean canAttack(final Card c, final Combat combat) {
|
public static boolean canAttack(final Card c, final GameEntity def, final Combat combat) {
|
||||||
|
|
||||||
int cntAttackers = combat.getAttackers().size();
|
int cntAttackers = combat.getAttackers().size();
|
||||||
final GameEntity def = combat.getDefender();
|
|
||||||
for (final Card card : Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield)) {
|
for (final Card card : Singletons.getModel().getGame().getCardsIn(ZoneType.Battlefield)) {
|
||||||
for (final String keyword : card.getKeyword()) {
|
for (final String keyword : card.getKeyword()) {
|
||||||
if (keyword.equals("No more than two creatures can attack each combat.") && cntAttackers > 1) {
|
if (keyword.equals("No more than two creatures can attack each combat.") && cntAttackers > 1) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.awt.datatransfer.StringSelection;
|
|||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
@@ -191,9 +192,16 @@ public enum CDock implements ICDoc {
|
|||||||
final PhaseHandler ph = game.getPhaseHandler();
|
final PhaseHandler ph = game.getPhaseHandler();
|
||||||
|
|
||||||
if (ph.is(PhaseType.COMBAT_DECLARE_ATTACKERS, player)) {
|
if (ph.is(PhaseType.COMBAT_DECLARE_ATTACKERS, player)) {
|
||||||
|
List<Player> defenders = player.getOpponents();
|
||||||
|
|
||||||
for (Card c : CardLists.filter(player.getCardsIn(ZoneType.Battlefield), Presets.CREATURES)) {
|
for (Card c : CardLists.filter(player.getCardsIn(ZoneType.Battlefield), Presets.CREATURES)) {
|
||||||
if (!c.isAttacking() && CombatUtil.canAttack(c, game.getCombat())) {
|
if (c.isAttacking())
|
||||||
game.getCombat().addAttacker(c);
|
continue;
|
||||||
|
|
||||||
|
for(Player defender : defenders)
|
||||||
|
if( CombatUtil.canAttack(c, defender, game.getCombat())) {
|
||||||
|
game.getCombat().addAttacker(c, defender);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//human.updateObservers();
|
//human.updateObservers();
|
||||||
|
|||||||
Reference in New Issue
Block a user