Added AIPlayer parameter to doTrigger and chkAIDrawback

This commit is contained in:
Maxmtg
2013-02-05 19:18:31 +00:00
parent 8ba3ad5b90
commit 58fa5b34ea
20 changed files with 62 additions and 47 deletions

View File

@@ -68,7 +68,7 @@ public class CommonAbility extends AbilityActivated {
}
@Override
public boolean doTrigger(final boolean mandatory) {
return ai.doTriggerAI((AIPlayer)this.getActivatingPlayer(), this, mandatory);
public boolean doTrigger(final boolean mandatory, AIPlayer aiPlayer) {
return ai.doTriggerAI(aiPlayer, this, mandatory);
}
}

View File

@@ -74,20 +74,20 @@ public class CommonDrawback extends AbilitySub {
}
@Override
public boolean chkAIDrawback() {
if (!ai.chkAIDrawback(this, (AIPlayer)getActivatingPlayer())) {
public boolean chkAIDrawback(AIPlayer aiPlayer) {
if (!ai.chkAIDrawback(this, aiPlayer)) {
return false;
}
final AbilitySub subAb = getSubAbility();
if (subAb != null && !subAb.chkAIDrawback()) {
if (subAb != null && !subAb.chkAIDrawback(aiPlayer)) {
return false;
}
return true;
}
@Override
public boolean doTrigger(final boolean mandatory) {
return ai.doTriggerAI((AIPlayer)getActivatingPlayer(), this, mandatory);
public boolean doTrigger(final boolean mandatory, AIPlayer aiPlayer) {
return ai.doTriggerAI(aiPlayer, this, mandatory);
}
}

View File

@@ -10,7 +10,7 @@ public abstract class SpellAiLogic {
public final boolean canPlayAIWithSubs(final AIPlayer aiPlayer, final SpellAbility sa) {
final AbilitySub subAb = sa.getSubAbility();
if (subAb != null && !subAb.chkAIDrawback()) {
if (subAb != null && !subAb.chkAIDrawback(aiPlayer)) {
return false;
}
return canPlayAI(aiPlayer, sa);
@@ -32,7 +32,7 @@ public abstract class SpellAiLogic {
return false;
}
final AbilitySub subAb = sa.getSubAbility();
if (subAb != null && !subAb.chkAIDrawback() && !mandatory) {
if (subAb != null && !subAb.chkAIDrawback(aiPlayer) && !mandatory) {
return false;
}
return true;

View File

@@ -160,7 +160,7 @@ public class ChangeZoneAi extends SpellAiLogic {
* a {@link forge.card.spellability.SpellAbility} object.
* @return a boolean.
*/
private static boolean hiddenOriginCanPlayAI(final Player ai, final SpellAbility sa) {
private static boolean hiddenOriginCanPlayAI(final AIPlayer ai, final SpellAbility sa) {
// Fetching should occur fairly often as it helps cast more spells, and
// have access to more mana
final Cost abCost = sa.getPayCosts();
@@ -296,7 +296,7 @@ public class ChangeZoneAi extends SpellAiLogic {
final AbilitySub subAb = sa.getSubAbility();
if (subAb != null) {
chance &= subAb.chkAIDrawback();
chance &= subAb.chkAIDrawback(ai);
}
return chance;
@@ -530,7 +530,7 @@ public class ChangeZoneAi extends SpellAiLogic {
* a {@link forge.card.spellability.SpellAbility} object.
* @return a boolean.
*/
private static boolean knownOriginCanPlayAI(final Player ai, final SpellAbility sa) {
private static boolean knownOriginCanPlayAI(final AIPlayer ai, final SpellAbility sa) {
// Retrieve either this card, or target Cards in Graveyard
final Cost abCost = sa.getPayCosts();
final Card source = sa.getSourceCard();
@@ -630,7 +630,7 @@ public class ChangeZoneAi extends SpellAiLogic {
final AbilitySub subAb = sa.getSubAbility();
if (subAb != null) {
chance &= subAb.chkAIDrawback();
chance &= subAb.chkAIDrawback(ai);
}
return (chance);
@@ -647,7 +647,7 @@ public class ChangeZoneAi extends SpellAiLogic {
* a {@link forge.card.spellability.SpellAbility} object.
* @return a boolean.
*/
private static boolean knownOriginPlayDrawbackAI(final Player aiPlayer, final SpellAbility sa) {
private static boolean knownOriginPlayDrawbackAI(final AIPlayer aiPlayer, final SpellAbility sa) {
if (sa.getTarget() == null) {
return true;
}
@@ -668,7 +668,7 @@ public class ChangeZoneAi extends SpellAiLogic {
* a boolean.
* @return a boolean.
*/
private static boolean isPreferredTarget(final Player ai, final SpellAbility sa,
private static boolean isPreferredTarget(final AIPlayer ai, final SpellAbility sa,
final boolean mandatory) {
final Card source = sa.getSourceCard();
final ZoneType origin = ZoneType.listValueOf(sa.getParam("Origin")).get(0);
@@ -1027,7 +1027,7 @@ public class ChangeZoneAi extends SpellAiLogic {
* a boolean.
* @return a boolean.
*/
private static boolean knownOriginTriggerAI(final Player ai, final SpellAbility sa,
private static boolean knownOriginTriggerAI(final AIPlayer ai, final SpellAbility sa,
final boolean mandatory) {
if (sa.getTarget() == null) {

View File

@@ -33,7 +33,7 @@ public class CharmAi extends SpellAiLogic {
return r.nextFloat() <= Math.pow(.6667, sa.getActivationsThisTurn());
}
public static List<AbilitySub> chooseOptionsAi(final Player ai, boolean playNow, List<AbilitySub> choices, int num, int min) {
public static List<AbilitySub> chooseOptionsAi(final AIPlayer ai, boolean playNow, List<AbilitySub> choices, int num, int min) {
List<AbilitySub> chosenList = new ArrayList<AbilitySub>();
for (int i = 0; i < num; i++) {
@@ -46,7 +46,7 @@ public class CharmAi extends SpellAiLogic {
playNow = true;
break;
}
if ((playNow || i < num - 1) && sub.doTrigger(false)) {
if ((playNow || i < num - 1) && sub.doTrigger(false, ai)) {
thisPick = (AbilitySub) sub;
choices.remove(sub);
break;

View File

@@ -16,7 +16,7 @@ public class DelayedTriggerAi extends SpellAiLogic {
trigsa.setActivatingPlayer(ai);
if (trigsa instanceof AbilitySub) {
return ((AbilitySub) trigsa).chkAIDrawback();
return ((AbilitySub) trigsa).chkAIDrawback(ai);
} else {
return trigsa.canPlayAI();
}
@@ -29,9 +29,9 @@ public class DelayedTriggerAi extends SpellAiLogic {
trigsa.setActivatingPlayer(ai);
if (!sa.hasParam("OptionalDecider")) {
return trigsa.doTrigger(true);
return trigsa.doTrigger(true, ai);
} else {
return trigsa.doTrigger(!sa.getParam("OptionalDecider").equals("You"));
return trigsa.doTrigger(!sa.getParam("OptionalDecider").equals("You"), ai);
}
}

View File

@@ -8,6 +8,7 @@ import forge.card.abilityfactory.SpellEffect;
import forge.card.abilityfactory.ai.CharmAi;
import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
import forge.gui.GuiChoose;
@@ -70,7 +71,7 @@ public class CharmEffect extends SpellEffect {
chosen.add(a);
}
} else {
chosen = CharmAi.chooseOptionsAi(activator, sa.isTrigger(), choices, num, min);
chosen = CharmAi.chooseOptionsAi((AIPlayer)activator, sa.isTrigger(), choices, num, min);
}
chainAbilities(sa, chosen);

View File

@@ -9,6 +9,7 @@ import forge.card.abilityfactory.AbilityFactory;
import forge.card.abilityfactory.SpellEffect;
import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
import forge.game.zone.PlayerZone;
import forge.game.zone.ZoneType;
@@ -64,7 +65,7 @@ public class PeekAndRevealEffect extends SpellEffect {
if (doReveal && revealOptional) {
// If
AbilitySub subAb = sa.getSubAbility();
doReveal = subAb != null && subAb.chkAIDrawback();
doReveal = subAb != null && subAb.chkAIDrawback((AIPlayer)peekingPlayer);
}
}

View File

@@ -76,6 +76,7 @@ import forge.game.ai.ComputerUtilCost;
import forge.game.event.TokenCreatedEvent;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
import forge.game.zone.PlayerZone;
import forge.game.zone.Zone;
@@ -3733,7 +3734,7 @@ public class CardFactoryUtil {
@Override
public boolean canPlayAI() {
if (!SpellPermanent.checkETBEffects(card, this.getActivatingPlayer())) {
if (!SpellPermanent.checkETBEffects(card, (AIPlayer) this.getActivatingPlayer())) {
return false;
}
return super.canPlayAI();

View File

@@ -31,6 +31,7 @@ import forge.card.abilityfactory.AbilityFactory;
import forge.card.cardfactory.CardFactoryUtil;
import forge.card.spellability.SpellAbility;
import forge.game.phase.PhaseType;
import forge.game.player.AIPlayer;
import forge.game.zone.ZoneType;
import forge.util.Expressions;
@@ -67,9 +68,10 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
* Ai should run.
*
* @param sa the sa
* @param ai
* @return true, if successful
*/
public final boolean aiShouldRun(final SpellAbility sa) {
public final boolean aiShouldRun(final SpellAbility sa, AIPlayer ai) {
if (this.mapParams.containsKey("AICheckSVar")) {
System.out.println("aiShouldRun?" + sa);
final String svarToCheck = this.mapParams.get("AICheckSVar");
@@ -102,7 +104,7 @@ public abstract class ReplacementEffect extends TriggerReplacementBase {
if (Expressions.compare(left, comparator, compareTo)) {
return true;
}
} else if (sa != null && sa.doTrigger(false)) {
} else if (sa != null && sa.doTrigger(false, ai)) {
return true;
}

View File

@@ -28,6 +28,7 @@ import forge.card.abilityfactory.AbilityFactory;
import forge.card.spellability.SpellAbility;
import forge.game.GameState;
import forge.game.ai.ComputerUtil;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
import forge.gui.GuiChoose;
@@ -222,7 +223,7 @@ public class ReplacementHandler {
}
} else {
// AI-logic
if (!replacementEffect.aiShouldRun(effectSA)) {
if (!replacementEffect.aiShouldRun(effectSA, (AIPlayer)optDecider)) {
return ReplacementResult.NotReplaced;
}
}

View File

@@ -18,6 +18,7 @@
package forge.card.spellability;
import forge.Card;
import forge.game.player.AIPlayer;
/**
* <p>
@@ -59,16 +60,17 @@ public abstract class AbilitySub extends SpellAbility implements java.io.Seriali
* <p>
* chkAI_Drawback.
* </p>
* @param ai TODO
*
* @return a boolean.
*/
public abstract boolean chkAIDrawback();
public abstract boolean chkAIDrawback(AIPlayer ai);
public abstract AbilitySub getCopy();
/** {@inheritDoc} */
@Override
public abstract boolean doTrigger(boolean mandatory);
public abstract boolean doTrigger(boolean mandatory, AIPlayer ai);
/**
* <p>

View File

@@ -34,6 +34,7 @@ import forge.card.abilityfactory.ApiType;
import forge.card.cost.Cost;
import forge.card.mana.Mana;
import forge.control.input.Input;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
//only SpellAbility can go on the stack
@@ -220,9 +221,10 @@ public abstract class SpellAbility implements ISpellAbility {
*
* @param mandatory
* a boolean.
* @param ai TODO
* @return a boolean.
*/
public boolean doTrigger(final boolean mandatory) {
public boolean doTrigger(final boolean mandatory, AIPlayer ai) {
return false;
}

View File

@@ -45,6 +45,7 @@ import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCost;
import forge.game.ai.ComputerUtilMana;
import forge.game.phase.PhaseType;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
import forge.view.ButtonUtil;
@@ -326,7 +327,7 @@ public class SpellPermanent extends Spell {
if (mandatory) {
return true;
}
final Player ai = getActivatingPlayer();
final AIPlayer ai = (AIPlayer) getActivatingPlayer();
final Card card = this.getSourceCard();
SpellManaCost mana = this.getPayCosts().getTotalMana();
final Cost cost = this.getPayCosts();
@@ -407,11 +408,11 @@ public class SpellPermanent extends Spell {
return checkETBEffects(card, sa, api, null);
}
public static boolean checkETBEffects(final Card card, final Player ai) {
public static boolean checkETBEffects(final Card card, final AIPlayer ai) {
return checkETBEffects(card, null, null, ai);
}
private static boolean checkETBEffects(final Card card, final SpellAbility sa, final ApiType api, final Player ai) {
private static boolean checkETBEffects(final Card card, final SpellAbility sa, final ApiType api, final AIPlayer ai) {
boolean rightapi = false;
if (card.isCreature()
@@ -501,7 +502,7 @@ public class SpellPermanent extends Spell {
// Run non-mandatory trigger.
// These checks only work if the Executing SpellAbility is an
// Ability_Sub.
if ((exSA instanceof AbilitySub) && !exSA.doTrigger(false)) {
if ((exSA instanceof AbilitySub) && !exSA.doTrigger(false, ai)) {
// AI would not run this trigger if given the chance
// if trigger is mandatory, return false
@@ -583,7 +584,7 @@ public class SpellPermanent extends Spell {
// ETBReplacement uses overriding abilities.
// These checks only work if the Executing SpellAbility is an
// Ability_Sub.
if (exSA != null && (exSA instanceof AbilitySub) && !exSA.doTrigger(false)) {
if (exSA != null && (exSA instanceof AbilitySub) && !exSA.doTrigger(false, ai)) {
return false;
}
}

View File

@@ -38,6 +38,7 @@ import forge.game.GameState;
import forge.game.GlobalRuleChange;
import forge.game.ai.ComputerUtil;
import forge.game.phase.PhaseType;
import forge.game.player.AIPlayer;
//import forge.util.TextUtil;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
@@ -545,7 +546,7 @@ public class TriggerHandler {
if (wrapperAbility.getActivatingPlayer().isHuman()) {
game.getAction().playSpellAbilityNoStack(wrapperAbility, false);
} else {
wrapperAbility.doTrigger(isMandatory);
wrapperAbility.doTrigger(isMandatory, (AIPlayer)wrapperAbility.getActivatingPlayer());
ComputerUtil.playNoStack(wrapperAbility.getActivatingPlayer(), wrapperAbility, game);
}
} else {

View File

@@ -20,6 +20,7 @@ import forge.card.spellability.Target;
import forge.control.input.Input;
import forge.game.GameState;
import forge.game.ai.ComputerUtil;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
import forge.gui.GuiDialog;
@@ -150,8 +151,8 @@ public class WrappedAbility extends Ability implements ISpellAbility {
}
@Override
public boolean doTrigger(final boolean mandatory) {
return sa.doTrigger(mandatory);
public boolean doTrigger(final boolean mandatory, AIPlayer ai) {
return sa.doTrigger(mandatory, ai);
}
@Override
@@ -497,7 +498,7 @@ public class WrappedAbility extends Ability implements ISpellAbility {
tgts = new ArrayList<Object>(sa.getTarget().getTargetChoices().getTargets());
}
// This isn't quite right, but better than canPlayAI
if (!sa.doTrigger(this.isMandatory())) {
if (!sa.doTrigger(this.isMandatory(), (AIPlayer)decider)) {
return;
}
if (sa.getTarget() != null && sa.getTarget().getTargetChoices() != null) {

View File

@@ -33,6 +33,7 @@ import forge.card.spellability.SpellAbility;
import forge.game.GameState;
import forge.game.GameType;
import forge.game.ai.ComputerUtil;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
import forge.game.zone.Zone;
import forge.game.zone.ZoneType;
@@ -158,7 +159,7 @@ public class InputMulligan extends Input {
final SpellAbility effect = af.getAbility(c.getSVar(effName), c);
// Is there a better way for the AI to decide this?
if (effect.doTrigger(false)) {
if (effect.doTrigger(false, (AIPlayer)p)) {
GuiDialog.message("Computer reveals " + c.getName() + "(" + c.getUniqueNumber() + ").");
ComputerUtil.playNoStack(p, effect, game);
}

View File

@@ -67,7 +67,7 @@ public class ComputerUtilMana {
}
// get map of mana abilities
final Map<String, List<SpellAbility>> manaAbilityMap = ComputerUtilMana.mapManaSources(ai, checkPlayable);
final Map<String, List<SpellAbility>> manaAbilityMap = ComputerUtilMana.mapManaSources((AIPlayer) ai, checkPlayable);
// initialize ArrayList list for mana needed
final List<List<SpellAbility>> partSources = new ArrayList<List<SpellAbility>>();
final List<Integer> partPriority = new ArrayList<Integer>();
@@ -456,7 +456,7 @@ public class ComputerUtilMana {
* @param checkPlayable
* @return a {@link forge.CardList} object.
*/
private static List<Card> getAvailableMana(final Player ai, final boolean checkPlayable) {
private static List<Card> getAvailableMana(final AIPlayer ai, final boolean checkPlayable) {
final GameState game = Singletons.getModel().getGame();
final List<Card> list = ai.getCardsIn(ZoneType.Battlefield);
final List<Card> manaSources = CardLists.filter(list, new Predicate<Card>() {
@@ -528,7 +528,7 @@ public class ComputerUtilMana {
// don't use abilities with dangerous drawbacks
if (m.getSubAbility() != null && !card.getName().equals("Pristine Talisman")) {
if (!m.getSubAbility().chkAIDrawback()) {
if (!m.getSubAbility().chkAIDrawback(ai)) {
continue;
}
needsLimitedResources = true; // TODO: check for good
@@ -582,7 +582,7 @@ public class ComputerUtilMana {
* @param checkPlayable TODO
* @return HashMap<String, List<Card>>
*/
private static Map<String, List<SpellAbility>> mapManaSources(final Player ai, boolean checkPlayable) {
private static Map<String, List<SpellAbility>> mapManaSources(final AIPlayer ai, boolean checkPlayable) {
final Map<String, List<SpellAbility>> manaMap = new HashMap<String, List<SpellAbility>>();
final List<SpellAbility> whiteSources = new ArrayList<SpellAbility>();
@@ -610,7 +610,7 @@ public class ComputerUtilMana {
// don't use abilities with dangerous drawbacks
if (m.getSubAbility() != null) {
if (!m.getSubAbility().chkAIDrawback()) {
if (!m.getSubAbility().chkAIDrawback(ai)) {
continue;
}
}

View File

@@ -2542,7 +2542,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
return false;
}
} else if (property.equals("attackedBySourceThisCombat")) {
if (!this.equals(Singletons.getModel().getGame().getCombat().getDefenderPlayerByAttacker(source))) {
if (!this.equals(game.getCombat().getDefenderPlayerByAttacker(source))) {
return false;
}
} else if (property.startsWith("wasDealtDamageThisTurn")) {

View File

@@ -56,6 +56,7 @@ import forge.game.ai.ComputerUtil;
import forge.game.ai.ComputerUtilCost;
import forge.game.event.SpellResolvedEvent;
import forge.game.phase.PhaseType;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
import forge.gui.GuiChoose;
import forge.gui.framework.EDocID;
@@ -1342,7 +1343,7 @@ public class MagicStack extends MyObservable {
if (activePlayer.isComputer()) {
for (final SpellAbility sa : activePlayerSAs) {
sa.doTrigger(sa.isMandatory());
sa.doTrigger(sa.isMandatory(), (AIPlayer) activePlayer);
ComputerUtil.playStack(sa, activePlayer, game);
}
} else {