|
|
|
@ -1,7 +1,7 @@
|
|
|
|
|
package eu.jonahbauer.wizard.client.libgdx.state;
|
|
|
|
|
|
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.Client;
|
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.actors.game.overlay.InteractionOverlay;
|
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.actions.overlay.InteractionOverlay;
|
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen;
|
|
|
|
|
import eu.jonahbauer.wizard.client.libgdx.util.Pair;
|
|
|
|
|
import eu.jonahbauer.wizard.common.messages.client.InteractionMessage;
|
|
|
|
@ -14,10 +14,15 @@ import eu.jonahbauer.wizard.common.messages.server.GameMessage;
|
|
|
|
|
import eu.jonahbauer.wizard.common.messages.server.NackMessage;
|
|
|
|
|
import eu.jonahbauer.wizard.common.messages.server.ServerMessage;
|
|
|
|
|
import eu.jonahbauer.wizard.common.model.Card;
|
|
|
|
|
import eu.jonahbauer.wizard.common.model.Configuration;
|
|
|
|
|
import lombok.Data;
|
|
|
|
|
import lombok.Getter;
|
|
|
|
|
import lombok.experimental.Accessors;
|
|
|
|
|
import lombok.extern.log4j.Log4j2;
|
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
|
import org.jetbrains.annotations.Range;
|
|
|
|
|
import org.jetbrains.annotations.Unmodifiable;
|
|
|
|
|
|
|
|
|
|
import java.lang.ref.WeakReference;
|
|
|
|
|
import java.time.Instant;
|
|
|
|
@ -34,6 +39,7 @@ public final class Game extends BaseState {
|
|
|
|
|
private final UUID self;
|
|
|
|
|
private final UUID session;
|
|
|
|
|
private final String sessionName;
|
|
|
|
|
private final Configuration configuration;
|
|
|
|
|
private final String secret;
|
|
|
|
|
|
|
|
|
|
private final LinkedHashMap<UUID, String> players;
|
|
|
|
@ -59,10 +65,11 @@ public final class Game extends BaseState {
|
|
|
|
|
private Card juggleCard;
|
|
|
|
|
private boolean werewolf;
|
|
|
|
|
|
|
|
|
|
public Game(UUID self, UUID session, String sessionName, String secret, LinkedHashMap<UUID, String> players) {
|
|
|
|
|
public Game(UUID self, UUID session, String sessionName, Configuration configuration, String secret, LinkedHashMap<UUID, String> players) {
|
|
|
|
|
this.self = self;
|
|
|
|
|
this.session = session;
|
|
|
|
|
this.sessionName = sessionName;
|
|
|
|
|
this.configuration = configuration;
|
|
|
|
|
this.secret = secret;
|
|
|
|
|
this.players = players;
|
|
|
|
|
}
|
|
|
|
@ -117,12 +124,12 @@ public final class Game extends BaseState {
|
|
|
|
|
}
|
|
|
|
|
return Optional.empty();
|
|
|
|
|
} else if (message instanceof NackMessage nack) {
|
|
|
|
|
return onNackMessage(client, message, nack);
|
|
|
|
|
return onNackMessage(nack);
|
|
|
|
|
} else if (message instanceof AckMessage) {
|
|
|
|
|
onAckMessage();
|
|
|
|
|
return Optional.empty();
|
|
|
|
|
} else {
|
|
|
|
|
return unexpectedMessage(client, message);
|
|
|
|
|
return unexpectedMessage(message);
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
if (pendingClearActivePlayer > 0 && --pendingClearActivePlayer == 0) {
|
|
|
|
@ -165,7 +172,7 @@ public final class Game extends BaseState {
|
|
|
|
|
log.error("The game has finished with an error.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void onHandMessage(UUID player, List<Card> hand) {
|
|
|
|
|
private void onHandMessage(@NotNull UUID player, @Unmodifiable @NotNull List<@NotNull Card> hand) {
|
|
|
|
|
checkPlayer(player);
|
|
|
|
|
log.info("{} hand cards are: {}", nameOf(player, true, true), hand);
|
|
|
|
|
|
|
|
|
@ -178,7 +185,7 @@ public final class Game extends BaseState {
|
|
|
|
|
juggling = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void onPredictionMessage(UUID player, int prediction) {
|
|
|
|
|
private void onPredictionMessage(@NotNull UUID player, @Range(from = 0, to = Integer.MAX_VALUE) int prediction) {
|
|
|
|
|
checkPlayer(player);
|
|
|
|
|
checkActivePlayer(player, MAKE_PREDICTION, CHANGE_PREDICTION);
|
|
|
|
|
log.info("{} predicted: {}", nameOf(player, true, false), prediction);
|
|
|
|
@ -190,13 +197,13 @@ public final class Game extends BaseState {
|
|
|
|
|
gameScreen.addPrediction(round, player, prediction, changed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void onTrumpMessage(Card trumpCard, Card.Suit trumpSuit) {
|
|
|
|
|
private void onTrumpMessage(@Nullable Card trumpCard, @Nullable Card.Suit trumpSuit) {
|
|
|
|
|
if (trumpCard == null) {
|
|
|
|
|
log.info("There is no trump in this round.");
|
|
|
|
|
} else {
|
|
|
|
|
log.info("The trump suit is {} ({}).", trumpSuit != null ? trumpSuit : "yet to be determined.", trumpCard);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var player = currentInteraction != null && currentInteraction.action() == PICK_TRUMP ? currentInteraction.player() : null;
|
|
|
|
|
finishInteraction();
|
|
|
|
|
|
|
|
|
|
this.trumpCard = trumpCard;
|
|
|
|
@ -205,11 +212,11 @@ public final class Game extends BaseState {
|
|
|
|
|
werewolf = true;
|
|
|
|
|
} else {
|
|
|
|
|
werewolf = false;
|
|
|
|
|
gameScreen.showTrumpOverlay(null, trumpCard, trumpSuit);
|
|
|
|
|
gameScreen.showTrumpOverlay(player, trumpCard, trumpSuit);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void onTrickMessage(UUID player, List<Card> cards) {
|
|
|
|
|
private void onTrickMessage(@NotNull UUID player, @Unmodifiable @NotNull List<@NotNull Card> cards) {
|
|
|
|
|
checkPlayer(player);
|
|
|
|
|
log.info("This trick {} goes to {}.", cards, nameOf(player));
|
|
|
|
|
|
|
|
|
@ -219,7 +226,7 @@ public final class Game extends BaseState {
|
|
|
|
|
gameScreen.finishTrick(player);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void onCardMessage(UUID player, Card card) {
|
|
|
|
|
private void onCardMessage(@NotNull UUID player, @NotNull Card card) {
|
|
|
|
|
checkPlayer(player);
|
|
|
|
|
checkActivePlayer(player, PLAY_CARD);
|
|
|
|
|
log.info("{} played {}.", nameOf(player, true, false), card);
|
|
|
|
@ -242,14 +249,14 @@ public final class Game extends BaseState {
|
|
|
|
|
gameScreen.playCard(player, handCard);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void onScoreMessage(Map<UUID, Integer> points) {
|
|
|
|
|
private void onScoreMessage(@Unmodifiable Map<@NotNull UUID, @NotNull Integer> points) {
|
|
|
|
|
log.info("The scores are as follows: " + points);
|
|
|
|
|
points.forEach((player, p) -> scores.merge(player, p, Integer::sum));
|
|
|
|
|
gameScreen.addScores(round, points);
|
|
|
|
|
gameScreen.showScoreOverlay();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void onUserInputMessage(UUID player, UserInputMessage.Action action, long timeout) {
|
|
|
|
|
private void onUserInputMessage(@Nullable UUID player, @NotNull UserInputMessage.Action action, long timeout) {
|
|
|
|
|
checkPlayer(player);
|
|
|
|
|
log.info(
|
|
|
|
|
"Waiting for input {} from {}. (times out at {})",
|
|
|
|
@ -264,7 +271,7 @@ public final class Game extends BaseState {
|
|
|
|
|
currentInteraction = new Interaction(player, action, timeout);
|
|
|
|
|
gameScreen.setActivePlayer(player, action, timeout);
|
|
|
|
|
|
|
|
|
|
if (werewolf && action == PICK_TRUMP) {
|
|
|
|
|
if (player != null && werewolf && action == PICK_TRUMP) {
|
|
|
|
|
gameScreen.swapTrumpCard(player);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -289,7 +296,7 @@ public final class Game extends BaseState {
|
|
|
|
|
gameScreen.timeout();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Optional<ClientState> onNackMessage(Client client, ServerMessage message, NackMessage nack) {
|
|
|
|
|
private Optional<ClientState> onNackMessage(@NotNull NackMessage nack) {
|
|
|
|
|
sending.set(false);
|
|
|
|
|
|
|
|
|
|
if (isActive() && currentInteraction.action() == JUGGLE_CARD && juggleCard != null) {
|
|
|
|
@ -303,7 +310,7 @@ public final class Game extends BaseState {
|
|
|
|
|
gameScreen.ready(false);
|
|
|
|
|
return Optional.empty();
|
|
|
|
|
} else {
|
|
|
|
|
return unexpectedMessage(client, message);
|
|
|
|
|
return unexpectedMessage(nack);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -321,7 +328,7 @@ public final class Game extends BaseState {
|
|
|
|
|
//</editor-fold>
|
|
|
|
|
|
|
|
|
|
//<editor-fold desc="Screen Callbacks" defaultstate="collapsed">
|
|
|
|
|
public Optional<ClientState> onCardClicked(Client client, Card card) {
|
|
|
|
|
public Optional<ClientState> onCardClicked(Client client, @NotNull Card card) {
|
|
|
|
|
if (isActive()) {
|
|
|
|
|
if (currentInteraction.action() == PLAY_CARD) {
|
|
|
|
|
if (card == Card.CLOUD || card == Card.JUGGLER) {
|
|
|
|
@ -342,7 +349,7 @@ public final class Game extends BaseState {
|
|
|
|
|
return Optional.empty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Optional<ClientState> onSuitClicked(Client client, Card.Suit suit) {
|
|
|
|
|
public Optional<ClientState> onSuitClicked(Client client, @NotNull Card.Suit suit) {
|
|
|
|
|
if (isActive() && currentInteraction.action() == PICK_TRUMP) {
|
|
|
|
|
send(client, new PickTrumpMessage(suit));
|
|
|
|
|
} else {
|
|
|
|
@ -371,7 +378,7 @@ public final class Game extends BaseState {
|
|
|
|
|
|
|
|
|
|
private Optional<ClientState> returnToSession() {
|
|
|
|
|
return Optional.of(new Session(
|
|
|
|
|
new SessionData(session, sessionName, -1, null),
|
|
|
|
|
new SessionData(session, sessionName, -1, configuration),
|
|
|
|
|
players.entrySet().stream()
|
|
|
|
|
.map(entry -> new PlayerData(entry.getKey(), entry.getValue(), false))
|
|
|
|
|
.toList(),
|
|
|
|
|