mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
* Added checks in all the methods that wait for human response to prevent endless loops if the method is called from a the get playable actions.
This commit is contained in:
parent
1f82e7a4ae
commit
cadae9ee92
2 changed files with 86 additions and 14 deletions
|
@ -14,6 +14,7 @@ import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import jdk.nashorn.internal.objects.NativeError;
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.ActivatedAbility;
|
import mage.abilities.ActivatedAbility;
|
||||||
|
@ -250,6 +251,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseMulligan(Game game) {
|
public boolean chooseMulligan(Game game) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
updateGameStatePriority("chooseMulligan", game);
|
updateGameStatePriority("chooseMulligan", game);
|
||||||
int nextHandSize = game.mulliganDownTo(playerId);
|
int nextHandSize = game.mulliganDownTo(playerId);
|
||||||
do {
|
do {
|
||||||
|
@ -353,6 +357,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int chooseReplacementEffect(Map<String, String> rEffects, Game game) {
|
public int chooseReplacementEffect(Map<String, String> rEffects, Game game) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (game.inCheckPlayableState()) {
|
if (game.inCheckPlayableState()) {
|
||||||
logger.warn("player interaction in checkPlayableState.");
|
logger.warn("player interaction in checkPlayableState.");
|
||||||
if (rEffects.size() <= 1) {
|
if (rEffects.size() <= 1) {
|
||||||
|
@ -421,9 +428,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choose(Outcome outcome, Choice choice, Game game) {
|
public boolean choose(Outcome outcome, Choice choice, Game game) {
|
||||||
if (game.inCheckPlayableState()) {
|
if (gameInCheckPlayableState(game)) {
|
||||||
logger.warn("player interaction in checkPlayableState. Choice: " + choice.getMessage());
|
|
||||||
choice.setChoice(choice.getChoices().iterator().next());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Outcome.PutManaInPool == outcome) {
|
if (Outcome.PutManaInPool == outcome) {
|
||||||
|
@ -461,9 +466,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game, Map<String, Serializable> options) {
|
public boolean choose(Outcome outcome, Target target, UUID sourceId, Game game, Map<String, Serializable> options) {
|
||||||
if (game.inCheckPlayableState()) {
|
if (gameInCheckPlayableState(game)) {
|
||||||
logger.warn("player interaction in checkPlayableState. Target: " + target.getMessage());
|
|
||||||
// TODO: set default choice
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// choose one or multiple permanents
|
// choose one or multiple permanents
|
||||||
|
@ -557,9 +560,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseTarget(Outcome outcome, Target target, Ability source, Game game) {
|
public boolean chooseTarget(Outcome outcome, Target target, Ability source, Game game) {
|
||||||
if (game.inCheckPlayableState()) {
|
if (gameInCheckPlayableState(game)) {
|
||||||
logger.warn("player interaction in checkPlayableState. Target: " + target.getMessage());
|
|
||||||
// TODO: set default choice
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// choose one or multiple targets
|
// choose one or multiple targets
|
||||||
|
@ -624,9 +625,7 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choose(Outcome outcome, Cards cards, TargetCard target, Game game) {
|
public boolean choose(Outcome outcome, Cards cards, TargetCard target, Game game) {
|
||||||
if (game.inCheckPlayableState()) {
|
if (gameInCheckPlayableState(game)) {
|
||||||
logger.warn("player interaction in checkPlayableState. Target: " + target.getMessage());
|
|
||||||
// TODO: set default choice
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// choose one or multiple cards
|
// choose one or multiple cards
|
||||||
|
@ -685,9 +684,12 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// choose one or multiple target cards
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
|
public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
|
||||||
// choose one or multiple target cards
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
updateGameStatePriority("chooseTarget(5)", game);
|
updateGameStatePriority("chooseTarget(5)", game);
|
||||||
while (!abort) {
|
while (!abort) {
|
||||||
boolean required;
|
boolean required;
|
||||||
|
@ -751,6 +753,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
|
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
|
||||||
// choose amount
|
// choose amount
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
updateGameStatePriority("chooseTargetAmount", game);
|
updateGameStatePriority("chooseTargetAmount", game);
|
||||||
while (!abort) {
|
while (!abort) {
|
||||||
prepareForResponse(game);
|
prepareForResponse(game);
|
||||||
|
@ -1061,6 +1066,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
@Override
|
@Override
|
||||||
public TriggeredAbility chooseTriggeredAbility(List<TriggeredAbility> abilities, Game game) {
|
public TriggeredAbility chooseTriggeredAbility(List<TriggeredAbility> abilities, Game game) {
|
||||||
// choose triggered abilitity from list
|
// choose triggered abilitity from list
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
String autoOrderRuleText = null;
|
String autoOrderRuleText = null;
|
||||||
boolean autoOrderUse = getControllingPlayersUserData(game).isAutoOrderTrigger();
|
boolean autoOrderUse = getControllingPlayersUserData(game).isAutoOrderTrigger();
|
||||||
while (!abort) {
|
while (!abort) {
|
||||||
|
@ -1138,6 +1146,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
protected boolean playManaHandling(Ability abilityToCast, ManaCost unpaid, String promptText, Game game) {
|
protected boolean playManaHandling(Ability abilityToCast, ManaCost unpaid, String promptText, Game game) {
|
||||||
// choose mana to pay (from permanents or from pool)
|
// choose mana to pay (from permanents or from pool)
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
updateGameStatePriority("playMana", game);
|
updateGameStatePriority("playMana", game);
|
||||||
Map<String, Serializable> options = new HashMap<>();
|
Map<String, Serializable> options = new HashMap<>();
|
||||||
prepareForResponse(game);
|
prepareForResponse(game);
|
||||||
|
@ -1174,6 +1185,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int announceRepetitions(Game game) {
|
public int announceRepetitions(Game game) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
int xValue = 0;
|
int xValue = 0;
|
||||||
updateGameStatePriority("announceRepetitions", game);
|
updateGameStatePriority("announceRepetitions", game);
|
||||||
do {
|
do {
|
||||||
|
@ -1192,10 +1206,20 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
/**
|
/**
|
||||||
* Gets the amount of mana the player want to spent for a x spell
|
* Gets the amount of mana the player want to spent for a x spell
|
||||||
*
|
*
|
||||||
|
* @param min
|
||||||
|
* @param max
|
||||||
* @param multiplier - X multiplier after replace events
|
* @param multiplier - X multiplier after replace events
|
||||||
|
* @param message
|
||||||
|
* @param ability
|
||||||
|
* @param game
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int announceXMana(int min, int max, int multiplier, String message, Game game, Ability ability) {
|
public int announceXMana(int min, int max, int multiplier, String message, Game game, Ability ability) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int xValue = 0;
|
int xValue = 0;
|
||||||
String extraMessage = (multiplier == 1 ? "" : ", X will be increased by " + multiplier + " times");
|
String extraMessage = (multiplier == 1 ? "" : ", X will be increased by " + multiplier + " times");
|
||||||
updateGameStatePriority("announceXMana", game);
|
updateGameStatePriority("announceXMana", game);
|
||||||
|
@ -1216,6 +1240,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variableCost) {
|
public int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variableCost) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
int xValue = 0;
|
int xValue = 0;
|
||||||
updateGameStatePriority("announceXCost", game);
|
updateGameStatePriority("announceXCost", game);
|
||||||
do {
|
do {
|
||||||
|
@ -1262,6 +1289,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectAttackers(Game game, UUID attackingPlayerId) {
|
public void selectAttackers(Game game, UUID attackingPlayerId) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
updateGameStatePriority("selectAttackers", game);
|
updateGameStatePriority("selectAttackers", game);
|
||||||
FilterCreatureForCombat filter = filterCreatureForCombat.copy();
|
FilterCreatureForCombat filter = filterCreatureForCombat.copy();
|
||||||
filter.add(new ControllerIdPredicate(attackingPlayerId));
|
filter.add(new ControllerIdPredicate(attackingPlayerId));
|
||||||
|
@ -1521,6 +1551,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectBlockers(Game game, UUID defendingPlayerId) {
|
public void selectBlockers(Game game, UUID defendingPlayerId) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
updateGameStatePriority("selectBlockers", game);
|
updateGameStatePriority("selectBlockers", game);
|
||||||
FilterCreatureForCombatBlock filter = filterCreatureForCombatBlock.copy();
|
FilterCreatureForCombatBlock filter = filterCreatureForCombatBlock.copy();
|
||||||
filter.add(new ControllerIdPredicate(defendingPlayerId));
|
filter.add(new ControllerIdPredicate(defendingPlayerId));
|
||||||
|
@ -1570,6 +1603,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UUID chooseAttackerOrder(List<Permanent> attackers, Game game) {
|
public UUID chooseAttackerOrder(List<Permanent> attackers, Game game) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
updateGameStatePriority("chooseAttackerOrder", game);
|
updateGameStatePriority("chooseAttackerOrder", game);
|
||||||
while (!abort) {
|
while (!abort) {
|
||||||
prepareForResponse(game);
|
prepareForResponse(game);
|
||||||
|
@ -1590,6 +1626,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) {
|
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
updateGameStatePriority("chooseBlockerOrder", game);
|
updateGameStatePriority("chooseBlockerOrder", game);
|
||||||
while (!abort) {
|
while (!abort) {
|
||||||
prepareForResponse(game);
|
prepareForResponse(game);
|
||||||
|
@ -1609,6 +1648,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void selectCombatGroup(UUID defenderId, UUID blockerId, Game game) {
|
protected void selectCombatGroup(UUID defenderId, UUID blockerId, Game game) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
updateGameStatePriority("selectCombatGroup", game);
|
updateGameStatePriority("selectCombatGroup", game);
|
||||||
TargetAttackingCreature target = new TargetAttackingCreature();
|
TargetAttackingCreature target = new TargetAttackingCreature();
|
||||||
prepareForResponse(game);
|
prepareForResponse(game);
|
||||||
|
@ -1674,6 +1716,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAmount(int min, int max, String message, Game game) {
|
public int getAmount(int min, int max, String message, Game game) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
updateGameStatePriority("getAmount", game);
|
updateGameStatePriority("getAmount", game);
|
||||||
do {
|
do {
|
||||||
prepareForResponse(game);
|
prepareForResponse(game);
|
||||||
|
@ -1705,6 +1750,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void specialAction(Game game) {
|
protected void specialAction(Game game) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Map<UUID, SpecialAction> specialActions = game.getState().getSpecialActions().getControlledBy(playerId, false);
|
Map<UUID, SpecialAction> specialActions = game.getState().getSpecialActions().getControlledBy(playerId, false);
|
||||||
if (!specialActions.isEmpty()) {
|
if (!specialActions.isEmpty()) {
|
||||||
updateGameStatePriority("specialAction", game);
|
updateGameStatePriority("specialAction", game);
|
||||||
|
@ -1722,6 +1770,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void specialManaAction(ManaCost unpaid, Game game) {
|
protected void specialManaAction(ManaCost unpaid, Game game) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Map<UUID, SpecialAction> specialActions = game.getState().getSpecialActions().getControlledBy(playerId, true);
|
Map<UUID, SpecialAction> specialActions = game.getState().getSpecialActions().getControlledBy(playerId, true);
|
||||||
if (!specialActions.isEmpty()) {
|
if (!specialActions.isEmpty()) {
|
||||||
updateGameStatePriority("specialAction", game);
|
updateGameStatePriority("specialAction", game);
|
||||||
|
@ -1749,6 +1800,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void activateAbility(LinkedHashMap<UUID, ? extends ActivatedAbility> abilities, MageObject object, Game game) {
|
protected void activateAbility(LinkedHashMap<UUID, ? extends ActivatedAbility> abilities, MageObject object, Game game) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
updateGameStatePriority("activateAbility", game);
|
updateGameStatePriority("activateAbility", game);
|
||||||
if (abilities.size() == 1
|
if (abilities.size() == 1
|
||||||
&& suppressAbilityPicker(abilities.values().iterator().next(), game)) {
|
&& suppressAbilityPicker(abilities.values().iterator().next(), game)) {
|
||||||
|
@ -1800,6 +1854,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana) {
|
public SpellAbility chooseSpellAbilityForCast(SpellAbility ability, Game game, boolean noMana) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
switch (ability.getSpellAbilityType()) {
|
switch (ability.getSpellAbilityType()) {
|
||||||
case SPLIT:
|
case SPLIT:
|
||||||
case SPLIT_FUSED:
|
case SPLIT_FUSED:
|
||||||
|
@ -1832,6 +1889,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpellAbility chooseAbilityForCast(Card card, Game game, boolean nonMana) {
|
public SpellAbility chooseAbilityForCast(Card card, Game game, boolean nonMana) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
MageObject object = game.getObject(card.getId());
|
MageObject object = game.getObject(card.getId());
|
||||||
if (object != null) {
|
if (object != null) {
|
||||||
LinkedHashMap<UUID, ActivatedAbility> useableAbilities = getSpellAbilities(object, game.getState().getZone(object.getId()), game);
|
LinkedHashMap<UUID, ActivatedAbility> useableAbilities = getSpellAbilities(object, game.getState().getZone(object.getId()), game);
|
||||||
|
@ -1858,6 +1918,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
@Override
|
@Override
|
||||||
public Mode chooseMode(Modes modes, Ability source, Game game) {
|
public Mode chooseMode(Modes modes, Ability source, Game game) {
|
||||||
// choose mode to activate
|
// choose mode to activate
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
updateGameStatePriority("chooseMode", game);
|
updateGameStatePriority("chooseMode", game);
|
||||||
if (modes.size() > 1) {
|
if (modes.size() > 1) {
|
||||||
MageObject obj = game.getObject(source.getSourceId());
|
MageObject obj = game.getObject(source.getSourceId());
|
||||||
|
@ -1927,6 +1990,9 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean choosePile(Outcome outcome, String message, List<? extends Card> pile1, List<? extends Card> pile2, Game game) {
|
public boolean choosePile(Outcome outcome, String message, List<? extends Card> pile1, List<? extends Card> pile2, Game game) {
|
||||||
|
if (gameInCheckPlayableState(game)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
updateGameStatePriority("choosePile", game);
|
updateGameStatePriority("choosePile", game);
|
||||||
do {
|
do {
|
||||||
prepareForResponse(game);
|
prepareForResponse(game);
|
||||||
|
@ -2197,4 +2263,11 @@ public class HumanPlayer extends PlayerImpl {
|
||||||
return "no available";
|
return "no available";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean gameInCheckPlayableState(Game game) {
|
||||||
|
if (game.inCheckPlayableState()) {
|
||||||
|
logger.warn("Player interaction in checkPlayableState./n" + NativeError.printStackTrace(this));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.game.events;
|
package mage.game.events;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
Loading…
Reference in a new issue