Turn under control reworked:

- game: added support for human games (cards like Emrakul, the Promised End, #12878);
 - game: added support of 720.1. to reset control in the turn beginning instead cleanup step (related to #12115);
 - game: added game logs for priorities in cleanup step;
 - game: fixed game freezes and wrong skip settings usages (related to #12878);
 - gui: added playable and choose-able marks for controlling player's cards and permanents, including switched hands;
 - gui: added controlling player name in all choice dialogs;
 - info: control of computer players is it not yet supported;
This commit is contained in:
Oleg Agafonov 2025-01-07 12:26:30 +04:00
parent 75d241d541
commit c076f4925f
17 changed files with 177 additions and 140 deletions

View file

@ -2987,21 +2987,35 @@ public abstract class GameImpl implements Game {
}
String message;
if (this.canPlaySorcery(playerId)) {
message = "Play spells and abilities.";
message = "Play spells and abilities";
} else {
message = "Play instants and activated abilities.";
message = "Play instants and activated abilities";
}
playerQueryEventSource.select(playerId, message);
message += getControllingPlayerHint(playerId);
Player player = this.getPlayer(playerId);
playerQueryEventSource.select(player.getTurnControlledBy(), message);
getState().clearLookedAt();
getState().clearRevealed();
}
private String getControllingPlayerHint(UUID playerId) {
Player player = this.getPlayer(playerId);
Player controllingPlayer = this.getPlayer(player.getTurnControlledBy());
if (player != controllingPlayer) {
return " (as " + player.getLogName() + ")";
} else {
return "";
}
}
@Override
public synchronized void fireSelectEvent(UUID playerId, String message) {
if (simulation) {
return;
}
playerQueryEventSource.select(playerId, message);
playerQueryEventSource.select(playerId, message + getControllingPlayerHint(playerId));
}
@Override
@ -3009,7 +3023,7 @@ public abstract class GameImpl implements Game {
if (simulation) {
return;
}
playerQueryEventSource.select(playerId, message, options);
playerQueryEventSource.select(playerId, message + getControllingPlayerHint(playerId), options);
}
@Override
@ -3017,7 +3031,7 @@ public abstract class GameImpl implements Game {
if (simulation) {
return;
}
playerQueryEventSource.playMana(playerId, message, options);
playerQueryEventSource.playMana(playerId, message + getControllingPlayerHint(playerId), options);
}
@Override
@ -3025,7 +3039,7 @@ public abstract class GameImpl implements Game {
if (simulation) {
return;
}
playerQueryEventSource.playXMana(playerId, message);
playerQueryEventSource.playXMana(playerId, message + getControllingPlayerHint(playerId));
}
@Override
@ -3038,7 +3052,7 @@ public abstract class GameImpl implements Game {
if (simulation) {
return;
}
playerQueryEventSource.ask(playerId, message.getMessage(), source, addMessageToOptions(message, options));
playerQueryEventSource.ask(playerId, message.getMessage() + getControllingPlayerHint(playerId), source, addMessageToOptions(message, options));
}
@Override
@ -3050,7 +3064,7 @@ public abstract class GameImpl implements Game {
if (object != null) {
objectName = object.getName();
}
playerQueryEventSource.chooseAbility(playerId, message, objectName, choices);
playerQueryEventSource.chooseAbility(playerId, message + getControllingPlayerHint(playerId), objectName, choices);
}
@Override
@ -3058,7 +3072,7 @@ public abstract class GameImpl implements Game {
if (simulation) {
return;
}
playerQueryEventSource.chooseMode(playerId, message, modes);
playerQueryEventSource.chooseMode(playerId, message + getControllingPlayerHint(playerId), modes);
}
@Override
@ -3066,7 +3080,7 @@ public abstract class GameImpl implements Game {
if (simulation) {
return;
}
playerQueryEventSource.target(playerId, message.getMessage(), targets, required, addMessageToOptions(message, options));
playerQueryEventSource.target(playerId, message.getMessage() + getControllingPlayerHint(playerId), targets, required, addMessageToOptions(message, options));
}
@Override
@ -3074,7 +3088,7 @@ public abstract class GameImpl implements Game {
if (simulation) {
return;
}
playerQueryEventSource.target(playerId, message.getMessage(), cards, required, addMessageToOptions(message, options));
playerQueryEventSource.target(playerId, message.getMessage() + getControllingPlayerHint(playerId), cards, required, addMessageToOptions(message, options));
}
/**
@ -3087,7 +3101,7 @@ public abstract class GameImpl implements Game {
*/
@Override
public void fireSelectTargetTriggeredAbilityEvent(UUID playerId, String message, List<TriggeredAbility> abilities) {
playerQueryEventSource.target(playerId, message, abilities);
playerQueryEventSource.target(playerId, message + getControllingPlayerHint(playerId), abilities);
}
@Override
@ -3095,7 +3109,7 @@ public abstract class GameImpl implements Game {
if (simulation) {
return;
}
playerQueryEventSource.target(playerId, message, perms, required);
playerQueryEventSource.target(playerId, message + getControllingPlayerHint(playerId), perms, required);
}
@Override
@ -3103,7 +3117,7 @@ public abstract class GameImpl implements Game {
if (simulation) {
return;
}
playerQueryEventSource.amount(playerId, message, min, max);
playerQueryEventSource.amount(playerId, message + getControllingPlayerHint(playerId), min, max);
}
@Override
@ -3128,7 +3142,7 @@ public abstract class GameImpl implements Game {
if (simulation) {
return;
}
playerQueryEventSource.choosePile(playerId, message, pile1, pile2);
playerQueryEventSource.choosePile(playerId, message + getControllingPlayerHint(playerId), pile1, pile2);
}
@Override