diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/MakePredictionOverlay.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/MakePredictionOverlay.java index 89cc725..bd17cc5 100644 --- a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/MakePredictionOverlay.java +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/MakePredictionOverlay.java @@ -30,7 +30,7 @@ public class MakePredictionOverlay extends Overlay implements InteractionOverlay public VerticalGroup createContent() { var root = new VerticalGroup().columnCenter().space(10); - var prompt = new Label("Please make your prediction:", data.skin); + var prompt = new Label(messages.get("game.overlay.make_prediction.prompt"), data.skin); var buttonGroup = new HorizontalGroup().space(20); var listener = new ChangeListener() { diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/Overlay.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/Overlay.java index c9c4d78..3d7ea1c 100644 --- a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/Overlay.java +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/Overlay.java @@ -6,6 +6,7 @@ import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.scenes.scene2d.*; import com.badlogic.gdx.scenes.scene2d.ui.Container; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.I18NBundle; import eu.jonahbauer.wizard.client.libgdx.UiskinAtlas; import eu.jonahbauer.wizard.client.libgdx.WizardGame; import eu.jonahbauer.wizard.client.libgdx.screens.GameScreen; @@ -17,6 +18,7 @@ public abstract class Overlay extends Action { protected final GameScreen screen; protected final WizardGame.Data data; + protected final I18NBundle messages; protected final TextureAtlas atlas; private long timeout; @@ -27,6 +29,7 @@ public abstract class Overlay extends Action { public Overlay(GameScreen gameScreen, long timeout) { this.screen = gameScreen; this.data = gameScreen.getData(); + this.messages = gameScreen.getMessages(); this.atlas = gameScreen.getAtlas(); this.timeout = timeout; } diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/PickTrumpOverlay.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/PickTrumpOverlay.java index c7c48a3..24b2bf4 100644 --- a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/PickTrumpOverlay.java +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/PickTrumpOverlay.java @@ -28,7 +28,7 @@ public class PickTrumpOverlay extends Overlay implements InteractionOverlay { public Actor createContent() { var root = new VerticalGroup().columnCenter().space(10); - var prompt = new Label("Please choose the trump suit:", data.skin); + var prompt = new Label(messages.get("game.overlay.pick_trump.prompt"), data.skin); var cardGroup = new HorizontalGroup().space(20); cards.put(Card.Suit.RED, new CardActor(Card.Suit.RED, atlas)); diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/StartRoundOverlay.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/StartRoundOverlay.java index 01de769..1513a82 100644 --- a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/StartRoundOverlay.java +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/StartRoundOverlay.java @@ -23,7 +23,7 @@ public class StartRoundOverlay extends Overlay { public Actor createContent() { var root = new VerticalGroup().columnCenter().space(10f); - var label = new Label("Round " + (round + 1), data.skin, "enchanted"); + var label = new Label(messages.format("game.overlay.round.title", round + 1), data.skin, "enchanted"); label.setFontScale(1.5f); root.addActor(label); diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/TrumpOverlay.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/TrumpOverlay.java index 506354f..415b55c 100644 --- a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/TrumpOverlay.java +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/actors/game/overlay/TrumpOverlay.java @@ -100,21 +100,21 @@ public class TrumpOverlay extends Overlay { String text; if (player == null) { - text = suit != null ? switch (suit) { - case YELLOW -> "The trump suit is [#ffff00]yellow[#ffffff]."; - case GREEN -> "The trump suit is [#00ff00]green[#ffffff]."; - case BLUE -> "The trump suit is [#0000ff]blue[#ffffff]."; - case RED -> "The trump suit is [#ff0000]red[#ffffff]."; - default -> "There is no trump suit."; - } : "To be determined."; + text = messages.get(suit != null ? switch (suit) { + case YELLOW -> "game.overlay.trump.yellow"; + case GREEN -> "game.overlay.trump.green"; + case BLUE -> "game.overlay.trump.blue"; + case RED -> "game.overlay.trump.red"; + default -> "game.overlay.trump.none"; + } : "game.overlay.trump.unknown"); } else { - text = player + (suit != null ? switch (suit) { - case YELLOW -> " chose the trump suit [#ffff00]yellow[#ffffff]."; - case GREEN -> " chose the trump suit [#00ff00]green[#ffffff]."; - case BLUE -> " chose the trump suit [#0000ff]blue[#ffffff]."; - case RED -> " chose the trump suit [#ff0000]red[#ffffff]."; - default -> " has decided there will be no trump suit this round."; - } : " to be determined."); + text = messages.format(suit != null ? switch (suit) { + case YELLOW -> "game.overlay.trump.yellow.player"; + case GREEN -> "game.overlay.trump.green.player"; + case BLUE -> "game.overlay.trump.blue.player"; + case RED -> "game.overlay.trump.red.player"; + default -> "game.overlay.trump.none.player"; + } : "game.overlay.trump.unknown.player", player); } var label = new Label(text, data.skin); @@ -158,7 +158,7 @@ public class TrumpOverlay extends Overlay { )); } - if (suit != null) { + if (suit != DEFAULT_SUITES.get(card)) { cardAnimation.addAction(sequence( targeting(trumpSuitActor, removeActorSilently()), targeting(trumpSuitActor, changeParent(parent)), diff --git a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/GameScreen.java b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/GameScreen.java index e89db6c..1528eb8 100644 --- a/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/GameScreen.java +++ b/wizard-client/wizard-client-libgdx/core/src/main/java/eu/jonahbauer/wizard/client/libgdx/screens/GameScreen.java @@ -10,6 +10,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.I18NBundle; import eu.jonahbauer.wizard.client.libgdx.GameAtlas; import eu.jonahbauer.wizard.client.libgdx.WizardGame; import eu.jonahbauer.wizard.client.libgdx.actors.game.CardActor; @@ -26,6 +27,7 @@ import eu.jonahbauer.wizard.common.messages.player.PlayCardMessage; import eu.jonahbauer.wizard.common.messages.player.PlayerMessage; import eu.jonahbauer.wizard.common.model.Card; import lombok.Getter; +import org.jetbrains.annotations.Nls; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; @@ -273,11 +275,19 @@ public class GameScreen extends MenuScreen { } public void addPrediction(int round, UUID player, int prediction) { + boolean changed = false; if (activePlayer != null && activePlayer.first().equals(player) && (activePlayer.second() == CHANGE_PREDICTION || activePlayer.second() == MAKE_PREDICTION)) { + changed = activePlayer.second() == CHANGE_PREDICTION; setActivePlayer(null, null, 0); } - addMessage(state.getPlayers().get(player) + " predicted " + prediction + "."); + if (state.getSelf().equals(player)) { + addMessage(game.messages.format("game.action." + (changed ? "change" : "make") + "_prediction.self", prediction)); + } else { + var name = state.getPlayers().get(player); + addMessage(game.messages.format("game.action." + (changed ? "change" : "make") + "_prediction.other", name, prediction)); + } + execute(() -> padOfTruth.setPrediction(players.indexOf(player), round, prediction)); } @@ -286,7 +296,12 @@ public class GameScreen extends MenuScreen { setActivePlayer(null, null, 0); } - addMessage(state.getPlayers().get(player) + " played a card."); + if (state.getSelf().equals(player)) { + addMessage(game.messages.get("game.action.play_card.self")); + } else { + var name = state.getPlayers().get(player); + addMessage(game.messages.format("game.action.play_card.other", name)); + } Seat seat = seats.get(player); @@ -318,6 +333,9 @@ public class GameScreen extends MenuScreen { } public void setActivePlayer(UUID player, UserInputMessage.Action action, long timeout) { + if (action == SYNC) throw new IllegalArgumentException(); + + // reset label color if (activePlayer != null && nameLabels.containsKey(activePlayer.getKey())) { var label = nameLabels.get(activePlayer.getKey()); execute(() -> label.setStyle(labelStyleDefault)); @@ -330,38 +348,47 @@ public class GameScreen extends MenuScreen { } activePlayer = Pair.of(player, action); + // set label color if (nameLabels.containsKey(player)) { var label = nameLabels.get(player); execute(() -> label.setStyle(labelStyleActive)); } if (state.getSelf().equals(player)) { + // show interface setPersistentMessage(null); switch (action) { case PICK_TRUMP -> execute(new PickTrumpOverlay(this, timeout, false)); case MAKE_PREDICTION -> execute(new MakePredictionOverlay(this, timeout, state.getRound())); case CHANGE_PREDICTION -> execute(new ChangePredictionOverlay(this, timeout, state.getRound(), state.getPredictions().get(state.getSelf()))); - case PLAY_CARD -> setPersistentMessage("It is your turn to play a card."); + case PLAY_CARD -> setPersistentMessage(game.messages.get("game.message.play_card.self")); } // TODO do something } else { - var name = state.getPlayers().get(player); - setPersistentMessage("It is " + name + "'s turn to " + switch (action) { - case CHANGE_PREDICTION -> "change their prediction"; - case JUGGLE_CARD -> "juggle a card"; - case PLAY_CARD -> "play a card"; - case PICK_TRUMP -> "pick the trump suit"; - case MAKE_PREDICTION -> "make a prediction"; + // show message + var key = switch (action) { + case CHANGE_PREDICTION -> "game.message.change_prediction."; + case JUGGLE_CARD -> "game.message.juggle_card."; + case MAKE_PREDICTION -> "game.message.make_prediction."; + case PICK_TRUMP -> "game.message.pick_trump."; + case PLAY_CARD -> "game.message.play_card."; default -> throw new AssertionError(); - }); + }; + + if (player == null) { + setPersistentMessage(game.messages.get(key + "all")); + } else { + var name = state.getPlayers().get(player); + setPersistentMessage(game.messages.format(key + "other", name)); + } } } - public void addMessage(String text) { + public void addMessage(@Nls String text) { addMessage(text, false); } - public void addMessage(String text, boolean immediate) { + public void addMessage(@Nls String text, boolean immediate) { var label = new Label(text, game.data.skin); label.addAction(sequence( delay(1.5f), @@ -384,7 +411,7 @@ public class GameScreen extends MenuScreen { } } - public void setPersistentMessage(String text) { + public void setPersistentMessage(@Nls String text) { execute(() -> { if (text != null) { if (persistentMessage == null) { @@ -418,7 +445,7 @@ public class GameScreen extends MenuScreen { } public void timeout() { - addMessage("Timed out."); + addMessage(game.messages.get("game.message.timeout")); ready(true); } @@ -436,6 +463,10 @@ public class GameScreen extends MenuScreen { return game.data; } + public I18NBundle getMessages() { + return game.messages; + } + @Getter public enum Seat { BOTTOM(WizardGame.WIDTH * 0.5f, 0, 0, 0, Align.bottom, WizardGame.WIDTH * 0.5f, 300), diff --git a/wizard-client/wizard-client-libgdx/core/src/main/resources/i18n/messages.properties b/wizard-client/wizard-client-libgdx/core/src/main/resources/i18n/messages.properties index f6f4c17..fea1b9b 100644 --- a/wizard-client/wizard-client-libgdx/core/src/main/resources/i18n/messages.properties +++ b/wizard-client/wizard-client-libgdx/core/src/main/resources/i18n/messages.properties @@ -1,3 +1,4 @@ +# suppress inspection "UnusedProperty" for whole file menu.main.play=Play menu.main.quit=Close @@ -35,4 +36,54 @@ menu.waiting.leave=Leave menu.waiting.player_name.label=Own Name menu.waiting.session_name.label=Session Name menu.waiting.session_uuid.label=Session UUID -menu.waiting.session_configuration.label=Configuration \ No newline at end of file +menu.waiting.session_configuration.label=Configuration + + +game.message.play_card.other=It is {0}'s turn to play a card +game.message.play_card.all=Everybody must play a card +game.message.play_card.self=It is your turn to play a card + +game.message.juggle_card.other=It is {0}'s turn to juggle a card +game.message.juggle_card.all=Everybody must juggle a card +game.message.juggle_card.self=It is your turn to juggle a card + +game.message.pick_trump.other=It is {0}'s turn to pick the trump suit +game.message.pick_trump.all=Everybody must pick the trump suit +game.message.pick_trump.self=It is your turn to pick the trump suit + +game.message.make_prediction.other=It is {0}'s turn to make a prediction +game.message.make_prediction.all=Everybody must make a prediction +game.message.make_prediction.self=It is your turn to make a prediction + +game.message.change_prediction.other=It is {0}'s turn to change their prediction +game.message.change_prediction.all=Everybody must change their prediction +game.message.change_prediction.self=It is your turn to change your prediction + +game.message.timeout=Timed out + +game.action.play_card.other={0} played a card +game.action.play_card.self=You played a card + +game.action.make_prediction.other={0} predicted {1} +game.action.make_prediction.self=You predicted {0} + +game.action.change_prediction.other={0} changed their prediction to {1} +game.action.change_prediction.self=You changed your prediction to {0} + +game.overlay.make_prediction.prompt=Please make your prediction +game.overlay.pick_trump.prompt=Please choose the trump suit + +game.overlay.round.title=Round {0} + +game.overlay.trump.yellow=The trump suit is [#ffff00]yellow[#ffffff] +game.overlay.trump.green=The trump suit is [#00ff00]green[#ffffff] +game.overlay.trump.blue=The trump suit is [#0000ff]blue[#ffffff] +game.overlay.trump.red=The trump suit is [#ff0000]red[#ffffff] +game.overlay.trump.none=There is no trump suit +game.overlay.trump.unknown=The trump suit is yet to be determined +game.overlay.trump.yellow.player={0} choose the trump suit [#ffff00]yellow[#ffffff] +game.overlay.trump.green.player={0} choose the trump suit [#00ff00]green[#ffffff] +game.overlay.trump.blue.player={0} choose the trump suit [#0000ff]blue[#ffffff] +game.overlay.trump.red.player={0} choose the trump suit [#ff0000]red[#ffffff] +game.overlay.trump.none.player={0} has decided there will be no trump suit this round +game.overlay.trump.unknown.player=The trump suit is yet to be determined by {0} \ No newline at end of file diff --git a/wizard-client/wizard-client-libgdx/core/src/main/resources/i18n/messages_de.properties b/wizard-client/wizard-client-libgdx/core/src/main/resources/i18n/messages_de.properties index 7a4d06b..86f67dc 100644 --- a/wizard-client/wizard-client-libgdx/core/src/main/resources/i18n/messages_de.properties +++ b/wizard-client/wizard-client-libgdx/core/src/main/resources/i18n/messages_de.properties @@ -1,3 +1,4 @@ +# suppress inspection "UnusedProperty" for whole file menu.main.play=Spiel beitreten menu.main.quit=Verlassen @@ -35,4 +36,54 @@ menu.waiting.leave=Verlassen menu.waiting.player_name.label=Eigener Name menu.waiting.session_name.label=Sitzungsname menu.waiting.session_uuid.label=Sitzungs-ID -menu.waiting.session_configuration.label=Spielvariante \ No newline at end of file +menu.waiting.session_configuration.label=Spielvariante + + +game.message.play_card.other={0} muss eine Karte spielen +game.message.play_card.all=Jeder muss eine Karte spielen +game.message.play_card.self=Du musst eine Karte spielen + +game.message.juggle_card.other={0} muss eine Karte jonglieren +game.message.juggle_card.all=Jeder muss eine Karte jonglieren +game.message.juggle_card.self=Du musst eine Karte jonglieren + +game.message.pick_trump.other={0} muss die Trumpffarbe bestimmen +game.message.pick_trump.all=Jeder muss die Trumpffarbe bestimmen +game.message.pick_trump.self=Du musst die Trumpffarbe bestimmen + +game.message.make_prediction.other={0} muss eine Vorhersage treffen +game.message.make_prediction.all=Jeder muss eine Vorhersage treffen +game.message.make_prediction.self=Du musst eine Vorhersage treffen + +game.message.change_prediction.other={0} muss seine Vorhersage ändern +game.message.change_prediction.all=Jeder muss seine Vorhersage ändern +game.message.change_prediction.self=Du musst deine Vorhersage ändern + +game.message.timeout=Zeit abgelaufen + +game.action.play_card.other={0} hat eine Karte gespielt +game.action.play_card.self=Du hast eine Karte gespielt + +game.action.make_prediction.other={0} hat {1} vorhergesagt +game.action.make_prediction.self=Du hast {0} vorhergesagt + +game.action.change_prediction.other={0} hat seine Vorhersage auf {1} geändert +game.action.change_prediction.self=Du hast deine Vorhersage auf {0} geändert + +game.overlay.make_prediction.prompt=Triff eine Vorhersage +game.overlay.pick_trump.prompt=Wähle die Trumpffarbe + +game.overlay.round.title=Runde {0} + +game.overlay.trump.yellow=Die Trumpffarbe ist [#ffff00]gelb[#ffffff] +game.overlay.trump.green=Die Trumpffarbe ist [#00ff00]grün[#ffffff] +game.overlay.trump.blue=Die Trumpffarbe ist [#0000ff]blau[#ffffff] +game.overlay.trump.red=Die Trumpffarbe ist [#ff0000]rot[#ffffff] +game.overlay.trump.none=Es gibt keine Trumpffarbe +game.overlay.trump.unknown=Die Trumpffarbe muss noch bestimmt werden +game.overlay.trump.yellow.player={0} hat die Trumpffarbe [#ffff00]gelb[#ffffff] gewählt +game.overlay.trump.green.player={0} hat die Trumpffarbe [#00ff00]grün[#ffffff] gewählt +game.overlay.trump.blue.player={0} hat die Trumpffarbe [#0000ff]blau[#ffffff] gewählt +game.overlay.trump.red.player={0} hat die Trumpffarbe [#ff0000]rot[#ffffff] gewählt +game.overlay.trump.none.player={0} hat entschieden, dass es diese Runde keinen Trump geben wird +game.overlay.trump.unknown.player={0} muss die Trumpffarbe muss noch bestimmen \ No newline at end of file