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:
parent
8e42660e33
commit
ca25cc4679
5 changed files with 19 additions and 12 deletions
Mage/src/main/java/mage
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue