forked from External/mage
Please test! Some changes to the display of user choices, showing also a longer text in tooltip window.
This commit is contained in:
parent
cac04616f3
commit
df3e6db569
352 changed files with 2277 additions and 2034 deletions
|
|
@ -37,38 +37,38 @@ public abstract class StackObjImpl implements StackObject {
|
|||
public boolean chooseNewTargets(Game game, UUID playerId) {
|
||||
return chooseNewTargets(game, playerId, false, false, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 114.6. Some effects allow a player to change the target(s) of a spell or
|
||||
* ability, and other effects allow a player to choose new targets for a
|
||||
* spell or ability.
|
||||
*
|
||||
* 114.6a If an effect allows a player to "change the
|
||||
* target(s)" of a spell or ability, each target can be changed only to
|
||||
* another legal target. If a target can't be changed to another legal
|
||||
* target, the original target is unchanged, even if the original target is
|
||||
* itself illegal by then. If all the targets aren't changed to other legal
|
||||
* targets, none of them are changed.
|
||||
*
|
||||
* 114.6b If an effect allows a player to "change a target" of a
|
||||
* spell or ability, the process described in rule 114.6a
|
||||
* is followed, except that only one of those targets may be changed
|
||||
* (rather than all of them or none of them).
|
||||
*
|
||||
* 114.6c If an effect allows a
|
||||
* player to "change any targets" of a spell or ability, the process
|
||||
* described in rule 114.6a is followed, except that any number of those
|
||||
* targets may be changed (rather than all of them or none of them).
|
||||
*
|
||||
* 114.6d If an effect allows a player to "choose new targets" for a spell or
|
||||
* ability, the player may leave any number of the targets unchanged, even
|
||||
* if those targets would be illegal. If the player chooses to change some
|
||||
* or all of the targets, the new targets must be legal and must not cause
|
||||
* any unchanged targets to become illegal.
|
||||
*
|
||||
* 114.6e When changing targets or
|
||||
* choosing new targets for a spell or ability, only the final set of
|
||||
* targets is evaluated to determine whether the change is legal.
|
||||
* spell or ability.
|
||||
*
|
||||
* 114.6a If an effect allows a player to "change the target(s)" of a spell
|
||||
* or ability, each target can be changed only to another legal target. If a
|
||||
* target can't be changed to another legal target, the original target is
|
||||
* unchanged, even if the original target is itself illegal by then. If all
|
||||
* the targets aren't changed to other legal targets, none of them are
|
||||
* changed.
|
||||
*
|
||||
* 114.6b If an effect allows a player to "change a target" of a spell or
|
||||
* ability, the process described in rule 114.6a is followed, except that
|
||||
* only one of those targets may be changed (rather than all of them or none
|
||||
* of them).
|
||||
*
|
||||
* 114.6c If an effect allows a player to "change any targets" of a spell or
|
||||
* ability, the process described in rule 114.6a is followed, except that
|
||||
* any number of those targets may be changed (rather than all of them or
|
||||
* none of them).
|
||||
*
|
||||
* 114.6d If an effect allows a player to "choose new targets" for a spell
|
||||
* or ability, the player may leave any number of the targets unchanged,
|
||||
* even if those targets would be illegal. If the player chooses to change
|
||||
* some or all of the targets, the new targets must be legal and must not
|
||||
* cause any unchanged targets to become illegal.
|
||||
*
|
||||
* 114.6e When changing targets or choosing new targets for a spell or
|
||||
* ability, only the final set of targets is evaluated to determine whether
|
||||
* the change is legal.
|
||||
*
|
||||
* Example: Arc Trail is a sorcery that reads "Arc Trail deals 2 damage to
|
||||
* target creature or player and 1 damage to another target creature or
|
||||
|
|
@ -92,10 +92,14 @@ public abstract class StackObjImpl implements StackObject {
|
|||
* targets will be, the copy is put onto the stack with those targets.
|
||||
*
|
||||
* @param game
|
||||
* @param targetControllerId - player that can/has to change the target of the spell
|
||||
* @param forceChange - does only work for targets with maximum of one targetId
|
||||
* @param onlyOneTarget - 114.6b one target must be changed to another target
|
||||
* @param filterNewTarget restriction for the new target, if null nothing is cheched
|
||||
* @param targetControllerId - player that can/has to change the target of
|
||||
* the spell
|
||||
* @param forceChange - does only work for targets with maximum of one
|
||||
* targetId
|
||||
* @param onlyOneTarget - 114.6b one target must be changed to another
|
||||
* target
|
||||
* @param filterNewTarget restriction for the new target, if null nothing is
|
||||
* cheched
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
|
|
@ -105,8 +109,8 @@ public abstract class StackObjImpl implements StackObject {
|
|||
StringBuilder newTargetDescription = new StringBuilder();
|
||||
// Fused split spells or spells where "Splice on Arcane" was used can have more than one ability
|
||||
Abilities<Ability> objectAbilities = new AbilitiesImpl<>();
|
||||
if (this instanceof Spell) {
|
||||
objectAbilities.addAll(((Spell)this).getSpellAbilities());
|
||||
if (this instanceof Spell) {
|
||||
objectAbilities.addAll(((Spell) this).getSpellAbilities());
|
||||
} else {
|
||||
objectAbilities.addAll(getAbilities());
|
||||
}
|
||||
|
|
@ -119,7 +123,7 @@ public abstract class StackObjImpl implements StackObject {
|
|||
// clear the old target and copy all targets from new target
|
||||
target.clearChosen();
|
||||
for (UUID targetId : newTarget.getTargets()) {
|
||||
target.addTarget(targetId, newTarget.getTargetAmount(targetId), ability, game, false);
|
||||
target.addTarget(targetId, newTarget.getTargetAmount(targetId), ability, game, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -137,30 +141,30 @@ public abstract class StackObjImpl implements StackObject {
|
|||
|
||||
/**
|
||||
* Handles the change of one target instance of a mode
|
||||
*
|
||||
*
|
||||
* @param targetController - player that can choose the new target
|
||||
* @param ability
|
||||
* @param mode
|
||||
* @param target
|
||||
* @param forceChange
|
||||
* @param game
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
private Target chooseNewTarget(Player targetController, Ability ability, Mode mode, Target target, boolean forceChange, FilterPermanent filterNewTarget, Game game) {
|
||||
Target newTarget = target.copy();
|
||||
if (!targetController.getId().equals(getControllerId())) {
|
||||
newTarget.setTargetController(targetController.getId()); // target controller for the change is different from spell controller
|
||||
newTarget.setAbilityController(getControllerId());
|
||||
}
|
||||
}
|
||||
newTarget.clearChosen();
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
String targetNames = getNamesOftargets(targetId, game);
|
||||
// change the target?
|
||||
if (targetNames != null
|
||||
&& (forceChange || targetController.chooseUse(mode.getEffects().get(0).getOutcome(), "Change this target: " + targetNames + "?", game))) {
|
||||
&& (forceChange || targetController.chooseUse(mode.getEffects().get(0).getOutcome(), "Change this target: " + targetNames + "?", ability, game))) {
|
||||
Set<UUID> possibleTargets = target.possibleTargets(this.getSourceId(), getControllerId(), game);
|
||||
// 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)
|
||||
int iteration = 0;
|
||||
do {
|
||||
if (iteration > 0 && !game.isSimulation()) {
|
||||
|
|
@ -168,36 +172,36 @@ public abstract class StackObjImpl implements StackObject {
|
|||
}
|
||||
iteration++;
|
||||
newTarget.clearChosen();
|
||||
|
||||
newTarget.chooseTarget(mode.getEffects().get(0).getOutcome(), getControllerId(), ability, game);
|
||||
// check target restriction
|
||||
|
||||
newTarget.chooseTarget(mode.getEffects().get(0).getOutcome(), getControllerId(), ability, game);
|
||||
// check target restriction
|
||||
if (newTarget.getFirstTarget() != null && filterNewTarget != null) {
|
||||
Permanent newTargetPermanent = game.getPermanent(newTarget.getFirstTarget());
|
||||
if (newTargetPermanent == null || !filterNewTarget.match(newTargetPermanent, game)) {
|
||||
game.informPlayer(targetController, "Target does not fullfil the target requirements (" + filterNewTarget.getMessage() +")");
|
||||
game.informPlayer(targetController, "Target does not fullfil the target requirements (" + filterNewTarget.getMessage() + ")");
|
||||
newTarget.clearChosen();
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (targetController.isInGame() && (targetId.equals(newTarget.getFirstTarget()) || newTarget.getTargets().size() != 1));
|
||||
// choose a new target
|
||||
// choose a new target
|
||||
} else {
|
||||
// build a target definition with exactly one possible target to select that replaces old target
|
||||
Target tempTarget = target.copy();
|
||||
if (target instanceof TargetAmount) {
|
||||
((TargetAmount)tempTarget).setAmountDefinition(new StaticValue(target.getTargetAmount(targetId)));
|
||||
((TargetAmount) tempTarget).setAmountDefinition(new StaticValue(target.getTargetAmount(targetId)));
|
||||
}
|
||||
tempTarget.setMinNumberOfTargets(1);
|
||||
tempTarget.setMaxNumberOfTargets(1);
|
||||
if (!targetController.getId().equals(getControllerId())) {
|
||||
tempTarget.setTargetController(targetController.getId());
|
||||
tempTarget.setAbilityController(getControllerId());
|
||||
tempTarget.setAbilityController(getControllerId());
|
||||
}
|
||||
boolean again;
|
||||
do {
|
||||
again = false;
|
||||
tempTarget.clearChosen();
|
||||
if (!tempTarget.chooseTarget(mode.getEffects().get(0).getOutcome(), getControllerId(), ability, game)) {
|
||||
if (targetController.chooseUse(Outcome.Benefit, "No target object selected. Reset to original target?", game)) {
|
||||
if (targetController.chooseUse(Outcome.Benefit, "No target object selected. Reset to original target?", ability, game)) {
|
||||
// use previous target no target was selected
|
||||
newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false);
|
||||
} else {
|
||||
|
|
@ -206,43 +210,41 @@ public abstract class StackObjImpl implements StackObject {
|
|||
} 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(targetController.isHuman()) {
|
||||
if (targetController.isHuman()) {
|
||||
game.informPlayer(targetController, "This target was already selected from origin spell. You can only keep this target!");
|
||||
again = true;
|
||||
} else {
|
||||
newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false);
|
||||
}
|
||||
} else if (!target.canTarget(getControllerId(), tempTarget.getFirstTarget(), ability, game)) {
|
||||
if(targetController.isHuman()) {
|
||||
if (targetController.isHuman()) {
|
||||
game.informPlayer(targetController, "This target is not valid!");
|
||||
again = true;
|
||||
} else {
|
||||
// keep the old
|
||||
newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false);
|
||||
}
|
||||
}
|
||||
} else if (newTarget.getFirstTarget() != null && filterNewTarget != null) {
|
||||
Permanent newTargetPermanent = game.getPermanent(newTarget.getFirstTarget());
|
||||
if (newTargetPermanent == null || !filterNewTarget.match(newTargetPermanent, game)) {
|
||||
game.informPlayer(targetController, "This target does not fullfil the target requirements (" + filterNewTarget.getMessage() +")");
|
||||
game.informPlayer(targetController, "This target does not fullfil the target requirements (" + filterNewTarget.getMessage() + ")");
|
||||
again = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// valid target was selected, add it to the new target definition
|
||||
newTarget.addTarget(tempTarget.getFirstTarget(), target.getTargetAmount(targetId), ability, game, false);
|
||||
}
|
||||
}
|
||||
} while (again && targetController.isInGame());
|
||||
}
|
||||
}
|
||||
// keep the target
|
||||
else {
|
||||
}
|
||||
} // keep the target
|
||||
else {
|
||||
newTarget.addTarget(targetId, target.getTargetAmount(targetId), ability, game, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return newTarget;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private String getNamesOftargets(UUID targetId, Game game) {
|
||||
MageObject object = game.getObject(targetId);
|
||||
String name = null;
|
||||
|
|
@ -256,5 +258,5 @@ public abstract class StackObjImpl implements StackObject {
|
|||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue