- Fixed issue with AI retargeting for Optional triggers

- SpellAbilities will now (again) stay on the stack until they are finished resolving, allowing ChangeTarget spells to redirect Counterspells to themselves
This commit is contained in:
Sol
2013-04-20 01:56:12 +00:00
parent c32830f6a1
commit 9611a40e1d
2 changed files with 18 additions and 18 deletions

View File

@@ -1,6 +1,5 @@
package forge.card.trigger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -16,6 +15,7 @@ import forge.card.spellability.ISpellAbility;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityRestriction;
import forge.card.spellability.Target;
import forge.card.spellability.TargetChoices;
import forge.game.GameState;
import forge.game.ai.ComputerUtil;
import forge.game.player.AIPlayer;
@@ -352,10 +352,7 @@ public class WrappedAbility extends Ability implements ISpellAbility {
public void resolve() {
final GameState game = Singletons.getModel().getGame();
if (!(regtrig instanceof TriggerAlways)) {
// State triggers
// don't do the whole
// "Intervening If"
// thing.
// State triggers don't have "Intervening If"
if (!regtrig.requirementsCheck()) {
return;
}
@@ -390,20 +387,23 @@ public class WrappedAbility extends Ability implements ISpellAbility {
//TODO: The only card with an optional delayed trigger is Shirei, Shizo's Caretaker,
// needs to be expanded when a more difficult cards comes up
} else {
ArrayList<Object> tgts = null;
// make sure the targets won't change
if (sa.getTarget() != null && sa.getTarget().getTargetChoices() != null) {
tgts = new ArrayList<Object>(sa.getTarget().getTargetChoices().getTargets());
// Store/replace target choices more properly to get this SA cleared.
Target tgt = sa.getTarget();
TargetChoices tc = null;
boolean storeChoices = tgt != null && tgt.getTargetChoices() != null;
if (storeChoices) {
tc = tgt.getTargetChoices();
tgt.resetTargets();
}
// This isn't quite right, but better than canPlayAI
// There is no way this doTrigger here will have the same target as stored above
// So it's possible it's making a different decision here than will actually happen
if (!sa.doTrigger(this.isMandatory(), (AIPlayer) decider)) {
return;
}
if (sa.getTarget() != null && sa.getTarget().getTargetChoices() != null) {
for (Object tgt : tgts) {
sa.getTarget().getTargetChoices().clear();
sa.getTarget().getTargetChoices().addTarget(tgt);
}
if (storeChoices) {
tgt.resetTargets();
tgt.setTargetChoices(tc);
}
}
}

View File

@@ -594,8 +594,8 @@ public class MagicStack extends MyObservable {
// The SpellAbility isn't removed from the Stack until it finishes resolving
// temporarily reverted removing SAs after resolution
//final SpellAbility sa = this.top();
final SpellAbility sa = this.pop();
final SpellAbility sa = this.top();
//final SpellAbility sa = this.pop();
// ActivePlayer gains priority first after Resolve
game.getPhaseHandler().resetPriority();
@@ -727,7 +727,7 @@ public class MagicStack extends MyObservable {
this.removeCardFromStack(sa, fizzle);
// SpellAbility is removed from the stack here
// temporarily removed removing SA after resolution
//this.remove(sa);
this.remove(sa);
// After SA resolves we have to do a handful of things
this.setResolving(false);