Search in sources :

Example 1 with SOCSetTurn

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;
}
Also used : SOCGameState(soc.message.SOCGameState) Connection(soc.server.genericServer.Connection) ArrayList(java.util.ArrayList) SOCRollDicePrompt(soc.message.SOCRollDicePrompt) SOCGameElements(soc.message.SOCGameElements) SOCSetTurn(soc.message.SOCSetTurn)

Aggregations

ArrayList (java.util.ArrayList)1 SOCGameElements (soc.message.SOCGameElements)1 SOCGameState (soc.message.SOCGameState)1 SOCRollDicePrompt (soc.message.SOCRollDicePrompt)1 SOCSetTurn (soc.message.SOCSetTurn)1 Connection (soc.server.genericServer.Connection)1