Search in sources :

Example 1 with SOCPlayer

use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.

the class SOCGameMessageHandler method handlePUTPIECE.

/**
 * handle "put piece" message.
 *<P>
 * Because the current player changes during initial placement,
 * this method has a simplified version of some of the logic from
 * {@link SOCGameHandler#endGameTurn(SOCGame, SOCPlayer, boolean)}
 * to detect and announce the new turn.
 *
 * @param c  the connection that sent the message
 * @param mes  the message
 * @since 1.0.0
 */
private void handlePUTPIECE(SOCGame ga, Connection c, SOCPutPiece mes) {
    ga.takeMonitor();
    try {
        final String gaName = ga.getName();
        final String plName = c.getData();
        SOCPlayer player = ga.getPlayer(plName);
        /**
         * make sure the player can do it
         */
        if (handler.checkTurn(c, ga)) {
            boolean sendDenyReply = false;
            /*
                   if (D.ebugOn) {
                   D.ebugPrintln("BEFORE");
                   for (int pn = 0; pn < SOCGame.MAXPLAYERS; pn++) {
                   SOCPlayer tmpPlayer = ga.getPlayer(pn);
                   D.ebugPrintln("Player # "+pn);
                   for (int i = 0x22; i < 0xCC; i++) {
                   if (tmpPlayer.isPotentialRoad(i))
                   D.ebugPrintln("### POTENTIAL ROAD AT "+Integer.toHexString(i));
                   }
                   }
                   }
                 */
            int gameState = ga.getGameState();
            final int coord = mes.getCoordinates();
            final int pieceType = mes.getPieceType();
            final int pn = player.getPlayerNumber();
            final boolean isBuyAndPut = (gameState == SOCGame.PLAY1) || (gameState == SOCGame.SPECIAL_BUILDING);
            if (isBuyAndPut) {
                if (!handleBUILDREQUEST(ga, player, c, pieceType, false)) {
                    // <--- Can't build right now ---
                    return;
                // will call ga.releaseMonitor() in finally-block before returning
                }
                // updated by handleBUILDREQUEST
                gameState = ga.getGameState();
            }
            switch(pieceType) {
                case SOCPlayingPiece.ROAD:
                    if ((gameState == SOCGame.START1B) || (gameState == SOCGame.START2B) || (gameState == SOCGame.START3B) || (gameState == SOCGame.PLACING_ROAD) || (gameState == SOCGame.PLACING_FREE_ROAD1) || (gameState == SOCGame.PLACING_FREE_ROAD2)) {
                        if (player.isPotentialRoad(coord) && (player.getNumPieces(SOCPlayingPiece.ROAD) >= 1)) {
                            final SOCRoad rd = new SOCRoad(player, coord, null);
                            // Changes game state and (if initial placement) player
                            ga.putPiece(rd);
                            // If placing this piece reveals a fog hex, putPiece will call srv.gameEvent
                            // which will send a SOCRevealFogHex message to the game.
                            /*
                               if (D.ebugOn) {
                               D.ebugPrintln("AFTER");
                               for (int pn = 0; pn < SOCGame.MAXPLAYERS; pn++) {
                               SOCPlayer tmpPlayer = ga.getPlayer(pn);
                               D.ebugPrintln("Player # "+pn);
                               for (int i = 0x22; i < 0xCC; i++) {
                               if (tmpPlayer.isPotentialRoad(i))
                               D.ebugPrintln("### POTENTIAL ROAD AT "+Integer.toHexString(i));
                               }
                               }
                               }
                             */
                            srv.gameList.takeMonitorForGame(gaName);
                            // "Joe built a road."
                            srv.messageToGameKeyed(ga, false, "action.built.road", plName);
                            srv.messageToGameWithMon(gaName, new SOCPutPiece(gaName, pn, SOCPlayingPiece.ROAD, coord));
                            if (!ga.pendingMessagesOut.isEmpty())
                                handler.sendGamePendingMessages(ga, false);
                            srv.gameList.releaseMonitorForGame(gaName);
                            // If needed, call sendTurn or send SOCRollDicePrompt
                            handler.sendTurnStateAtInitialPlacement(ga, player, c, gameState);
                            int newState = ga.getGameState();
                            if ((newState == SOCGame.STARTS_WAITING_FOR_PICK_GOLD_RESOURCE) || (newState == SOCGame.WAITING_FOR_PICK_GOLD_RESOURCE)) {
                                // gold hex revealed from fog (scenario SC_FOG)
                                handler.sendGameState_sendGoldPickAnnounceText(ga, gaName, c, null);
                            }
                        } else {
                            D.ebugPrintln("ILLEGAL ROAD: 0x" + Integer.toHexString(coord) + ": player " + pn);
                            if (player.isRobot() && D.ebugOn) {
                                D.ebugPrintln(" - pl.isPotentialRoad: " + player.isPotentialRoad(coord));
                                SOCPlayingPiece pp = ga.getBoard().roadAtEdge(coord);
                                D.ebugPrintln(" - roadAtEdge: " + ((pp != null) ? pp : "none"));
                            }
                            srv.messageToPlayerKeyed(c, gaName, "action.build.cannot.there.road");
                            // "You can't build a road there."
                            sendDenyReply = true;
                        }
                    } else {
                        srv.messageToPlayerKeyed(c, gaName, "action.build.cannot.now.road");
                    // "You can't build a road now."
                    }
                    break;
                case SOCPlayingPiece.SETTLEMENT:
                    if ((gameState == SOCGame.START1A) || (gameState == SOCGame.START2A) || (gameState == SOCGame.START3A) || (gameState == SOCGame.PLACING_SETTLEMENT)) {
                        if (player.canPlaceSettlement(coord) && (player.getNumPieces(SOCPlayingPiece.SETTLEMENT) >= 1)) {
                            final SOCSettlement se = new SOCSettlement(player, coord, null);
                            // Changes game state and (if initial placement) player
                            ga.putPiece(se);
                            srv.gameList.takeMonitorForGame(gaName);
                            // "Joe built a settlement."
                            srv.messageToGameKeyed(ga, false, "action.built.stlmt", plName);
                            srv.messageToGameWithMon(gaName, new SOCPutPiece(gaName, pn, SOCPlayingPiece.SETTLEMENT, coord));
                            if (!ga.pendingMessagesOut.isEmpty())
                                handler.sendGamePendingMessages(ga, false);
                            srv.gameList.releaseMonitorForGame(gaName);
                            // Check player and send new game state
                            if (!handler.checkTurn(c, ga))
                                // Announce new state and new current player
                                handler.sendTurn(ga, false);
                            else
                                handler.sendGameState(ga);
                            if (ga.hasSeaBoard && (ga.getGameState() == SOCGame.STARTS_WAITING_FOR_PICK_GOLD_RESOURCE)) {
                                // Prompt to pick from gold: send text and SOCSimpleRequest(PROMPT_PICK_RESOURCES)
                                handler.sendGameState_sendGoldPickAnnounceText(ga, gaName, c, null);
                            }
                        } else {
                            D.ebugPrintln("ILLEGAL SETTLEMENT: 0x" + Integer.toHexString(coord) + ": player " + pn);
                            if (player.isRobot() && D.ebugOn) {
                                D.ebugPrintln(" - pl.isPotentialSettlement: " + player.isPotentialSettlement(coord));
                                SOCPlayingPiece pp = ga.getBoard().settlementAtNode(coord);
                                D.ebugPrintln(" - settlementAtNode: " + ((pp != null) ? pp : "none"));
                            }
                            srv.messageToPlayerKeyed(c, gaName, "action.build.cannot.there.stlmt");
                            // "You can't build a settlement there."
                            sendDenyReply = true;
                        }
                    } else {
                        srv.messageToPlayerKeyed(c, gaName, "action.build.cannot.now.stlmt");
                    // "You can't build a settlement now."
                    }
                    break;
                case SOCPlayingPiece.CITY:
                    if (gameState == SOCGame.PLACING_CITY) {
                        if (player.isPotentialCity(coord) && (player.getNumPieces(SOCPlayingPiece.CITY) >= 1)) {
                            boolean houseRuleFirstCity = ga.isGameOptionSet("N7C") && !ga.hasBuiltCity();
                            if (houseRuleFirstCity && ga.isGameOptionSet("N7") && (ga.getRoundCount() < ga.getGameOptionIntValue("N7"))) {
                                // If "No 7s for first # rounds" is active, and this isn't its last round, 7s won't
                                // be rolled soon: Don't announce "Starting next turn, dice rolls of 7 may occur"
                                houseRuleFirstCity = false;
                            }
                            final SOCCity ci = new SOCCity(player, coord, null);
                            // changes game state and maybe player
                            ga.putPiece(ci);
                            srv.gameList.takeMonitorForGame(gaName);
                            // "Joe built a city."
                            srv.messageToGameKeyed(ga, false, "action.built.city", plName);
                            srv.messageToGameWithMon(gaName, new SOCPutPiece(gaName, pn, SOCPlayingPiece.CITY, coord));
                            if (!ga.pendingMessagesOut.isEmpty())
                                handler.sendGamePendingMessages(ga, false);
                            if (houseRuleFirstCity)
                                srv.messageToGameKeyed(ga, false, "action.built.nextturn.7.houserule");
                            // "Starting next turn, dice rolls of 7 may occur (house rule)."
                            srv.gameList.releaseMonitorForGame(gaName);
                            // Check player and send new game state
                            if (!handler.checkTurn(c, ga))
                                // Announce new state and new current player
                                handler.sendTurn(ga, false);
                            else
                                handler.sendGameState(ga);
                        } else {
                            D.ebugPrintln("ILLEGAL CITY: 0x" + Integer.toHexString(coord) + ": player " + pn);
                            if (player.isRobot() && D.ebugOn) {
                                D.ebugPrintln(" - pl.isPotentialCity: " + player.isPotentialCity(coord));
                                SOCPlayingPiece pp = ga.getBoard().settlementAtNode(coord);
                                D.ebugPrintln(" - city/settlementAtNode: " + ((pp != null) ? pp : "none"));
                            }
                            srv.messageToPlayerKeyed(c, gaName, "action.build.cannot.there.city");
                            // "You can't build a city there."
                            sendDenyReply = true;
                        }
                    } else {
                        srv.messageToPlayerKeyed(c, gaName, "action.build.cannot.now.city");
                    // "You can't build a city now."
                    }
                    break;
                case SOCPlayingPiece.SHIP:
                    if ((gameState == SOCGame.START1B) || (gameState == SOCGame.START2B) || (gameState == SOCGame.START3B) || (gameState == SOCGame.PLACING_SHIP) || (gameState == SOCGame.PLACING_FREE_ROAD1) || (gameState == SOCGame.PLACING_FREE_ROAD2)) {
                        // Place it if we can; canPlaceShip checks potentials and pirate ship location
                        if (ga.canPlaceShip(player, coord) && (player.getNumPieces(SOCPlayingPiece.SHIP) >= 1)) {
                            final SOCShip sh = new SOCShip(player, coord, null);
                            // Changes game state and (during initial placement) sometimes player
                            ga.putPiece(sh);
                            srv.gameList.takeMonitorForGame(gaName);
                            // "Joe built a ship."
                            srv.messageToGameKeyed(ga, false, "action.built.ship", plName);
                            srv.messageToGameWithMon(gaName, new SOCPutPiece(gaName, pn, SOCPlayingPiece.SHIP, coord));
                            if (!ga.pendingMessagesOut.isEmpty())
                                handler.sendGamePendingMessages(ga, false);
                            srv.gameList.releaseMonitorForGame(gaName);
                            // If needed, call sendTurn or send SOCRollDicePrompt
                            handler.sendTurnStateAtInitialPlacement(ga, player, c, gameState);
                            int newState = ga.getGameState();
                            if ((newState == SOCGame.STARTS_WAITING_FOR_PICK_GOLD_RESOURCE) || (newState == SOCGame.WAITING_FOR_PICK_GOLD_RESOURCE)) {
                                // gold hex revealed from fog (scenario SC_FOG)
                                handler.sendGameState_sendGoldPickAnnounceText(ga, gaName, c, null);
                            }
                        } else {
                            D.ebugPrintln("ILLEGAL SHIP: 0x" + Integer.toHexString(coord) + ": player " + pn);
                            if (player.isRobot() && D.ebugOn) {
                                D.ebugPrintln(" - pl.isPotentialShip: " + player.isPotentialShip(coord));
                                SOCPlayingPiece pp = ga.getBoard().roadAtEdge(coord);
                                D.ebugPrintln(" - ship/roadAtEdge: " + ((pp != null) ? pp : "none"));
                            }
                            srv.messageToPlayerKeyed(c, gaName, "action.build.cannot.there.ship");
                            // "You can't build a ship there."
                            sendDenyReply = true;
                        }
                    } else {
                        srv.messageToPlayerKeyed(c, gaName, "action.build.cannot.now.ship");
                    // "You can't build a ship now."
                    }
                    break;
            }
            if (sendDenyReply) {
                if (isBuyAndPut)
                    // is probably now PLACING_*, was PLAY1 or SPECIAL_BUILDING
                    handler.sendGameState(ga);
                srv.messageToPlayer(c, new SOCCancelBuildRequest(gaName, mes.getPieceType()));
                if (player.isRobot()) {
                    // Set the "force end turn soon" field
                    ga.lastActionTime = 0L;
                }
            }
        } else {
            // "It's not your turn."
            srv.messageToPlayerKeyed(c, gaName, "reply.not.your.turn");
        }
    } catch (Exception e) {
        D.ebugPrintStackTrace(e, "Exception caught in handlePUTPIECE");
    } finally {
        ga.releaseMonitor();
    }
}
Also used : SOCSettlement(soc.game.SOCSettlement) SOCCity(soc.game.SOCCity) SOCPlayingPiece(soc.game.SOCPlayingPiece) SOCShip(soc.game.SOCShip) SOCPlayer(soc.game.SOCPlayer) SOCRoad(soc.game.SOCRoad)

