use of soc.message.SOCSetTurn in project JSettlers2 by jdmonin.
the class SOCGameHandler method sendGameState.
/**
* Send all game members the current state of the game with a message.
* May also send other messages to the current player.
* Note that the current (or new) player number is not sent here.
* If game is now OVER, sends appropriate messages.
*<P>
* State {@link SOCGame#WAITING_FOR_DISCARDS}:
* If a 7 is rolled, will also say who must discard (in a GAMETEXTMSG).
*<P>
* State {@link SOCGame#WAITING_FOR_ROB_CHOOSE_PLAYER}:
* If current player must choose which player to rob,
* will also prompt their client to choose (in a CHOOSEPLAYERREQUEST).
*<P>
* State {@link SOCGame#STARTS_WAITING_FOR_PICK_GOLD_RESOURCE}:
* To announce the player must pick a resource to gain from the gold hex initial placement,
* please call {@link #sendGameState_sendGoldPickAnnounceText(SOCGame, String, Connection, SOCGame.RollResult)}.
*<P>
* State {@link SOCGame#WAITING_FOR_PICK_GOLD_RESOURCE}:
* If a gold hex is rolled, does not say who
* must pick resources to gain (because of timing). Please call
* {@link #sendGameState_sendGoldPickAnnounceText(SOCGame, String, Connection, SOCGame.RollResult)}
* after sending the resource gain text ("x gets 1 sheep").
*<P>
* <b>Note:</b> If game is now {@link SOCGame#OVER OVER} and the {@link SOCGame#isBotsOnly} flag is set,
* {@link #sendGameStateOVER(SOCGame)} will call {@link SOCServer#destroyGameAndBroadcast(String, String)}.
* Be sure that callers to {@code sendGameState} don't assume the game will still exist after calling this method.
* Also, {@code destroyGame} might create more {@link SOCGame#isBotsOnly} games, depending on server settings.
*<P>
* <b>Locks:</b> Does not hold {@link SOCGameList#takeMonitor()} or
* {@link SOCGameList#takeMonitorForGame}<tt>(gaName)</tt> when called.
* Some callers call {@link SOCGame#takeMonitor()} before calling; not important here.
*
* @see #sendTurn(SOCGame, boolean)
* @see #sendGameState(SOCGame)
* @see #sendGameStateOVER(SOCGame)
*
* @param ga the game
* @param omitGameStateMessage if true, don't send the {@link SOCGameState} message itself
* but do send any other messages as described above. For use just after sending a message which
* includes a Game State field.
* @param sendRollPrompt If true, and if we send a text message to prompt
* the player to roll, send a RollDicePrompt data message.
* If the client is too old (1.0.6), it will ignore the prompt.
*
* @return did we send a text message to prompt the player to roll?
* If so, sendTurn can also send a RollDicePrompt data message.
* @since 1.1.00
*/
boolean sendGameState(SOCGame ga, final boolean omitGameStateMessage, final boolean sendRollPrompt) {
if (ga == null)
return false;
final int gaState = ga.getGameState();
final int cpn = ga.getCurrentPlayerNumber();
final String gname = ga.getName();
boolean promptedRoll = false;
if (gaState == SOCGame.OVER) {
/**
* Before sending state "OVER", enforce current player number.
* This helps the client's copy of game recognize winning condition.
*/
srv.messageToGame(gname, (ga.clientVersionLowest >= SOCGameElements.MIN_VERSION) ? new SOCGameElements(gname, SOCGameElements.CURRENT_PLAYER, cpn) : new SOCSetTurn(gname, cpn));
}
if (!omitGameStateMessage)
srv.messageToGame(gname, new SOCGameState(gname, gaState));
SOCPlayer player = null;
if (cpn != -1)
player = ga.getPlayer(cpn);
switch(gaState) {
case SOCGame.START1A:
case SOCGame.START2A:
case SOCGame.START3A:
// "It's Joe's turn to build a settlement."
srv.messageToGameKeyed(ga, true, "prompt.turn.to.build.stlmt", player.getName());
if ((gaState >= SOCGame.START2A) && ga.isGameOptionSet(SOCGameOption.K_SC_3IP)) {
// reminder to player before their 2nd, 3rd settlements
Connection con = srv.getConnection(player.getName());
if (con != null) {
srv.messageToPlayerKeyed(con, gname, "prompt.gameopt._SC_3IP.part1");
// "This game gives you 3 initial settlements and roads."
srv.messageToPlayerKeyed(con, gname, "prompt.gameopt._SC_3IP.part2");
// "Your free resources will be from the third settlement."
}
}
break;
case SOCGame.START1B:
case SOCGame.START2B:
case SOCGame.START3B:
srv.messageToGameKeyed(ga, true, (// "It's Joe's turn to build a road or ship."
(ga.hasSeaBoard) ? // "It's Joe's turn to build a road or ship."
"prompt.turn.to.build.road.or.ship" : "prompt.turn.to.build.road"), player.getName());
break;
case SOCGame.ROLL_OR_CARD:
// "It's Joe's turn to roll the dice."
srv.messageToGameKeyed(ga, true, "prompt.turn.to.roll.dice", player.getName());
promptedRoll = true;
if (sendRollPrompt)
srv.messageToGame(gname, new SOCRollDicePrompt(gname, player.getPlayerNumber()));
break;
case SOCGame.WAITING_FOR_DISCARDS:
{
ArrayList<String> names = new ArrayList<String>();
for (int i = 0; i < ga.maxPlayers; i++) if (ga.getPlayer(i).getNeedToDiscard())
names.add(ga.getPlayer(i).getName());
if (names.size() == 1)
// "Joe needs to discard"
srv.messageToGameKeyed(ga, true, "prompt.discard.1", names.get(0));
else
// "Joe and Ed need to discard"
srv.messageToGameKeyedSpecial(ga, true, "prompt.discard.n", names);
}
break;
case SOCGame.WAITING_FOR_ROBBER_OR_PIRATE:
// "{0} must choose to move the robber or the pirate."
srv.messageToGameKeyed(ga, true, "robber.willmove.choose", player.getName());
break;
case SOCGame.PLACING_ROBBER:
// "{0} will move the robber."
srv.messageToGameKeyed(ga, true, "robber.willmove", player.getName());
break;
case SOCGame.PLACING_PIRATE:
// "{0} will move the pirate ship."
srv.messageToGameKeyed(ga, true, "robber.willmove.pirate", player.getName());
break;
case SOCGame.WAITING_FOR_ROB_CHOOSE_PLAYER:
/**
* get the choices from the game
*/
final boolean canStealNone = ga.isGameOptionSet(SOCGameOption.K_SC_PIRI);
boolean[] choices = new boolean[ga.maxPlayers + (canStealNone ? 1 : 0)];
Arrays.fill(choices, false);
if (canStealNone)
choices[ga.maxPlayers] = true;
for (SOCPlayer pl : ga.getPossibleVictims()) choices[pl.getPlayerNumber()] = true;
/**
* ask the current player to choose a player to steal from
*/
Connection con = srv.getConnection(ga.getPlayer(cpn).getName());
if (con != null) {
con.put(SOCChoosePlayerRequest.toCmd(gname, choices));
}
break;
case SOCGame.OVER:
sendGameStateOVER(ga);
break;
}
return promptedRoll;
}
Aggregations