Search in sources :

Example 1 with SOCDevCardCount

use of soc.message.SOCDevCardCount in project JSettlers2 by jdmonin.

the class SOCGameHandler method startGame.

// javadoc inherited from GameHandler
/**
 * {@inheritDoc}
 *<P>
 * If {@link SOCGame#hasSeaBoard}: Once the board is made, send the updated
 * {@link SOCPotentialSettlements potential settlements}.
 *<P>
 * If this code changes, must also update {@link soctest.TestBoardLayouts#testSingleLayout(SOCScenario, int)}.
 */
public void startGame(SOCGame ga) {
    if (ga == null)
        return;
    final String gaName = ga.getName();
    // TODO once multiple handler threads, encapsulate this
    srv.numberOfGamesStarted++;
    /**
     * start the game, place any initial pieces.
     * If anything is added to this game object setup code,
     * update soctest.TestBoardLayouts.testSingleLayout(..).
     */
    // for playerEvent, gameEvent callbacks (since 2.0.00)
    ga.setScenarioEventListener(this);
    ga.startGame();
    // used on sea board; if null, all are legal
    final int[][] legalSeaEdges;
    if (ga.hasSeaBoard) {
        legalSeaEdges = SOCBoardAtServer.getLegalSeaEdges(ga, -1);
        if (legalSeaEdges != null)
            for (int pn = 0; pn < ga.maxPlayers; ++pn) ga.getPlayer(pn).setRestrictedLegalShips(legalSeaEdges[pn]);
        if (ga.isGameOptionSet(SOCGameOption.K_SC_FTRI) || ga.isGameOptionSet(SOCGameOption.K_SC_PIRI)) {
            // scenario has initial pieces
            ((SOCBoardAtServer) (ga.getBoard())).startGame_putInitPieces(ga);
        }
    } else {
        legalSeaEdges = null;
    }
    srv.gameList.takeMonitorForGame(gaName);
    try {
        /**
         * send the board layout
         */
        try {
            srv.messageToGameWithMon(gaName, getBoardLayoutMessage(ga));
        // For scenario option _SC_CLVI, the board layout message
        // includes villages and the general supply cloth count.
        // For _SC_PIRI, it includes the Pirate Path (additional layout part "PP").
        } catch (IllegalArgumentException e) {
            System.err.println("startGame: Cannot send board for " + gaName + ": " + e.getMessage());
            // the enclosing try-finally will releaseMonitorForGame(gaName) before returning
            return;
        }
        if (ga.hasSeaBoard) {
            // See also joinGame which has very similar code.
            // Send the updated Potential/Legal Settlement node list
            // Note: Assumes all players have same potential settlements
            // (sends with playerNumber -1 == all)
            final HashSet<Integer> psList = ga.getPlayer(0).getPotentialSettlements();
            // Some boards may have multiple land areas.
            final HashSet<Integer>[] lan;
            final int pan;
            boolean addedPsList = false;
            final SOCBoardLarge bl = (SOCBoardLarge) ga.getBoard();
            lan = bl.getLandAreasLegalNodes();
            pan = bl.getStartingLandArea();
            if ((lan != null) && (pan != 0) && !lan[pan].equals(psList)) {
                // If potentials != legals[startingLandArea], send as legals[0]
                lan[0] = psList;
                addedPsList = true;
            }
            if (lan == null)
                srv.messageToGameWithMon(gaName, new SOCPotentialSettlements(gaName, -1, new ArrayList<Integer>(psList)));
            else
                srv.messageToGameWithMon(gaName, new SOCPotentialSettlements(gaName, -1, pan, lan, legalSeaEdges));
            if (addedPsList)
                // Undo change to game's copy of landAreasLegalNodes
                lan[0] = null;
        }
        /**
         * send the player info
         */
        boolean sentInitPiecesState = false;
        for (int i = 0; i < ga.maxPlayers; i++) {
            if (ga.isSeatVacant(i))
                continue;
            final SOCPlayer pl = ga.getPlayer(i);
            final int[] counts = new int[(ga.hasSeaBoard) ? 4 : 3];
            counts[0] = pl.getNumPieces(SOCPlayingPiece.ROAD);
            counts[1] = pl.getNumPieces(SOCPlayingPiece.SETTLEMENT);
            counts[2] = pl.getNumPieces(SOCPlayingPiece.CITY);
            if (ga.hasSeaBoard) {
                // Some scenarios like SC_PIRI may place initial pieces at fixed locations.
                // Usually, pieces will be empty.
                final Vector<SOCPlayingPiece> pieces = pl.getPieces();
                if (!pieces.isEmpty()) {
                    if (!sentInitPiecesState) {
                        // Temporary state change, to avoid initial-piece placement actions.
                        // The actual game state will be sent soon.
                        srv.messageToGameWithMon(gaName, new SOCGameState(gaName, SOCGame.READY));
                        sentInitPiecesState = true;
                    }
                    for (SOCPlayingPiece pp : pieces) srv.messageToGameWithMon(gaName, new SOCPutPiece(gaName, i, pp.getType(), pp.getCoordinates()));
                    SOCPlayingPiece pp = pl.getFortress();
                    if (pp != null)
                        srv.messageToGameWithMon(gaName, new SOCPutPiece(gaName, i, pp.getType(), pp.getCoordinates()));
                }
                counts[3] = pl.getNumPieces(SOCPlayingPiece.SHIP);
            }
            if (ga.clientVersionLowest >= SOCPlayerElements.MIN_VERSION)
                srv.messageToGameWithMon(gaName, new SOCPlayerElements(gaName, i, SOCPlayerElement.SET, (ga.hasSeaBoard) ? ELEM_PIECETYPES_SEA : ELEM_PIECETYPES_CLASSIC, counts));
            else
                for (int j = 0; j < counts.length; ++j) srv.messageToGameWithMon(gaName, new SOCPlayerElement(gaName, i, SOCPlayerElement.SET, ELEM_PIECETYPES_SEA[j], counts[j]));
            if (ga.clientVersionLowest < SOCPlayerElement.VERSION_FOR_CARD_ELEMENTS)
                srv.messageToGameWithMon(gaName, new SOCSetPlayedDevCard(gaName, i, false));
        }
        if (ga.clientVersionLowest >= SOCPlayerElement.VERSION_FOR_CARD_ELEMENTS)
            srv.messageToGameWithMon(gaName, new SOCPlayerElement(gaName, -1, SOCPlayerElement.SET, SOCPlayerElement.PLAYED_DEV_CARD_FLAG, 0));
        /**
         * send the number of dev cards
         */
        srv.messageToGameWithMon(gaName, (ga.clientVersionLowest >= SOCGameElements.MIN_VERSION) ? new SOCGameElements(gaName, SOCGameElements.DEV_CARD_COUNT, ga.getNumDevCards()) : new SOCDevCardCount(gaName, ga.getNumDevCards()));
        /**
         * ga.startGame() picks who goes first, but feedback is nice
         */
        srv.messageToGameKeyed(ga, false, // "Randomly picking a starting player..."
        "start.picking.random.starting.player");
    } finally {
        srv.gameList.releaseMonitorForGame(gaName);
    }
    /**
     * send the game state and start the game.
     * send game state and whose turn it is.
     */
    if (ga.clientVersionLowest >= SOCGameState.VERSION_FOR_GAME_STATE_AS_FIELD) {
        srv.messageToGame(gaName, new SOCStartGame(gaName, ga.getGameState()));
        sendTurn(ga, false);
    } else {
        final int cpn = ga.getCurrentPlayerNumber();
        final boolean sendRoll = sendGameState(ga, false, false);
        srv.messageToGame(gaName, new SOCStartGame(gaName, 0));
        srv.messageToGame(gaName, new SOCTurn(gaName, cpn, 0));
        if (sendRoll)
            srv.messageToGame(gaName, new SOCRollDicePrompt(gaName, cpn));
    }
}
Also used : SOCGameState(soc.message.SOCGameState) SOCPotentialSettlements(soc.message.SOCPotentialSettlements) SOCTurn(soc.message.SOCTurn) SOCRollDicePrompt(soc.message.SOCRollDicePrompt) SOCPlayerElement(soc.message.SOCPlayerElement) SOCSetPlayedDevCard(soc.message.SOCSetPlayedDevCard) HashSet(java.util.HashSet) SOCStartGame(soc.message.SOCStartGame) SOCPlayerElements(soc.message.SOCPlayerElements) SOCPutPiece(soc.message.SOCPutPiece) SOCGameElements(soc.message.SOCGameElements) SOCDevCardCount(soc.message.SOCDevCardCount)

Aggregations

HashSet (java.util.HashSet)1 SOCDevCardCount (soc.message.SOCDevCardCount)1 SOCGameElements (soc.message.SOCGameElements)1 SOCGameState (soc.message.SOCGameState)1 SOCPlayerElement (soc.message.SOCPlayerElement)1 SOCPlayerElements (soc.message.SOCPlayerElements)1 SOCPotentialSettlements (soc.message.SOCPotentialSettlements)1 SOCPutPiece (soc.message.SOCPutPiece)1 SOCRollDicePrompt (soc.message.SOCRollDicePrompt)1 SOCSetPlayedDevCard (soc.message.SOCSetPlayedDevCard)1 SOCStartGame (soc.message.SOCStartGame)1 SOCTurn (soc.message.SOCTurn)1