Example 2 with SOCPlayer

use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.

the class SOCGameMessageHandler method handleINVENTORYITEMACTION.

// / Inventory Items and Special Items ///
/**
 * Special inventory item action (play request) from a player.
 * Ignored unless {@link SOCInventoryItemAction#action mes.action} == {@link SOCInventoryItemAction#PLAY PLAY}.
 * Calls {@link SOCGame#canPlayInventoryItem(int, int)}, {@link SOCGame#playInventoryItem(int)}.
 * If game state changes here, calls {@link SOCGameHandler#sendGameState(SOCGame)} just before returning.
 *
 * @param ga  game with {@code c} as a client player
 * @param c  the connection sending the message
 * @param mes  the message
 */
private void handleINVENTORYITEMACTION(SOCGame ga, Connection c, final SOCInventoryItemAction mes) {
    if (mes.action != SOCInventoryItemAction.PLAY)
        return;
    final String gaName = ga.getName();
    SOCPlayer clientPl = ga.getPlayer(c.getData());
    if (clientPl == null)
        return;
    final int pn = clientPl.getPlayerNumber();
    final int replyCannot = ga.canPlayInventoryItem(pn, mes.itemType);
    if (replyCannot != 0) {
        srv.messageToPlayer(c, new SOCInventoryItemAction(gaName, -1, SOCInventoryItemAction.CANNOT_PLAY, mes.itemType, replyCannot));
        return;
    }
    final int oldGameState = ga.getGameState();
    // <--- Play the item ---
    final SOCInventoryItem item = ga.playInventoryItem(mes.itemType);
    if (item == null) {
        // Wasn't able to play.  Assume canPlay was recently called and returned OK; the most
        // volatile of its conditions is player's inventory, so assume that's what changed.
        srv.messageToPlayer(c, new SOCInventoryItemAction(gaName, -1, SOCInventoryItemAction.CANNOT_PLAY, mes.itemType, // 1 == item not in inventory
        1));
        return;
    }
    // Item played.  Announce play and removal (or keep) from player's inventory.
    // Announce game state if changed.
    srv.messageToGame(gaName, new SOCInventoryItemAction(gaName, pn, SOCInventoryItemAction.PLAYED, item.itype, item.isKept(), item.isVPItem(), item.canCancelPlay));
    final int gstate = ga.getGameState();
    if (gstate != oldGameState)
        handler.sendGameState(ga);
}
Also used : SOCInventoryItem(soc.game.SOCInventoryItem) SOCPlayer(soc.game.SOCPlayer)

Example 3 with SOCPlayer

use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.

the class SOCGameMessageHandler method handleROLLDICE.

// / Roll dice and pick resources ///
/**
 * handle "roll dice" message.
 *
 * @param c  the connection that sent the message
 * @param mes  the message
 * @since 1.0.0
 */
private void handleROLLDICE(SOCGame ga, Connection c, final SOCRollDice mes) {
    final String gn = ga.getName();
    ga.takeMonitor();
    try {
        final String plName = c.getData();
        final SOCPlayer pl = ga.getPlayer(plName);
        if ((pl != null) && ga.canRollDice(pl.getPlayerNumber())) {
            /**
             * Roll dice, distribute resources in game
             */
            SOCGame.RollResult roll = ga.rollDice();
            /**
             * Send roll results and then text to client.
             * Note that only the total is sent, not the 2 individual dice.
             * (Only the _SC_PIRI scenario cares about them indivdually, and
             * in that case it prints the result when needed.)
             *
             * If a 7 is rolled, sendGameState will also say who must discard
             * (in a GAMETEXTMSG).
             * If a gold hex is rolled, sendGameState will also say who
             * must pick resources to gain (in a GAMETEXTMSG).
             */
            srv.messageToGame(gn, new SOCDiceResult(gn, ga.getCurrentDice()));
            if (ga.clientVersionLowest < SOCGameTextMsg.VERSION_FOR_DICE_RESULT_INSTEAD) {
                // backwards-compat: this text message is redundant to v2.0.00 and newer clients
                // because they print the roll results from SOCDiceResult.  Use SOCGameTextMsg
                // because pre-2.0.00 clients don't understand SOCGameServerText messages.
                srv.messageToGameForVersions(ga, 0, SOCGameTextMsg.VERSION_FOR_DICE_RESULT_INSTEAD - 1, new SOCGameTextMsg(gn, SOCGameTextMsg.SERVERNAME, // I18N
                plName + " rolled a " + roll.diceA + " and a " + roll.diceB + "."), true);
            }
            // For 7, give visual feedback before sending discard request
            handler.sendGameState(ga);
            if (ga.isGameOptionSet(SOCGameOption.K_SC_PIRI)) {
                // pirate moves on every roll
                srv.messageToGame(gn, new SOCMoveRobber(gn, ga.getCurrentPlayerNumber(), -(((SOCBoardLarge) ga.getBoard()).getPirateHex())));
                if (roll.sc_piri_fleetAttackVictim != null) {
                    final SOCResourceSet loot = roll.sc_piri_fleetAttackRsrcs;
                    final int lootTotal = (loot != null) ? loot.getTotal() : 0;
                    if (lootTotal != 0) {
                        // use same resource-loss messages sent in handleDISCARD
                        final boolean won = (loot.contains(SOCResourceConstants.GOLD_LOCAL));
                        SOCPlayer vic = roll.sc_piri_fleetAttackVictim;
                        final String vicName = vic.getName();
                        final Connection vCon = srv.getConnection(vicName);
                        final int vpn = vic.getPlayerNumber();
                        final int strength = (roll.diceA < roll.diceB) ? roll.diceA : roll.diceB;
                        if (won) {
                            srv.messageToGameKeyed(ga, true, "action.rolled.sc_piri.player.won.pick.free", vicName, strength);
                        // "{0} won against the pirate fleet (strength {1}) and will pick a free resource."
                        } else {
                            /**
                             * tell the victim client that the player lost the resources
                             */
                            handler.reportRsrcGainLoss(gn, loot, true, true, vpn, -1, null, vCon);
                            srv.messageToPlayerKeyedSpecial(vCon, ga, "action.rolled.sc_piri.you.lost.rsrcs.to.fleet", loot, strength);
                            // "You lost {0,rsrcs} to the pirate fleet (strength {1,number})."
                            /**
                             * tell everyone else that the player lost unknown resources
                             */
                            srv.messageToGameExcept(gn, vCon, new SOCPlayerElement(gn, vpn, SOCPlayerElement.LOSE, SOCPlayerElement.UNKNOWN, lootTotal), true);
                            srv.messageToGameKeyedSpecialExcept(ga, true, vCon, "action.rolled.sc_piri.player.lost.rsrcs.to.fleet", vicName, lootTotal, strength);
                        // "Joe lost 1 resource to pirate fleet attack (strength 3)." or
                        // "Joe lost 3 resources to pirate fleet attack (strength 3)."
                        }
                    }
                }
            }
            /**
             * if the roll is not 7, tell players what they got
             * (if 7, sendGameState already told them what they lost).
             */
            if (ga.getCurrentDice() != 7) {
                boolean noPlayersGained = true;
                /**
                 * Clients v2.0.00 and newer get an i18n-neutral SOCDiceResultResources message.
                 * Older clients get a string such as "Joe gets 3 sheep. Mike gets 1 clay."
                 */
                String rollRsrcTxtOldCli = null;
                SOCDiceResultResources rollRsrcMsgNewCli = null;
                if (ga.clientVersionHighest >= SOCDiceResultResources.VERSION_FOR_DICERESULTRESOURCES) {
                    rollRsrcMsgNewCli = SOCDiceResultResources.buildForGame(ga);
                    noPlayersGained = (rollRsrcMsgNewCli == null);
                }
                if (ga.clientVersionLowest < SOCDiceResultResources.VERSION_FOR_DICERESULTRESOURCES) {
                    // Build a string to announce to v1.x.xx clients
                    StringBuffer gainsText = new StringBuffer();
                    // for string spacing; might be false due to loop for new clients in game
                    noPlayersGained = true;
                    for (int pn = 0; pn < ga.maxPlayers; ++pn) {
                        if (!ga.isSeatVacant(pn)) {
                            SOCPlayer pp = ga.getPlayer(pn);
                            SOCResourceSet rsrcs = pp.getRolledResources();
                            if (rsrcs.getKnownTotal() != 0) {
                                if (noPlayersGained)
                                    noPlayersGained = false;
                                else
                                    gainsText.append(" ");
                                gainsText.append(c.getLocalizedSpecial(ga, "_nolocaliz.roll.gets.resources", pp.getName(), rsrcs));
                                // "{0} gets {1,rsrcs}."
                                // get it from any connection's StringManager, because that string is never localized
                                // Announce SOCPlayerElement.GAIN messages
                                handler.reportRsrcGainLoss(gn, rsrcs, false, false, pn, -1, null, null);
                            }
                        }
                    }
                    if (!noPlayersGained)
                        rollRsrcTxtOldCli = gainsText.toString();
                }
                if (noPlayersGained) {
                    String key;
                    if (roll.cloth == null)
                        // "No player gets anything."
                        key = "action.rolled.no.player.gets.anything";
                    else
                        // "No player gets resources."
                        key = "action.rolled.no.player.gets.resources";
                    // debug_printPieceDiceNumbers(ga, message);
                    srv.messageToGameKeyed(ga, true, key);
                } else {
                    if (rollRsrcTxtOldCli == null)
                        srv.messageToGame(gn, rollRsrcMsgNewCli);
                    else if (rollRsrcMsgNewCli == null)
                        srv.messageToGame(gn, rollRsrcTxtOldCli);
                    else {
                        // neither is null: we have old and new clients
                        srv.messageToGameForVersions(ga, 0, (SOCDiceResultResources.VERSION_FOR_DICERESULTRESOURCES - 1), new SOCGameTextMsg(gn, SOCGameTextMsg.SERVERNAME, rollRsrcTxtOldCli), true);
                        srv.messageToGameForVersions(ga, SOCDiceResultResources.VERSION_FOR_DICERESULTRESOURCES, Integer.MAX_VALUE, rollRsrcMsgNewCli, true);
                    }
                    // 
                    for (int pn = 0; pn < ga.maxPlayers; ++pn) {
                        final SOCPlayer pp = ga.getPlayer(pn);
                        Connection playerCon = srv.getConnection(pp.getName());
                        if (playerCon == null)
                            continue;
                        if (pp.getRolledResources().getKnownTotal() == 0)
                            // skip if player didn't gain; before v2.0.00 each player in game got these
                            continue;
                        // send CLAY, ORE, SHEEP, WHEAT, WOOD even if player's amount is 0
                        final SOCResourceSet resources = pp.getResources();
                        final int[] counts = resources.getAmounts(false);
                        if (playerCon.getVersion() >= SOCPlayerElements.MIN_VERSION)
                            srv.messageToPlayer(playerCon, new SOCPlayerElements(gn, pn, SOCPlayerElement.SET, SOCGameHandler.ELEM_RESOURCES, counts));
                        else
                            for (int i = 0; i < counts.length; ++i) srv.messageToPlayer(playerCon, new SOCPlayerElement(gn, pn, SOCPlayerElement.SET, SOCGameHandler.ELEM_RESOURCES[i], counts[i]));
                        if (ga.clientVersionLowest < SOCDiceResultResources.VERSION_FOR_DICERESULTRESOURCES)
                            srv.messageToGame(gn, new SOCResourceCount(gn, pn, resources.getTotal()));
                    // else, already-sent SOCDiceResultResources included players' new resource totals
                    // we'll send gold picks text, PLAYERELEMENT, and SIMPLEREQUEST(PROMPT_PICK_RESOURCES)
                    // after the per-player loop
                    }
                }
                if (roll.cloth != null) {
                    // Send village cloth trade distribution
                    final int coord = roll.cloth[1];
                    final SOCBoardLarge board = (SOCBoardLarge) (ga.getBoard());
                    SOCVillage vi = board.getVillageAtNode(coord);
                    if (vi != null)
                        srv.messageToGame(gn, new SOCPieceValue(gn, coord, vi.getCloth(), 0));
                    if (roll.cloth[0] > 0)
                        // some taken from board general supply
                        srv.messageToGame(gn, new SOCPlayerElement(gn, -1, SOCPlayerElement.SET, SOCPlayerElement.SCENARIO_CLOTH_COUNT, board.getCloth()));
                    // name of first player to receive cloth
                    String clplName = null;
                    // names of all players receiving cloth, if more than one
                    ArrayList<String> clpls = null;
                    for (int i = 2; i < roll.cloth.length; ++i) {
                        if (roll.cloth[i] == 0)
                            // this player didn't receive cloth
                            continue;
                        final int pn = i - 2;
                        final SOCPlayer clpl = ga.getPlayer(pn);
                        srv.messageToGame(gn, new SOCPlayerElement(gn, pn, SOCPlayerElement.SET, SOCPlayerElement.SCENARIO_CLOTH_COUNT, clpl.getCloth()));
                        if (clplName == null) {
                            // first pl to receive cloth
                            clplName = clpl.getName();
                        } else {
                            // second or further player
                            if (clpls == null) {
                                clpls = new ArrayList<String>();
                                clpls.add(clplName);
                            }
                            clpls.add(clpl.getName());
                        }
                    }
                    if (clpls == null)
                        srv.messageToGameKeyed(ga, true, "action.rolled.sc_clvi.received.cloth.1", clplName);
                    else
                        // "{0} received 1 cloth from a village."
                        srv.messageToGameKeyedSpecial(ga, true, "action.rolled.sc_clvi.received.cloth.n", clpls);
                // "{0,list} each received 1 cloth from a village."
                }
                if (ga.getGameState() == SOCGame.WAITING_FOR_PICK_GOLD_RESOURCE)
                    // gold picks text, PLAYERELEMENT, and SIMPLEREQUEST(PROMPT_PICK_RESOURCES)s
                    handler.sendGameState_sendGoldPickAnnounceText(ga, gn, null, roll);
            /*
                       if (D.ebugOn) {
                       for (int i=0; i < SOCGame.MAXPLAYERS; i++) {
                       SOCResourceSet rsrcs = ga.getPlayer(i).getResources();
                       String resourceMessage = "PLAYER "+i+" RESOURCES: ";
                       resourceMessage += rsrcs.getAmount(SOCResourceConstants.CLAY)+" ";
                       resourceMessage += rsrcs.getAmount(SOCResourceConstants.ORE)+" ";
                       resourceMessage += rsrcs.getAmount(SOCResourceConstants.SHEEP)+" ";
                       resourceMessage += rsrcs.getAmount(SOCResourceConstants.WHEAT)+" ";
                       resourceMessage += rsrcs.getAmount(SOCResourceConstants.WOOD)+" ";
                       resourceMessage += rsrcs.getAmount(SOCResourceConstants.UNKNOWN)+" ";
                       messageToGame(gn, new SOCGameTextMsg(gn, SERVERNAME, resourceMessage));
                       }
                       }
                     */
            } else {
                /**
                 * player rolled 7
                 * If anyone needs to discard, prompt them.
                 */
                if (ga.getGameState() == SOCGame.WAITING_FOR_DISCARDS) {
                    handler.sendGameState_sendDiscardRequests(ga, gn);
                } else if (ga.getGameState() == SOCGame.WAITING_FOR_PICK_GOLD_RESOURCE) {
                    // Used in _SC_PIRI, when 7 is rolled and a player wins against the pirate fleet
                    for (int pn = 0; pn < ga.maxPlayers; ++pn) {
                        final SOCPlayer pp = ga.getPlayer(pn);
                        final int numPick = pp.getNeedToPickGoldHexResources();
                        if ((!ga.isSeatVacant(pn)) && (numPick > 0)) {
                            Connection con = srv.getConnection(pp.getName());
                            if (con != null) {
                                srv.messageToGame(gn, new SOCPlayerElement(gn, pn, SOCPlayerElement.SET, SOCPlayerElement.NUM_PICK_GOLD_HEX_RESOURCES, numPick));
                                con.put(SOCSimpleRequest.toCmd(gn, pn, SOCSimpleRequest.PROMPT_PICK_RESOURCES, numPick, 0));
                            }
                        }
                    }
                }
            }
        } else {
            srv.messageToPlayer(c, gn, "You can't roll right now.");
        }
    } catch (Exception e) {
        D.ebugPrintStackTrace(e, "Exception caught at handleROLLDICE" + e);
    }
    ga.releaseMonitor();
}
Also used : SOCVillage(soc.game.SOCVillage) SOCBoardLarge(soc.game.SOCBoardLarge) Connection(soc.server.genericServer.Connection) SOCPlayer(soc.game.SOCPlayer) SOCResourceSet(soc.game.SOCResourceSet) SOCGame(soc.game.SOCGame)

Example 4 with SOCPlayer

use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.

the class SOCGameMessageHandler method handleMOVEROBBER.

// / Robber/pirate robbery ///
/**
 * handle "move robber" message (move the robber or the pirate).
 *
 * @param c  the connection that sent the message
 * @param mes  the message
 * @since 1.0.0
 */
private void handleMOVEROBBER(SOCGame ga, Connection c, SOCMoveRobber mes) {
    ga.takeMonitor();
    try {
        SOCPlayer player = ga.getPlayer(c.getData());
        /**
         * make sure the player can do it
         */
        final String gaName = ga.getName();
        final boolean isPirate = ga.getRobberyPirateFlag();
        final int pn = player.getPlayerNumber();
        // negative for pirate
        int coord = mes.getCoordinates();
        final boolean canDo = (isPirate == (coord < 0)) && (isPirate ? ga.canMovePirate(pn, -coord) : ga.canMoveRobber(pn, coord));
        if (canDo) {
            SOCMoveRobberResult result;
            SOCMoveRobber moveMsg;
            if (isPirate) {
                result = ga.movePirate(pn, -coord);
                moveMsg = new SOCMoveRobber(gaName, pn, coord);
            } else {
                result = ga.moveRobber(pn, coord);
                moveMsg = new SOCMoveRobber(gaName, pn, coord);
            }
            srv.messageToGame(gaName, moveMsg);
            final List<SOCPlayer> victims = result.getVictims();
            /**
             * only one possible victim
             */
            if ((victims.size() == 1) && (ga.getGameState() != SOCGame.WAITING_FOR_ROB_CLOTH_OR_RESOURCE)) {
                /**
                 * report what was stolen
                 */
                SOCPlayer victim = victims.get(0);
                handler.reportRobbery(ga, player, victim, result.getLoot());
            } else {
                final String msgKey;
                /**
                 * no victim
                 */
                if (victims.size() == 0) {
                    /**
                     * just say it was moved; nothing is stolen
                     */
                    // "{0} moved the robber" or "{0} moved the pirate"
                    msgKey = "robberpirate.moved";
                } else if (ga.getGameState() == SOCGame.WAITING_FOR_ROB_CLOTH_OR_RESOURCE) {
                    /**
                     * only one possible victim, they have both clay and resources
                     */
                    msgKey = "robberpirate.moved.choose.cloth.rsrcs";
                // "{0} moved the robber/pirate. Must choose to steal cloth or steal resources."
                } else {
                    /**
                     * else, the player needs to choose a victim
                     */
                    msgKey = "robberpirate.moved.choose.victim";
                // "{0} moved the robber/pirate. Must choose a victim."
                }
                srv.messageToGameKeyed(ga, true, msgKey, player.getName(), ((isPirate) ? 2 : 1));
            }
            handler.sendGameState(ga);
            // victims there, just send the prompt from here:
            if (ga.getGameState() == SOCGame.WAITING_FOR_ROB_CLOTH_OR_RESOURCE) {
                final int vpn = victims.get(0).getPlayerNumber();
                srv.messageToPlayer(c, new SOCChoosePlayer(gaName, vpn));
            }
        } else {
            srv.messageToPlayerKeyed(c, gaName, ((coord < 0) ? "robber.cantmove.pirate" : "robber.cantmove"));
        // "You can't move the pirate" / "You can't move the robber"
        }
    } catch (Exception e) {
        D.ebugPrintStackTrace(e, "Exception caught");
    }
    ga.releaseMonitor();
}
Also used : SOCPlayer(soc.game.SOCPlayer) SOCMoveRobberResult(soc.game.SOCMoveRobberResult)

