mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
[CMR] fixed Akroma's Will - missing copy of new condition in modes (#7210);
Improved compatibility of new modes condition with choose dialogs and test framework;
This commit is contained in:
parent
64821a50d3
commit
2b78388eab
5 changed files with 131 additions and 32 deletions
|
@ -1924,7 +1924,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
@Override
|
||||
public Mode chooseMode(Modes modes, Ability source, Game game) {
|
||||
log.debug("chooseMode");
|
||||
if (modes.getMode() != null && modes.getMaxModes() == modes.getSelectedModes().size()) {
|
||||
if (modes.getMode() != null && modes.getMaxModes(game, source) == modes.getSelectedModes().size()) {
|
||||
// mode was already set by the AI
|
||||
return modes.getMode();
|
||||
}
|
||||
|
|
|
@ -2085,7 +2085,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
boolean done = false;
|
||||
while (!done && canRespond()) {
|
||||
|
||||
String message = "Choose mode (selected " + modes.getSelectedModes().size() + " of " + modes.getMaxModes()
|
||||
String message = "Choose mode (selected " + modes.getSelectedModes().size() + " of " + modes.getMaxModes(game, source)
|
||||
+ ", min " + modes.getMinModes() + ")";
|
||||
if (obj != null) {
|
||||
message = message + "<br>" + obj.getLogName();
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package org.mage.test.cards.single.cmr;
|
||||
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.LifelinkAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestCommanderDuelBase;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
|
||||
public class AkromasWillTest extends CardTestCommanderDuelBase {
|
||||
|
||||
@Test
|
||||
public void test_OneMode() {
|
||||
// https://github.com/magefree/mage/issues/7210
|
||||
|
||||
// Choose one. If you control a commander as you cast this spell, you may choose both.
|
||||
// * Creatures you control gain flying, vigilance, and double strike until end of turn.
|
||||
// * Creatures you control gain lifelink, indestructible, and protection from all colors until end of turn.
|
||||
addCard(Zone.HAND, playerA, "Akroma's Will", 1); // {3}{W}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||
//
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Kitesail Corsair", 1);
|
||||
|
||||
checkAbility("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kitesail Corsair", FlyingAbility.class, false);
|
||||
checkAbility("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kitesail Corsair", LifelinkAbility.class, false);
|
||||
|
||||
// cast and use ONE mode only
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akroma's Will");
|
||||
setModeChoice(playerA, "1");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkAbility("after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kitesail Corsair", FlyingAbility.class, true);
|
||||
checkAbility("after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kitesail Corsair", LifelinkAbility.class, false);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_MultiModesOnCommander() {
|
||||
// https://github.com/magefree/mage/issues/7210
|
||||
|
||||
// Choose one. If you control a commander as you cast this spell, you may choose both.
|
||||
// * Creatures you control gain flying, vigilance, and double strike until end of turn.
|
||||
// * Creatures you control gain lifelink, indestructible, and protection from all colors until end of turn.
|
||||
addCard(Zone.HAND, playerA, "Akroma's Will", 1); // {3}{W}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||
//
|
||||
addCard(Zone.COMMAND, playerA, "Balduvian Bears", 1); // {1}{G}
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||
//
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Kitesail Corsair", 1);
|
||||
|
||||
checkAbility("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kitesail Corsair", FlyingAbility.class, false);
|
||||
checkAbility("before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kitesail Corsair", LifelinkAbility.class, false);
|
||||
|
||||
// prepare commander
|
||||
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {G}", 2);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkPermanentCount("commander on battle", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Balduvian Bears", 1);
|
||||
|
||||
// cast and use two modes instead one
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akroma's Will");
|
||||
setModeChoice(playerA, "2");
|
||||
setModeChoice(playerA, "1");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkAbility("after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kitesail Corsair", FlyingAbility.class, true);
|
||||
checkAbility("after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Kitesail Corsair", LifelinkAbility.class, true);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
}
|
|
@ -1869,7 +1869,7 @@ public class TestPlayer implements Player {
|
|||
|
||||
@Override
|
||||
public Mode chooseMode(Modes modes, Ability source, Game game) {
|
||||
if (!modesSet.isEmpty() && modes.getMaxModes() > modes.getSelectedModes().size()) {
|
||||
if (!modesSet.isEmpty() && modes.getMaxModes(game, source) > modes.getSelectedModes().size()) {
|
||||
// set mode to null to select less than maximum modes if multiple modes are allowed
|
||||
if (modesSet.get(0) == null) {
|
||||
modesSet.remove(0);
|
||||
|
|
|
@ -76,6 +76,7 @@ public class Modes extends LinkedHashMap<UUID, Mode> {
|
|||
} else {
|
||||
this.currentMode = get(modes.getMode().getId()); // need fix?
|
||||
}
|
||||
this.moreCondition = modes.moreCondition;
|
||||
}
|
||||
|
||||
public Modes copy() {
|
||||
|
@ -190,8 +191,41 @@ public class Modes extends LinkedHashMap<UUID, Mode> {
|
|||
this.maxModesFilter = maxModesFilter;
|
||||
}
|
||||
|
||||
public int getMaxModes() {
|
||||
return this.maxModes;
|
||||
/**
|
||||
* Return real affected max modes in current game. Use null params for default max modes value.
|
||||
*
|
||||
* @param game
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public int getMaxModes(Game game, Ability source) {
|
||||
int realMaxModes = this.maxModes;
|
||||
if (game == null || source == null) {
|
||||
return realMaxModes;
|
||||
}
|
||||
|
||||
// use case: make all modes chooseable
|
||||
if (moreCondition != null && moreCondition.apply(game, source)) {
|
||||
realMaxModes = Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
// use case: limit max modes by opponents (wtf?!)
|
||||
if (getMaxModesFilter() != null) {
|
||||
if (this.maxModesFilter instanceof FilterPlayer) {
|
||||
realMaxModes = 0;
|
||||
for (UUID targetPlayerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
|
||||
Player targetPlayer = game.getPlayer(targetPlayerId);
|
||||
if (((FilterPlayer) this.maxModesFilter).match(targetPlayer, source.getSourceId(), source.getControllerId(), game)) {
|
||||
realMaxModes++;
|
||||
}
|
||||
}
|
||||
if (realMaxModes > this.maxModes) {
|
||||
realMaxModes = this.maxModes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return realMaxModes;
|
||||
}
|
||||
|
||||
public void setModeChooser(TargetController modeChooser) {
|
||||
|
@ -222,9 +256,9 @@ public class Modes extends LinkedHashMap<UUID, Mode> {
|
|||
|
||||
public boolean choose(Game game, Ability source) {
|
||||
if (this.isResetEachTurn()) {
|
||||
if (this.getTurnNum(game, source) != game.getTurnNum()) {
|
||||
if (getTurnNum(game, source) != game.getTurnNum()) {
|
||||
this.clearAlreadySelectedModes(source, game);
|
||||
this.setTurnNum(game, source);
|
||||
setTurnNum(game, source);
|
||||
}
|
||||
}
|
||||
if (this.size() > 1) {
|
||||
|
@ -284,24 +318,8 @@ public class Modes extends LinkedHashMap<UUID, Mode> {
|
|||
|
||||
// player chooses modes manually
|
||||
this.currentMode = null;
|
||||
int currentMaxModes = this.getMaxModes();
|
||||
if (moreCondition != null && moreCondition.apply(game, source)) {
|
||||
currentMaxModes = Integer.MAX_VALUE;
|
||||
}
|
||||
if (getMaxModesFilter() != null) {
|
||||
if (maxModesFilter instanceof FilterPlayer) {
|
||||
currentMaxModes = 0;
|
||||
for (UUID targetPlayerId : game.getState().getPlayersInRange(source.getControllerId(), game)) {
|
||||
Player targetPlayer = game.getPlayer(targetPlayerId);
|
||||
if (((FilterPlayer) maxModesFilter).match(targetPlayer, source.getSourceId(), source.getControllerId(), game)) {
|
||||
currentMaxModes++;
|
||||
}
|
||||
}
|
||||
if (currentMaxModes > this.getMaxModes()) {
|
||||
currentMaxModes = this.getMaxModes();
|
||||
}
|
||||
}
|
||||
}
|
||||
int currentMaxModes = this.getMaxModes(game, source);
|
||||
|
||||
while (this.selectedModes.size() < currentMaxModes) {
|
||||
Mode choice = player.chooseMode(this, source, game);
|
||||
if (choice == null) {
|
||||
|
@ -446,19 +464,19 @@ public class Modes extends LinkedHashMap<UUID, Mode> {
|
|||
sb.append(chooseText);
|
||||
} else if (this.getMaxModesFilter() != null) {
|
||||
sb.append("choose one or more. Each mode must target ").append(getMaxModesFilter().getMessage());
|
||||
} else if (this.getMinModes() == 0 && this.getMaxModes() == 1) {
|
||||
} else if (this.getMinModes() == 0 && this.getMaxModes(null, null) == 1) {
|
||||
sb.append("choose up to one");
|
||||
} else if (this.getMinModes() == 0 && this.getMaxModes() == 3) {
|
||||
} else if (this.getMinModes() == 0 && this.getMaxModes(null, null) == 3) {
|
||||
sb.append("choose any number");
|
||||
} else if (this.getMinModes() == 1 && this.getMaxModes() > 2) {
|
||||
} else if (this.getMinModes() == 1 && this.getMaxModes(null, null) > 2) {
|
||||
sb.append("choose one or more");
|
||||
} else if (this.getMinModes() == 1 && this.getMaxModes() == 2) {
|
||||
} else if (this.getMinModes() == 1 && this.getMaxModes(null, null) == 2) {
|
||||
sb.append("choose one or both");
|
||||
} else if (this.getMinModes() == 2 && this.getMaxModes() == 2) {
|
||||
} else if (this.getMinModes() == 2 && this.getMaxModes(null, null) == 2) {
|
||||
sb.append("choose two");
|
||||
} else if (this.getMinModes() == 3 && this.getMaxModes() == 3) {
|
||||
} else if (this.getMinModes() == 3 && this.getMaxModes(null, null) == 3) {
|
||||
sb.append("choose three");
|
||||
} else if (this.getMinModes() == 4 && this.getMaxModes() == 4) {
|
||||
} else if (this.getMinModes() == 4 && this.getMaxModes(null, null) == 4) {
|
||||
sb.append("choose four");
|
||||
} else {
|
||||
sb.append("choose one");
|
||||
|
|
Loading…
Reference in a new issue