forked from External/mage
other: reworked target selection: (#13638)
- WIP: AI and multi targets, human and X=0 use cases, human and impossible targets use cases;
- improved stability and shared logic (related to #13606, #11134, #11666, continue from a53eb66b58, close #13617, close #13613);
- improved test logs and debug info to show more target info on errors;
- improved test framework to support multiple addTarget calls;
- improved test framework to find bad commands order for targets (related to #11666);
- fixed game freezes on auto-choice usages with disconnected or under control players (related to #11285);
- gui, game: fixed that player doesn't mark avatar as selected/green in "up to" targeting;
- gui, game: fixed small font in some popup messages on big screens (related to #969);
- gui, game: added min targets info for target selection dialog;
- for devs: added new cheat option to call and test any game dialog (define own dialogs, targets, etc in HumanDialogsTester);
- for devs: now tests require complete an any or up to target selection by addTarget + TestPlayer.TARGET_SKIP or setChoice + TestPlayer.CHOICE_SKIP (if not all max/possible targets used);
- for devs: added detail targets info for activate/trigger/cast, can be useful to debug unit tests, auto-choose or AI (see DebugUtil.GAME_SHOW_CHOOSE_TARGET_LOGS)
This commit is contained in:
parent
80d62727e1
commit
133e4fe425
84 changed files with 2737 additions and 743 deletions
|
|
@ -886,7 +886,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return toDiscard;
|
||||
}
|
||||
TargetDiscard target = new TargetDiscard(minAmount, maxAmount, StaticFilters.FILTER_CARD, getId());
|
||||
choose(Outcome.Discard, target, source, game);
|
||||
target.choose(Outcome.Discard, getId(), source, game);
|
||||
toDiscard.addAll(target.getTargets());
|
||||
return toDiscard;
|
||||
}
|
||||
|
|
@ -4472,14 +4472,14 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
List<Ability> options = new ArrayList<>();
|
||||
if (ability.isModal()) {
|
||||
addModeOptions(options, ability, game);
|
||||
} else if (!ability.getTargets().getUnchosen(game).isEmpty()) {
|
||||
} else if (ability.getTargets().getNextUnchosen(game) != null) {
|
||||
// TODO: Handle other variable costs than mana costs
|
||||
if (!ability.getManaCosts().getVariableCosts().isEmpty()) {
|
||||
addVariableXOptions(options, ability, 0, game);
|
||||
} else {
|
||||
addTargetOptions(options, ability, 0, game);
|
||||
}
|
||||
} else if (!ability.getCosts().getTargets().getUnchosen(game).isEmpty()) {
|
||||
} else if (ability.getCosts().getTargets().getNextUnchosen(game) != null) {
|
||||
addCostTargetOptions(options, ability, 0, game);
|
||||
}
|
||||
|
||||
|
|
@ -4497,13 +4497,13 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
newOption.getModes().clearSelectedModes();
|
||||
newOption.getModes().addSelectedMode(mode.getId());
|
||||
newOption.getModes().setActiveMode(mode);
|
||||
if (!newOption.getTargets().getUnchosen(game).isEmpty()) {
|
||||
if (newOption.getTargets().getNextUnchosen(game) != null) {
|
||||
if (!newOption.getManaCosts().getVariableCosts().isEmpty()) {
|
||||
addVariableXOptions(options, newOption, 0, game);
|
||||
} else {
|
||||
addTargetOptions(options, newOption, 0, game);
|
||||
}
|
||||
} else if (!newOption.getCosts().getTargets().getUnchosen(game).isEmpty()) {
|
||||
} else if (newOption.getCosts().getTargets().getNextUnchosen(game) != null) {
|
||||
addCostTargetOptions(options, newOption, 0, game);
|
||||
} else {
|
||||
options.add(newOption);
|
||||
|
|
@ -4523,7 +4523,9 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
*/
|
||||
protected void addTargetOptions(List<Ability> options, Ability option, int targetNum, Game game) {
|
||||
// TODO: target options calculated for triggered ability too, but do not used in real game
|
||||
for (Target target : option.getTargets().getUnchosen(game).get(targetNum).getTargetOptions(option, game)) {
|
||||
// TODO: there are rare errors with wrong targetNum - maybe multiple game sims can change same target object somehow?
|
||||
// do not hide NullPointError here, research instead
|
||||
for (Target target : option.getTargets().getNextUnchosen(game, targetNum).getTargetOptions(option, game)) {
|
||||
Ability newOption = option.copy();
|
||||
if (target instanceof TargetAmount) {
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
|
|
@ -5562,8 +5564,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
TargetPermanent target = new TargetControlledCreaturePermanent();
|
||||
target.withNotTarget(true);
|
||||
target.withChooseHint("to be your Ring-bearer");
|
||||
choose(Outcome.Neutral, target, null, game);
|
||||
|
||||
target.choose(Outcome.Neutral, getId(), null, null, game);
|
||||
newBearerId = target.getFirstTarget();
|
||||
} else {
|
||||
newBearerId = currentBearerId;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue