1
0
Fork 0
mirror of https://github.com/correl/mage.git synced 2025-04-10 09:11:04 -09:00

* Fixed a problem that optional effects could produce IndexOutOfBoundsExceptions.

This commit is contained in:
LevelX2 2016-11-19 12:47:20 +01:00
parent 8e42660e33
commit ca25cc4679
5 changed files with 19 additions and 12 deletions

View file

@ -31,6 +31,7 @@ import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.constants.AbilityType; import mage.constants.AbilityType;
import mage.constants.Outcome;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
@ -88,7 +89,7 @@ public abstract class TriggeredAbilityImpl extends AbilityImpl implements Trigge
MageObject object = game.getObject(getSourceId()); MageObject object = game.getObject(getSourceId());
Player player = game.getPlayer(this.getControllerId()); Player player = game.getPlayer(this.getControllerId());
if (player != null && object != null) { if (player != null && object != null) {
if (!player.chooseUse(getEffects().get(0).getOutcome(), this.getRule(object.getLogName()), this, game)) { if (!player.chooseUse(getEffects().isEmpty() ? Outcome.Detriment : getEffects().get(0).getOutcome(), this.getRule(object.getLogName()), this, game)) {
return false; return false;
} }
} else { } else {

View file

@ -32,6 +32,7 @@ import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
/** /**
@ -53,7 +54,7 @@ public class CreateDelayedTriggeredAbilityEffect extends OneShotEffect {
} }
public CreateDelayedTriggeredAbilityEffect(DelayedTriggeredAbility ability, boolean copyTargets, boolean initAbility) { public CreateDelayedTriggeredAbilityEffect(DelayedTriggeredAbility ability, boolean copyTargets, boolean initAbility) {
super(ability.getEffects().get(0).getOutcome()); super(ability.getEffects().isEmpty() ? Outcome.Detriment : ability.getEffects().get(0).getOutcome());
this.ability = ability; this.ability = ability;
this.copyTargets = copyTargets; this.copyTargets = copyTargets;
this.initAbility = initAbility; this.initAbility = initAbility;

View file

@ -25,13 +25,13 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.abilities.effects.common; package mage.abilities.effects.common;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.SpecialAction; import mage.abilities.SpecialAction;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game; import mage.game.Game;
/** /**
@ -43,7 +43,7 @@ public class CreateSpecialActionEffect extends OneShotEffect {
protected SpecialAction action; protected SpecialAction action;
public CreateSpecialActionEffect(SpecialAction action) { public CreateSpecialActionEffect(SpecialAction action) {
super(action.getEffects().get(0).getOutcome()); super(action.getEffects().isEmpty() ? Outcome.Detriment : action.getEffects().get(0).getOutcome());
this.action = action; this.action = action;
} }

View file

@ -54,6 +54,7 @@ import mage.constants.AbilityType;
import mage.constants.AbilityWord; import mage.constants.AbilityWord;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.EffectType; import mage.constants.EffectType;
import mage.constants.Outcome;
import mage.constants.Zone; import mage.constants.Zone;
import mage.constants.ZoneDetail; import mage.constants.ZoneDetail;
import mage.game.Game; import mage.game.Game;
@ -194,7 +195,7 @@ public class StackAbility extends StackObjImpl implements Ability {
public ObjectColor getColor(Game game) { public ObjectColor getColor(Game game) {
return emptyColor; return emptyColor;
} }
@Override @Override
public ObjectColor getFrameColor(Game game) { public ObjectColor getFrameColor(Game game) {
return ability.getSourceObject(game).getFrameColor(game); return ability.getSourceObject(game).getFrameColor(game);
@ -220,7 +221,7 @@ public class StackAbility extends StackObjImpl implements Ability {
public MageInt getToughness() { public MageInt getToughness() {
return MageInt.EmptyMageInt; return MageInt.EmptyMageInt;
} }
@Override @Override
public int getStartingLoyalty() { public int getStartingLoyalty() {
return 0; return 0;
@ -590,9 +591,10 @@ public class StackAbility extends StackObjImpl implements Ability {
game.getStack().push(newStackAbility); game.getStack().push(newStackAbility);
if (chooseNewTargets && newAbility.getTargets().size() > 0) { if (chooseNewTargets && newAbility.getTargets().size() > 0) {
Player controller = game.getPlayer(newControllerId); Player controller = game.getPlayer(newControllerId);
if (controller.chooseUse(newAbility.getEffects().get(0).getOutcome(), "Choose new targets?", source, game)) { Outcome outcome = newAbility.getEffects().isEmpty() ? Outcome.Detriment : newAbility.getEffects().get(0).getOutcome();
if (controller.chooseUse(outcome, "Choose new targets?", source, game)) {
newAbility.getTargets().clearChosen(); newAbility.getTargets().clearChosen();
newAbility.getTargets().chooseTargets(newAbility.getEffects().get(0).getOutcome(), newControllerId, newAbility, false, game); newAbility.getTargets().chooseTargets(outcome, newControllerId, newAbility, false, game);
} }
} }
game.fireEvent(new GameEvent(GameEvent.EventType.COPIED_STACKOBJECT, newStackAbility.getId(), this.getId(), newControllerId)); game.fireEvent(new GameEvent(GameEvent.EventType.COPIED_STACKOBJECT, newStackAbility.getId(), this.getId(), newControllerId));

View file

@ -163,8 +163,9 @@ public abstract class StackObjImpl implements StackObject {
for (UUID targetId : target.getTargets()) { for (UUID targetId : target.getTargets()) {
String targetNames = getNamesOftargets(targetId, game); String targetNames = getNamesOftargets(targetId, game);
// change the target? // change the target?
Outcome outcome = mode.getEffects().isEmpty() ? Outcome.Detriment : mode.getEffects().get(0).getOutcome();
if (targetNames != null if (targetNames != null
&& (forceChange || targetController.chooseUse(mode.getEffects().get(0).getOutcome(), "Change this target: " + targetNames + "?", ability, game))) { && (forceChange || targetController.chooseUse(outcome, "Change this target: " + targetNames + "?", ability, game))) {
Set<UUID> possibleTargets = target.possibleTargets(this.getSourceId(), getControllerId(), game); Set<UUID> possibleTargets = target.possibleTargets(this.getSourceId(), getControllerId(), game);
// choose exactly one other target - already targeted objects are not counted // choose exactly one other target - already targeted objects are not counted
if (forceChange && possibleTargets != null && possibleTargets.size() > 1) { // controller of spell must be used (e.g. TargetOpponent) if (forceChange && possibleTargets != null && possibleTargets.size() > 1) { // controller of spell must be used (e.g. TargetOpponent)
@ -176,7 +177,7 @@ public abstract class StackObjImpl implements StackObject {
iteration++; iteration++;
newTarget.clearChosen(); newTarget.clearChosen();
newTarget.chooseTarget(mode.getEffects().get(0).getOutcome(), getControllerId(), ability, game); newTarget.chooseTarget(outcome, getControllerId(), ability, game);
// check target restriction // check target restriction
if (newTarget.getFirstTarget() != null && filterNewTarget != null) { if (newTarget.getFirstTarget() != null && filterNewTarget != null) {
Permanent newTargetPermanent = game.getPermanent(newTarget.getFirstTarget()); Permanent newTargetPermanent = game.getPermanent(newTarget.getFirstTarget());
@ -203,7 +204,7 @@ public abstract class StackObjImpl implements StackObject {
do { do {
again = false; again = false;
tempTarget.clearChosen(); tempTarget.clearChosen();
if (!tempTarget.chooseTarget(mode.getEffects().get(0).getOutcome(), getControllerId(), ability, game)) { if (!tempTarget.chooseTarget(outcome, getControllerId(), ability, game)) {
if (targetController.chooseUse(Outcome.Benefit, "No target object selected. Reset to original target?", ability, game)) { if (targetController.chooseUse(Outcome.Benefit, "No target object selected. Reset to original target?", ability, game)) {
// use previous target no target was selected // use previous target no target was selected
newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false); newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false);
@ -211,7 +212,8 @@ public abstract class StackObjImpl implements StackObject {
again = true; again = true;
} }
} else // if possible add the alternate Target - it may not be included in the old definition nor in the already selected targets of the new definition } else // if possible add the alternate Target - it may not be included in the old definition nor in the already selected targets of the new definition
if (newTarget.getTargets().contains(tempTarget.getFirstTarget()) || target.getTargets().contains(tempTarget.getFirstTarget())) { {
if (newTarget.getTargets().contains(tempTarget.getFirstTarget()) || target.getTargets().contains(tempTarget.getFirstTarget())) {
if (targetController.isHuman()) { if (targetController.isHuman()) {
if (targetController.chooseUse(Outcome.Benefit, "This target was already selected from origin spell. Reset to original target?", ability, game)) { if (targetController.chooseUse(Outcome.Benefit, "This target was already selected from origin spell. Reset to original target?", ability, game)) {
// use previous target no target was selected // use previous target no target was selected
@ -240,6 +242,7 @@ public abstract class StackObjImpl implements StackObject {
// valid target was selected, add it to the new target definition // valid target was selected, add it to the new target definition
newTarget.addTarget(tempTarget.getFirstTarget(), target.getTargetAmount(targetId), ability, game, false); newTarget.addTarget(tempTarget.getFirstTarget(), target.getTargetAmount(targetId), ability, game, false);
} }
}
} while (again && targetController.canRespond()); } while (again && targetController.canRespond());
} }
} // keep the target } // keep the target