Example 5 with SOCPlayer

use of soc.game.SOCPlayer in project JSettlers2 by jdmonin.

the class SOCGameMessageHandler method handleBUILDREQUEST.

// / Game piece building, placement, and moving ///
/**
 * handle "build request" message.
 * If client is current player, they want to buy a {@link SOCPlayingPiece}.
 * Otherwise, if 6-player board, they are requesting to build during the
 * next {@link SOCGame#SPECIAL_BUILDING Special Building Phase}.
 *
 * @param c  the connection that sent the message
 * @param mes  the message
 * @since 1.0.0
 * @see #handleBUILDREQUEST(SOCGame, SOCPlayer, Connection, int, boolean)
 */
private void handleBUILDREQUEST(SOCGame ga, Connection c, final SOCBuildRequest mes) {
    final String gaName = ga.getName();
    ga.takeMonitor();
    try {
        final boolean isCurrent = handler.checkTurn(c, ga);
        SOCPlayer player = ga.getPlayer(c.getData());
        final int pn = player.getPlayerNumber();
        final int pieceType = mes.getPieceType();
        // for robots' benefit
        boolean sendDenyReply = false;
        if (isCurrent) {
            if ((ga.getGameState() == SOCGame.PLAY1) || (ga.getGameState() == SOCGame.SPECIAL_BUILDING)) {
                sendDenyReply = !handleBUILDREQUEST(ga, player, c, pieceType, true);
            } else if (pieceType == -1) {
                // during start of own turn
                try {
                    ga.askSpecialBuild(pn, true);
                    srv.messageToGame(gaName, new SOCPlayerElement(gaName, pn, SOCPlayerElement.SET, SOCPlayerElement.ASK_SPECIAL_BUILD, 1));
                    // triggers start of SBP
                    handler.endGameTurn(ga, player, true);
                } catch (IllegalStateException e) {
                    // "You can't ask to build now."
                    srv.messageToPlayerKeyed(c, gaName, "action.build.cannot.now.ask");
                    sendDenyReply = true;
                }
            } else {
                // "You can't build now."
                srv.messageToPlayerKeyed(c, gaName, "action.build.cannot.now");
                sendDenyReply = true;
            }
        } else {
            if (ga.maxPlayers <= 4) {
                // "It's not your turn."
                srv.messageToPlayerKeyed(c, gaName, "reply.not.your.turn");
                sendDenyReply = true;
            } else {
                // during other player's turn
                try {
                    // will validate that they can build now
                    ga.askSpecialBuild(pn, true);
                    srv.messageToGame(gaName, new SOCPlayerElement(gaName, pn, SOCPlayerElement.SET, SOCPlayerElement.ASK_SPECIAL_BUILD, 1));
                } catch (IllegalStateException e) {
                    // "You can't ask to build now."
                    srv.messageToPlayerKeyed(c, gaName, "action.build.cannot.now.ask");
                    sendDenyReply = true;
                }
            }
        }
        if (sendDenyReply && ga.getPlayer(pn).isRobot()) {
            srv.messageToPlayer(c, new SOCCancelBuildRequest(gaName, pieceType));
        }
    } catch (Exception e) {
        D.ebugPrintStackTrace(e, "Exception caught at handleBUILDREQUEST");
    }
    ga.releaseMonitor();
}
Also used : SOCPlayer(soc.game.SOCPlayer)

Aggregations

SOCPlayer (soc.game.SOCPlayer)61 SOCGame (soc.game.SOCGame)17 SOCShip (soc.game.SOCShip)12 SOCSettlement (soc.game.SOCSettlement)11 SOCRoad (soc.game.SOCRoad)9 SOCResourceSet (soc.game.SOCResourceSet)8 SOCCity (soc.game.SOCCity)7 SOCBoardLarge (soc.game.SOCBoardLarge)6 SOCFortress (soc.game.SOCFortress)5 ArrayList (java.util.ArrayList)4 SOCBoard (soc.game.SOCBoard)4 Connection (soc.server.genericServer.Connection)4 SOCInventoryItem (soc.game.SOCInventoryItem)3 SOCVillage (soc.game.SOCVillage)3 SQLException (java.sql.SQLException)2 Iterator (java.util.Iterator)2 Stack (java.util.Stack)2 SOCLRPathData (soc.game.SOCLRPathData)2 SOCPlayingPiece (soc.game.SOCPlayingPiece)2 SOCSpecialItem (soc.game.SOCSpecialItem)2