removed CombatUtil.canAttack method without specifying attack target

This commit is contained in:
Maxmtg
2012-10-23 19:36:47 +00:00
parent 32caaf3ac3
commit 9c7d1fe8b6
13 changed files with 91 additions and 123 deletions

View File

@@ -120,13 +120,6 @@ public final class CardPredicates {
};
}
public static final Predicate<Card> possibleAttackers = new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return (c.isCreature() && CombatUtil.canAttack(c));
}
};
public final static Predicate<Card> isProtectedFrom(final Card source) {
return new Predicate<Card>() {
@Override
@@ -184,13 +177,6 @@ public final class CardPredicates {
};
public static final Predicate<Card> CREATURES_CAN_ATTACK = new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return c.isCreature() && CombatUtil.canAttack(c);
}
};
/**
* a Predicate<Card> to get all enchantments.
*/

View File

@@ -392,11 +392,11 @@ public class AbilityFactoryAttach {
* the logic
* @return the card
*/
public static Card attachGeneralAI(final Player aiPlayer, final SpellAbility sa, final List<Card> list, final boolean mandatory,
public static Card attachGeneralAI(final Player ai, final SpellAbility sa, final List<Card> list, final boolean mandatory,
final Card attachSource, final String logic) {
Player prefPlayer = aiPlayer.getOpponent();
Player prefPlayer = ai.getOpponent();
if ("Pump".equals(logic) || "Animate".equals(logic) ) {
prefPlayer = aiPlayer;
prefPlayer = ai;
}
// Some ChangeType cards are beneficial, and PrefPlayer should be
// changed to represent that
@@ -415,7 +415,7 @@ public class AbilityFactoryAttach {
} else if ("Curse".equals(logic)) {
c = AbilityFactoryAttach.attachAICursePreference(sa, prefList, mandatory, attachSource);
} else if ("Pump".equals(logic)) {
c = AbilityFactoryAttach.attachAIPumpPreference(sa, prefList, mandatory, attachSource);
c = AbilityFactoryAttach.attachAIPumpPreference(ai, sa, prefList, mandatory, attachSource);
} else if ("ChangeType".equals(logic)) {
c = AbilityFactoryAttach.attachAIChangeTypePreference(sa, prefList, mandatory, attachSource);
} else if ("KeepTapped".equals(logic)) {
@@ -688,7 +688,7 @@ public class AbilityFactoryAttach {
* the attach source
* @return the card
*/
public static Card attachAIPumpPreference(final SpellAbility sa, final List<Card> list, final boolean mandatory,
public static Card attachAIPumpPreference(final Player ai, final SpellAbility sa, final List<Card> list, final boolean mandatory,
final Card attachSource) {
// AI For choosing a Card to Pump
Card c = null;
@@ -724,7 +724,7 @@ public class AbilityFactoryAttach {
magnetList = CardLists.filter(magnetList, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return CombatUtil.canAttack(c);
return CombatUtil.canAttack(c, ai.getOpponent());
}
});

View File

@@ -800,6 +800,7 @@ public final class AbilityFactoryDebuff {
// final Card source = sa.getSourceCard();
final Card hostCard = af.getHostCard();
final HashMap<String, String> params = af.getMapParams();
final Player opp = ai.getOpponent();
final boolean chance = r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn()); // to
// prevent
@@ -812,16 +813,17 @@ public final class AbilityFactoryDebuff {
List<Card> comp = ai.getCardsIn(ZoneType.Battlefield);
comp = CardLists.getValidCards(comp, valid, hostCard.getController(), hostCard);
List<Card> human = ai.getOpponent().getCardsIn(ZoneType.Battlefield);
List<Card> human = opp.getCardsIn(ZoneType.Battlefield);
human = CardLists.getValidCards(human, valid, hostCard.getController(), hostCard);
// TODO - add blocking situations here also
// only count creatures that can attack
human = CardLists.filter(human, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return CombatUtil.canAttack(c);
return CombatUtil.canAttack(c, opp);
}
});

View File

@@ -41,6 +41,7 @@ import forge.card.spellability.Target;
import forge.card.trigger.Trigger;
import forge.card.trigger.TriggerHandler;
import forge.card.trigger.TriggerType;
import forge.game.GameState;
import forge.game.phase.CombatUtil;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
@@ -252,39 +253,41 @@ public class AbilityFactoryEffect {
* @return a boolean.
*/
public static boolean effectCanPlayAI(final Player ai, final AbilityFactory af, final SpellAbility sa) {
final GameState game = Singletons.getModel().getGame();
final Random r = MyRandom.getRandom();
final HashMap<String, String> params = af.getMapParams();
boolean randomReturn = r.nextFloat() <= .6667;
final Player opp = ai.getOpponent();
String logic = "";
if (params.containsKey("AILogic")) {
logic = params.get("AILogic");
final PhaseHandler phase = Singletons.getModel().getGame().getPhaseHandler();
final PhaseHandler phase = game.getPhaseHandler();
if (logic.equals("BeginningOfOppTurn")) {
if (phase.isPlayerTurn(ai.getOpponent()) || phase.getPhase().isAfter(PhaseType.DRAW)) {
return false;
}
randomReturn = true;
} else if (logic.equals("Fog")) {
if (Singletons.getModel().getGame().getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) {
if (game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) {
return false;
}
if (!Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
if (!game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
return false;
}
if (Singletons.getModel().getGame().getStack().size() != 0) {
if (game.getStack().size() != 0) {
return false;
}
if (Singletons.getModel().getGame().getPhaseHandler().isPreventCombatDamageThisTurn()) {
if (game.getPhaseHandler().isPreventCombatDamageThisTurn()) {
return false;
}
if (!CombatUtil.lifeInDanger(ai, Singletons.getModel().getGame().getCombat())) {
if (!CombatUtil.lifeInDanger(ai, game.getCombat())) {
return false;
}
final Target tgt = sa.getTarget();
if (tgt != null) {
tgt.resetTargets();
List<Card> list = Singletons.getModel().getGame().getCombat().getAttackerList();
List<Card> list = game.getCombat().getAttackerList();
list = CardLists.getValidCards(list, tgt.getValidTgts(), sa.getActivatingPlayer(), sa.getSourceCard());
list = CardLists.getTargetableCards(list, sa);
Card target = CardFactoryUtil.getBestCreatureAI(list);
@@ -298,13 +301,13 @@ public class AbilityFactoryEffect {
randomReturn = true;
} else if (logic.equals("Evasion")) {
List<Card> comp = ai.getCreaturesInPlay();
List<Card> human = ai.getOpponent().getCreaturesInPlay();
List<Card> human = opp.getCreaturesInPlay();
// only count creatures that can attack or block
comp = CardLists.filter(comp, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return CombatUtil.canAttack(c);
return CombatUtil.canAttack(c, opp);
}
});
human = CardLists.filter(human, new Predicate<Card>() {

View File

@@ -40,6 +40,7 @@ import forge.card.spellability.AbilitySub;
import forge.card.spellability.Spell;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target;
import forge.game.phase.CombatUtil;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.ComputerUtil;
@@ -998,7 +999,7 @@ public class AbilityFactoryPermanentState {
*/
private static boolean tapPrefTargeting(final Player ai, final Card source, final Target tgt, final AbilityFactory af,
final SpellAbility sa, final boolean mandatory) {
Player opp = ai.getOpponent();
final Player opp = ai.getOpponent();
List<Card> tapList = opp.getCardsIn(ZoneType.Battlefield);
tapList = CardLists.filter(tapList, Presets.UNTAPPED);
tapList = CardLists.getValidCards(tapList, tgt.getValidTgts(), source.getController(), source);
@@ -1038,7 +1039,12 @@ public class AbilityFactoryPermanentState {
//Combat has already started
attackers = Singletons.getModel().getGame().getCombat().getAttackerList();
} else {
attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES_CAN_ATTACK);
attackers = CardLists.filter(ai.getCreaturesInPlay(), new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return CombatUtil.canAttack(c, opp);
}
});
attackers.remove(sa.getSourceCard());
}
Predicate<Card> findBlockers = CardPredicates.possibleBlockerForAtLeastOne(attackers);
@@ -1051,7 +1057,12 @@ public class AbilityFactoryPermanentState {
&& phase.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
// Tap creatures possible blockers before combat during AI's turn.
if (Iterables.any(tapList, CardPredicates.Presets.CREATURES)) {
List<Card> creatureList = CardLists.filter(tapList, CardPredicates.Presets.CREATURES_CAN_ATTACK);
List<Card> creatureList = CardLists.filter(tapList, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return c.isCreature() && CombatUtil.canAttack(c, opp);
}
});
choice = CardFactoryUtil.getBestCreatureAI(creatureList);
} else { // no creatures available
choice = CardFactoryUtil.getMostExpensivePermanentAI(tapList, sa, false);

View File

@@ -318,20 +318,20 @@ public class AbilityFactoryPump {
if (!CardUtil.isStackingKeyword(keyword) && card.hasKeyword(keyword)) {
return false;
} else if (keyword.equals("Defender") || keyword.endsWith("CARDNAME can't attack.")) {
if (ph.isPlayerTurn(ai) || !CombatUtil.canAttack(card)
if (ph.isPlayerTurn(ai) || !CombatUtil.canAttack(card, human)
|| (card.getNetCombatDamage() <= 0)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
return false;
}
} else if (keyword.endsWith("CARDNAME can't attack or block.")) {
if (sa.getAbilityFactory().getMapParams().containsKey("UntilYourNextTurn")) {
if (CombatUtil.canAttack(card) || CombatUtil.canBlock(card, true)) {
if (CombatUtil.canAttack(card, human) || CombatUtil.canBlock(card, true)) {
return true;
}
return false;
}
if (ph.isPlayerTurn(human)) {
if (!CombatUtil.canAttack(card)
if (!CombatUtil.canAttack(card, human)
|| (card.getNetCombatDamage() <= 0)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
return false;
@@ -342,7 +342,12 @@ public class AbilityFactoryPump {
return false;
}
List<Card> attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.possibleAttackers);
List<Card> attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return (c.isCreature() && CombatUtil.canAttack(c, human));
}
});
if (!CombatUtil.canBlockAtLeastOne(card, attackers)) {
return false;
}
@@ -353,7 +358,12 @@ public class AbilityFactoryPump {
return false;
}
List<Card> attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), CardPredicates.possibleAttackers);
List<Card> attackers = CardLists.filter(ai.getCardsIn(ZoneType.Battlefield), new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return (c.isCreature() && CombatUtil.canAttack(c, human));
}
});
if (!CombatUtil.canBlockAtLeastOne(card, attackers)) {
return false;
}
@@ -376,7 +386,7 @@ public class AbilityFactoryPump {
return false;
}
} else if (keyword.endsWith("CARDNAME attacks each turn if able.")) {
if (ph.isPlayerTurn(ai) || !CombatUtil.canAttack(card) || !CombatUtil.canBeBlocked(card)
if (ph.isPlayerTurn(ai) || !CombatUtil.canAttack(card, human) || !CombatUtil.canBeBlocked(card)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
return false;
}
@@ -418,7 +428,7 @@ public class AbilityFactoryPump {
|| keyword.contains("Bushido"));
// give evasive keywords to creatures that can or do attack
if (evasive) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking())
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| card.getNetCombatDamage() <= 0
|| cardsCanBlock.isEmpty()) {
@@ -434,7 +444,7 @@ public class AbilityFactoryPump {
return true;
}
Predicate<Card> flyingOrReach = Predicates.or(CardPredicates.hasKeyword("Flying"), CardPredicates.hasKeyword("Reach"));
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking())
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| card.getNetCombatDamage() <= 0 || !Iterables.any(cardsCanBlock, Predicates.not(flyingOrReach))) {
return false;
@@ -447,7 +457,7 @@ public class AbilityFactoryPump {
&& CombatUtil.lifeInDanger(ai, Singletons.getModel().getGame().getCombat())) {
return true;
}
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking())
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| card.getNetCombatDamage() <= 0
|| CardLists.getNotKeyword(cardsCanBlock, "Horsemanship").isEmpty()) {
@@ -474,7 +484,7 @@ public class AbilityFactoryPump {
}
}
} else if (ph.isPlayerTurn(ai) && ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)
&& CombatUtil.canAttack(card)) {
&& CombatUtil.canAttack(card, opp)) {
List<Card> blockers = opp.getCreaturesInPlay();
for (Card blocker : blockers) {
if (CombatUtil.canBlock(card, blocker, combat)
@@ -485,32 +495,32 @@ public class AbilityFactoryPump {
}
return false;
} else if (combatRelevant) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking())
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)
|| (opp.getCreaturesInPlay().size() < 1)
|| cardsCanBlock.isEmpty()) {
return false;
}
} else if (keyword.equals("Double Strike")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking())
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| card.getNetCombatDamage() <= 0
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
return false;
}
} else if (keyword.startsWith("Rampage")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking())
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| cardsCanBlock.size() < 2) {
return false;
}
} else if (keyword.startsWith("Flanking")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking())
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| CardLists.getNotKeyword(cardsCanBlock, "Flanking").isEmpty()) {
return false;
}
} else if (keyword.startsWith("Trample")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking())
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| !CombatUtil.canBeBlocked(card)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| cardsCanBlock.isEmpty()
@@ -525,7 +535,7 @@ public class AbilityFactoryPump {
return true;
}
if ((ph.isPlayerTurn(opp))
|| !(CombatUtil.canAttack(card) || card.isAttacking())
|| !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_BLOCKERS_INSTANT_ABILITY)) {
return false;
}
@@ -548,7 +558,7 @@ public class AbilityFactoryPump {
return false;
}
} else if (keyword.equals("Vigilance")) {
if (ph.isPlayerTurn(opp) || !CombatUtil.canAttack(card)
if (ph.isPlayerTurn(opp) || !CombatUtil.canAttack(card, opp)
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|| CardLists.getNotKeyword(opp.getCreaturesInPlay(), "Defender").size() < 1) {
return false;
@@ -584,7 +594,7 @@ public class AbilityFactoryPump {
return false;
}
} else if (keyword.equals("Islandwalk")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking())
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| card.getNetCombatDamage() <= 0
|| CardLists.getType(opp.getLandsInPlay(), "Island").isEmpty()
@@ -592,7 +602,7 @@ public class AbilityFactoryPump {
return false;
}
} else if (keyword.equals("Swampwalk")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking())
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| card.getNetCombatDamage() <= 0
|| CardLists.getType(opp.getLandsInPlay(), "Swamp").isEmpty()
@@ -600,7 +610,7 @@ public class AbilityFactoryPump {
return false;
}
} else if (keyword.equals("Mountainwalk")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking())
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| card.getNetCombatDamage() <= 0
|| CardLists.getType(opp.getLandsInPlay(), "Mountain").isEmpty()
@@ -608,7 +618,7 @@ public class AbilityFactoryPump {
return false;
}
} else if (keyword.equals("Forestwalk")) {
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card) || card.isAttacking())
if (ph.isPlayerTurn(opp) || !(CombatUtil.canAttack(card, opp) || card.isAttacking())
|| ph.getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY)
|| card.getNetCombatDamage() <= 0
|| CardLists.getType(opp.getLandsInPlay(), "Forest").isEmpty()
@@ -1810,7 +1820,7 @@ public class AbilityFactoryPump {
if (phase.equals(PhaseType.COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY) && c.isAttacking()) {
return true;
}
if (phase.isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && CombatUtil.canAttack(c)) {
if (phase.isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS) && CombatUtil.canAttack(c, opp)) {
return true;
}
return false;

View File

@@ -291,7 +291,7 @@ public class SpellPermanent extends Spell {
}
// Wait for Main2 if possible
if (Singletons.getModel().getGame().getPhaseHandler().is(PhaseType.MAIN1)
&& !ComputerUtil.castPermanentInMain1(this, ai)) {
&& !ComputerUtil.castPermanentInMain1(ai, this)) {
return false;
}
// save cards with flash for surprise blocking

View File

@@ -3,7 +3,6 @@ package forge.card.trigger;
import java.util.HashMap;
import forge.Card;
import forge.card.TriggerReplacementBase;
import forge.card.spellability.SpellAbility;
/**

View File

@@ -546,7 +546,7 @@ public class Combat {
*/
public Player getDefendingPlayerRelatedTo(final Card source) {
Player defender = Singletons.getModel().getGame().getPhaseHandler().getPlayerTurn().getOpponent();
Player defender = getDefenderPlayerByAttacker(source);
Card attacker = source;
if (source.isAura()) {
attacker = source.getEnchantingCard();

View File

@@ -811,31 +811,8 @@ public class CombatUtil {
return false;
}
Player defender = c.getController().getOpponent();
if (combat != null) {
final GameEntity def = combat.getDefender();
if (def instanceof Player) {
defender = (Player) def;
} else {
defender = ((Card) def).getController();
}
}
return CombatUtil.canAttack(c, defender);
}
// can a creature attack at the moment?
/**
* <p>
* canAttack.
* </p>
*
* @param c
* a {@link forge.Card} object.
* @return a boolean.
*/
public static boolean canAttack(final Card c) {
return canAttack(c, c.getController().getOpponent());
final GameEntity def = combat.getDefender();
return CombatUtil.canAttack(c, def instanceof Player ? (Player) def : ((Card) def).getController());
}
// can a creature attack at the moment?

View File

@@ -1768,8 +1768,7 @@ public class ComputerUtil {
*/
public static Combat getAttackers(final Player ai) {
final Player opp = ai.getOpponent();
final ComputerUtilAttack att = new ComputerUtilAttack(ai.getCardsIn(ZoneType.Battlefield),
opp.getCardsIn(ZoneType.Battlefield));
final ComputerUtilAttack att = new ComputerUtilAttack(ai, opp);
return att.getAttackers(ai, opp);
}
@@ -2040,7 +2039,7 @@ public class ComputerUtil {
* a SpellAbility object.
* @return a boolean.
*/
public static boolean castPermanentInMain1(final SpellAbility sa, final Player ai) {
public static boolean castPermanentInMain1(final Player ai, final SpellAbility sa) {
final Card card = sa.getSourceCard();
if (card.getSVar("PlayMain1").equals("TRUE")) {
return true;
@@ -2061,7 +2060,7 @@ public class ComputerUtil {
return true;
}
}
if (card.isEquipment() && buffedcard.isCreature() && CombatUtil.canAttack(buffedcard)) {
if (card.isEquipment() && buffedcard.isCreature() && CombatUtil.canAttack(buffedcard, ai.getOpponent())) {
return true;
}
if (card.isCreature() && buffedcard.hasKeyword("Soulbond") && !buffedcard.isPaired()) {

View File

@@ -26,7 +26,6 @@ import com.google.common.base.Predicate;
import forge.Card;
import forge.CardLists;
import forge.CardPredicates;
import forge.Counters;
import forge.GameEntity;
import forge.Singletons;
@@ -74,15 +73,16 @@ public class ComputerUtilAttack {
* @param possibleBlockers
* a {@link forge.CardList} object.
*/
public ComputerUtilAttack(final List<Card> possibleAttackers, final List<Card> possibleBlockers) {
this.humanList = new ArrayList<Card>(possibleBlockers);
this.humanList = CardLists.filter(this.humanList, CardPredicates.Presets.CREATURES);
public ComputerUtilAttack(final Player ai, final Player human) {
this.humanList = human.getCreaturesInPlay();
this.computerList = ai.getCreaturesInPlay();
this.computerList = new ArrayList<Card>(possibleAttackers);
this.computerList = CardLists.filter(this.computerList, CardPredicates.Presets.CREATURES);
this.attackers = new ArrayList<Card>();
for(Card c : computerList)
if (CombatUtil.canAttack(c, human))
attackers.add(c);
this.attackers = this.getPossibleAttackers(possibleAttackers);
this.blockers = this.getPossibleBlockers(possibleBlockers, this.attackers);
this.blockers = this.getPossibleBlockers(humanList, this.attackers);
} // constructor
/**
@@ -157,26 +157,6 @@ public class ComputerUtilAttack {
return false;
}
/**
* <p>
* getPossibleAttackers.
* </p>
*
* @param in
* a {@link forge.CardList} object.
* @return a {@link forge.CardList} object.
*/
public final List<Card> getPossibleAttackers(final List<Card> in) {
List<Card> list = new ArrayList<Card>(in);
list = CardLists.filter(list, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return CombatUtil.canAttack(c);
}
});
return list;
} // getPossibleAttackers()
/**
* <p>
* getPossibleBlockers.

View File

@@ -164,6 +164,7 @@ public class QuestWinLose extends ControlWinLose {
// TODO: We don't have a enum for difficulty?
int difficulty = qData.getAchievements().getDifficulty();
final int wins = qData.getAchievements().getWin();
// Win case
if (this.wonMatch) {
@@ -189,17 +190,17 @@ public class QuestWinLose extends ControlWinLose {
if ((wins > 0) && ((wins % 80) == 0)) {
this.awardJackpot();
}
// Unlock new sets?
if (wins % 50 == 49) {
unlockSets();
}
}
// Lose case
else {
this.penalizeLoss();
}
// Unlock new sets?
if (this.wonMatch && wins % 50 == 49) {
unlockSets();
}
// Grant booster on a win, or on a loss in easy mode
if (this.wonMatch || difficulty == 0) {
final int outcome = this.wonMatch ? wins : qData.getAchievements().getLost();