use of soc.game.SOCBoardLarge in project JSettlers2 by jdmonin.
the class SOCBoardPanel method drawBoard.
/**
* Draw the whole board, including pieces and tooltip ({@link #hilight}, {@link #hoverTip}) if applicable.
* The basic board without pieces is drawn just once, then buffered.
* If the board layout changes (at start of game, for example),
* call {@link #flushBoardLayoutAndRepaint()} to clear the buffered copy.
*
* @see #drawBoardEmpty(Graphics)
*/
private void drawBoard(Graphics g) {
Image ebb = emptyBoardBuffer;
if (scaledMissedImage || ebb == null) {
if (ebb == null) {
ebb = createImage(scaledPanelW, scaledPanelH);
emptyBoardBuffer = ebb;
}
drawnEmptyAt = System.currentTimeMillis();
// drawBoardEmpty, drawHex will set this flag if missed
scaledMissedImage = false;
drawBoardEmpty(ebb.getGraphics());
ebb.flush();
if (scaledMissedImage && (scaledAt != 0) && (RESCALE_MAX_RETRY_MS < (drawnEmptyAt - scaledAt)))
// eventually give up scaling it
scaledMissedImage = false;
}
// draw ebb from local variable, not emptyBoardBuffer field, to avoid occasional NPE
g.setPaintMode();
g.drawImage(ebb, 0, 0, this);
// ask for antialiasing if available
if (g instanceof Graphics2D)
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
final boolean xlat = (panelMarginX != 0) || (panelMarginY != 0);
if (xlat)
g.translate(panelMarginX, panelMarginY);
final int gameState = game.getGameState();
if (board.getRobberHex() != -1) {
drawRobber(g, board.getRobberHex(), (gameState != SOCGame.PLACING_ROBBER), true);
}
if (board.getPreviousRobberHex() != -1) {
drawRobber(g, board.getPreviousRobberHex(), (gameState != SOCGame.PLACING_ROBBER), false);
}
if (isLargeBoard) {
int hex = ((SOCBoardLarge) board).getPirateHex();
if (hex > 0) {
drawRoadOrShip(g, hex, -2, (gameState == SOCGame.PLACING_PIRATE), false, false);
}
hex = ((SOCBoardLarge) board).getPreviousPirateHex();
if (hex > 0) {
drawRoadOrShip(g, hex, -3, (gameState == SOCGame.PLACING_PIRATE), false, false);
}
}
/**
* draw the roads and ships
*/
if (!game.isGameOptionSet(SOCGameOption.K_SC_PIRI)) {
for (SOCRoad r : board.getRoads()) {
drawRoadOrShip(g, r.getCoordinates(), r.getPlayerNumber(), false, !(r instanceof SOCShip), false);
}
} else {
for (int pn = 0; pn < game.maxPlayers; ++pn) {
final SOCPlayer pl = game.getPlayer(pn);
// count warships here, for efficiency, instead of calling SOCGame.isShipWarship for each one
int numWarships = pl.getNumWarships();
for (SOCRoad r : pl.getRoads()) {
final boolean isShip = (r instanceof SOCShip);
final boolean isWarship = isShip && (numWarships > 0);
drawRoadOrShip(g, r.getCoordinates(), pn, false, !isShip, isWarship);
if (isWarship)
// this works since warships begin with player's 1st-placed ship in getRoads()
--numWarships;
}
/**
* draw the player's fortress, if any
*/
SOCFortress fo = pl.getFortress();
if (fo != null)
drawFortress(g, fo, pn, false);
}
}
/**
* draw the settlements
*/
for (SOCSettlement s : board.getSettlements()) {
drawSettlement(g, s.getCoordinates(), s.getPlayerNumber(), false, false);
}
/**
* draw the cities
*/
for (SOCCity c : board.getCities()) {
drawCity(g, c.getCoordinates(), c.getPlayerNumber(), false);
}
if (xlat)
g.translate(-panelMarginX, -panelMarginY);
/**
* draw the current-player arrow after ("above") pieces,
* but below any hilighted piece, in case of overlap at
* edge of board. More likely on 6-player board for the
* two players whose handpanels are vertically centered.
*/
if (gameState != SOCGame.NEW) {
drawArrow(g, game.getCurrentPlayerNumber(), game.getCurrentDice());
}
if (player != null) {
if (xlat)
g.translate(panelMarginX, panelMarginY);
/**
* Draw the hilight when in interactive mode;
* No hilight when null player (before game started).
* The "hovering" road/settlement/city are separately painted
* in {@link soc.client.SOCBoardPanel.BoardToolTip#paint()}.
*/
switch(mode) {
case MOVE_SHIP:
if (moveShip_fromEdge != 0)
drawRoadOrShip(g, moveShip_fromEdge, -1, false, false, moveShip_isWarship);
case PLACE_ROAD:
case PLACE_INIT_ROAD:
case PLACE_FREE_ROAD_OR_SHIP:
if (hilight != 0) {
drawRoadOrShip(g, hilight, playerNumber, true, !hilightIsShip, (moveShip_isWarship && (moveShip_fromEdge != 0)));
}
break;
case PLACE_SETTLEMENT:
case PLACE_INIT_SETTLEMENT:
if (hilight > 0) {
drawSettlement(g, hilight, playerNumber, true, false);
}
break;
case PLACE_CITY:
if (hilight > 0) {
drawCity(g, hilight, playerNumber, true);
}
break;
case PLACE_SHIP:
if (hilight > 0) {
drawRoadOrShip(g, hilight, playerNumber, true, false, false);
}
break;
case CONSIDER_LM_SETTLEMENT:
case CONSIDER_LT_SETTLEMENT:
if (hilight > 0) {
drawSettlement(g, hilight, otherPlayer.getPlayerNumber(), true, false);
}
break;
case CONSIDER_LM_ROAD:
case CONSIDER_LT_ROAD:
if (hilight != 0) {
drawRoadOrShip(g, hilight, otherPlayer.getPlayerNumber(), false, true, false);
}
break;
case CONSIDER_LM_CITY:
case CONSIDER_LT_CITY:
if (hilight > 0) {
drawCity(g, hilight, otherPlayer.getPlayerNumber(), true);
}
break;
case PLACE_ROBBER:
if (hilight > 0) {
drawRobber(g, hilight, true, true);
}
break;
case PLACE_PIRATE:
if (hilight > 0) {
drawRoadOrShip(g, hilight, -2, false, false, false);
}
break;
case SC_FTRI_PLACE_PORT:
drawBoard_SC_FTRI_placePort(g);
break;
}
if (xlat)
g.translate(-panelMarginX, -panelMarginY);
}
if (superText1 != null) {
drawSuperText(g);
}
if (superTextTop != null) {
drawSuperTextTop(g);
}
}
use of soc.game.SOCBoardLarge in project JSettlers2 by jdmonin.
the class SOCBoardPanel method mouseClicked.
/**
* DOCUMENT ME!
*
* @param evt DOCUMENT ME!
*/
public void mouseClicked(MouseEvent evt) {
try {
int x = evt.getX();
int y = evt.getY();
if (evt.isPopupTrigger()) {
popupMenuSystime = evt.getWhen();
evt.consume();
doBoardMenuPopup(x, y);
// <--- Pop up menu, nothing else to do ---
return;
}
if (evt.getWhen() < (popupMenuSystime + POPUP_MENU_IGNORE_MS)) {
// <--- Ignore click: too soon after popup click ---
return;
}
boolean tempChangedMode = false;
if ((mode == NONE) && hoverTip.isVisible()) {
if (game.isDebugFreePlacement()) {
if (hoverTip.hoverSettlementID != 0) {
hilight = hoverTip.hoverSettlementID;
hilightIsShip = false;
mode = PLACE_SETTLEMENT;
tempChangedMode = true;
} else if (hoverTip.hoverCityID != 0) {
hilight = hoverTip.hoverCityID;
hilightIsShip = false;
mode = PLACE_CITY;
tempChangedMode = true;
} else if (hoverTip.hoverRoadID != 0) {
hilight = hoverTip.hoverRoadID;
hilightIsShip = false;
mode = PLACE_ROAD;
tempChangedMode = true;
} else if (hoverTip.hoverShipID != 0) {
hilight = hoverTip.hoverShipID;
hilightIsShip = true;
mode = PLACE_SHIP;
tempChangedMode = true;
}
} else if (((evt.getModifiers() & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) && (player != null) && (game.getCurrentPlayerNumber() == playerNumber) && (player.getPublicVP() == 2) && (hintShownCount_RightClickToBuild < 2)) {
// To help during the start of the game, display a hint message
// reminding new users to right-click to build (OSX: control-click).
// Show it at most twice to avoid annoying the user.
++hintShownCount_RightClickToBuild;
final String prompt = (SOCPlayerClient.isJavaOnOSX) ? "board.popup.hint_build_click.osx" : // "To build pieces, hold Control while clicking the build location."
"board.popup.hint_build_click";
// "To build pieces, right-click the build location."
NotifyDialog.createAndShow(playerInterface.getGameDisplay(), playerInterface, "\n" + strings.get(prompt), null, true);
// start prompt with \n to prevent it being a lengthy popup-dialog title
}
}
if ((hilight != 0) && (player != null) && (x == ptrOldX) && (y == ptrOldY)) {
SOCPlayerClient client = playerInterface.getClient();
switch(mode) {
case NONE:
break;
case TURN_STARTING:
break;
case PLACE_INIT_ROAD:
case PLACE_ROAD:
case PLACE_FREE_ROAD_OR_SHIP:
if (hilight == -1)
// Road on edge 0x00
hilight = 0;
if (player.isPotentialRoad(hilight) && !hilightIsShip) {
client.getGameManager().putPiece(game, new SOCRoad(player, hilight, board));
// Now that we've placed, clear the mode and the hilight.
clearModeAndHilight(SOCPlayingPiece.ROAD);
if (tempChangedMode)
hoverTip.hideHoverAndPieces();
} else if (// checks isPotentialShip, pirate ship
game.canPlaceShip(player, hilight)) {
if (game.isGameOptionSet(SOCGameOption.K_SC_FTRI) && ((SOCBoardLarge) board).canRemovePort(hilight)) {
java.awt.EventQueue.invokeLater(new ConfirmPlaceShipDialog(hilight, false, -1));
} else {
client.getGameManager().putPiece(game, new SOCShip(player, hilight, board));
// Now that we've placed, clear the mode and the hilight.
clearModeAndHilight(SOCPlayingPiece.SHIP);
}
if (tempChangedMode)
hoverTip.hideHoverAndPieces();
}
break;
case MOVE_SHIP:
// check and move ship to hilight from fromEdge;
// also sets moveShip_fromEdge = 0, calls clearModeAndHilight.
moveShip_toEdge = hilight;
tryMoveShipToEdge();
break;
case PLACE_INIT_SETTLEMENT:
if (playerNumber == playerInterface.getClientPlayerNumber()) {
initSettlementNode = hilight;
}
case PLACE_SETTLEMENT:
if (player.canPlaceSettlement(hilight)) {
client.getGameManager().putPiece(game, new SOCSettlement(player, hilight, board));
clearModeAndHilight(SOCPlayingPiece.SETTLEMENT);
if (tempChangedMode)
hoverTip.hideHoverAndPieces();
}
break;
case PLACE_CITY:
if (player.isPotentialCity(hilight)) {
client.getGameManager().putPiece(game, new SOCCity(player, hilight, board));
clearModeAndHilight(SOCPlayingPiece.CITY);
if (tempChangedMode)
hoverTip.hideHoverAndPieces();
}
break;
case PLACE_SHIP:
if (// checks isPotentialShip, pirate ship
game.canPlaceShip(player, hilight)) {
if (game.isGameOptionSet(SOCGameOption.K_SC_FTRI) && ((SOCBoardLarge) board).canRemovePort(hilight)) {
java.awt.EventQueue.invokeLater(new ConfirmPlaceShipDialog(hilight, false, -1));
} else {
client.getGameManager().putPiece(game, new SOCShip(player, hilight, board));
clearModeAndHilight(SOCPlayingPiece.SHIP);
}
if (tempChangedMode)
hoverTip.hideHoverAndPieces();
}
break;
case PLACE_ROBBER:
if (hilight != board.getRobberHex()) {
// do we have an adjacent settlement/city?
boolean cliAdjacent = false;
{
for (SOCPlayer pl : game.getPlayersOnHex(hilight)) {
if (pl.getPlayerNumber() == playerNumber) {
cliAdjacent = true;
break;
}
}
}
if (cliAdjacent) {
// ask player to confirm first
java.awt.EventQueue.invokeLater(new MoveRobberConfirmDialog(player, hilight));
} else {
// ask server to move it
client.getGameManager().moveRobber(game, player, hilight);
clearModeAndHilight(-1);
}
}
break;
case PLACE_PIRATE:
if (hilight != ((SOCBoardLarge) board).getPirateHex()) {
// do we have an adjacent ship?
boolean cliAdjacent = false;
{
for (SOCPlayer pl : game.getPlayersShipsOnHex(hilight)) {
if (pl.getPlayerNumber() == playerNumber) {
cliAdjacent = true;
break;
}
}
}
if (cliAdjacent) {
// ask player to confirm first
java.awt.EventQueue.invokeLater(new MoveRobberConfirmDialog(player, -hilight));
} else {
// ask server to move it
client.getGameManager().moveRobber(game, player, -hilight);
clearModeAndHilight(-1);
}
}
break;
case SC_FTRI_PLACE_PORT:
if (hilight != 0) {
int edge = hilight;
if (edge == -1)
edge = 0;
if (game.canPlacePort(player, edge)) {
// Ask server to place here.
client.getGameManager().sendSimpleRequest(player, SOCSimpleRequest.TRADE_PORT_PLACE, hilight, 0);
hilight = 0;
}
}
break;
case CONSIDER_LM_SETTLEMENT:
if (otherPlayer.canPlaceSettlement(hilight)) {
client.getGameManager().considerMove(game, otherPlayer.getName(), new SOCSettlement(otherPlayer, hilight, board));
clearModeAndHilight(SOCPlayingPiece.SETTLEMENT);
}
break;
case CONSIDER_LM_ROAD:
if (otherPlayer.isPotentialRoad(hilight)) {
client.getGameManager().considerMove(game, otherPlayer.getName(), new SOCRoad(otherPlayer, hilight, board));
clearModeAndHilight(SOCPlayingPiece.ROAD);
}
break;
case CONSIDER_LM_CITY:
if (otherPlayer.isPotentialCity(hilight)) {
client.getGameManager().considerMove(game, otherPlayer.getName(), new SOCCity(otherPlayer, hilight, board));
clearModeAndHilight(SOCPlayingPiece.CITY);
}
break;
case CONSIDER_LT_SETTLEMENT:
if (otherPlayer.canPlaceSettlement(hilight)) {
client.getGameManager().considerTarget(game, otherPlayer.getName(), new SOCSettlement(otherPlayer, hilight, board));
clearModeAndHilight(SOCPlayingPiece.SETTLEMENT);
}
break;
case CONSIDER_LT_ROAD:
if (otherPlayer.isPotentialRoad(hilight)) {
client.getGameManager().considerTarget(game, otherPlayer.getName(), new SOCRoad(otherPlayer, hilight, board));
clearModeAndHilight(SOCPlayingPiece.ROAD);
}
break;
case CONSIDER_LT_CITY:
if (otherPlayer.isPotentialCity(hilight)) {
client.getGameManager().considerTarget(game, otherPlayer.getName(), new SOCCity(otherPlayer, hilight, board));
clearModeAndHilight(SOCPlayingPiece.CITY);
}
break;
}
} else if ((player != null) && ((game.getCurrentPlayerNumber() == playerNumber) || game.isDebugFreePlacement())) {
// No hilight. But, they clicked the board, expecting something.
// It's possible the mode is incorrect.
// Update and wait for the next click.
updateMode();
ptrOldX = 0;
ptrOldY = 0;
// mouseMoved will establish hilight using click's x,y
mouseMoved(evt);
}
evt.consume();
if (tempChangedMode)
mode = NONE;
} catch (Throwable th) {
playerInterface.chatPrintStackTrace(th);
}
}
use of soc.game.SOCBoardLarge in project JSettlers2 by jdmonin.
the class SOCDisplaylessPlayerClient method handlePIECEVALUE.
/**
* Update a village piece's value on the board (cloth remaining) in _SC_CLVI,
* or a pirate fortress's strength in _SC_PIRI.
* @since 2.0.00
*/
protected void handlePIECEVALUE(final SOCPieceValue mes) {
final String gaName = mes.getGame();
SOCGame ga = games.get(gaName);
if (ga == null)
// Not one of our games
return;
if (!ga.hasSeaBoard)
// should not happen
return;
final int coord = mes.getParam1();
final int pv = mes.getParam2();
if (ga.isGameOptionSet(SOCGameOption.K_SC_CLVI)) {
SOCVillage vi = ((SOCBoardLarge) (ga.getBoard())).getVillageAtNode(coord);
if (vi != null)
vi.setCloth(pv);
} else if (ga.isGameOptionSet(SOCGameOption.K_SC_PIRI)) {
SOCFortress fort = ga.getFortress(coord);
if (fort != null)
fort.setStrength(pv);
}
}
use of soc.game.SOCBoardLarge in project JSettlers2 by jdmonin.
the class SOCDisplaylessPlayerClient method handleSIMPLEACTION.
/**
* Update any game data from "simple action" announcements from the server.
* Currently ignores them except for:
*<UL>
* <LI> {@link SOCSimpleAction#TRADE_PORT_REMOVED TRADE_PORT_REMOVED}:
* Calls {@link SOCGame#removePort(SOCPlayer, int)}
*</UL>
*
* @param games Games the client is playing, for method reuse by SOCPlayerClient
* @param mes the message
* @since 1.1.19
*/
public static void handleSIMPLEACTION(final Map<String, SOCGame> games, final SOCSimpleAction mes) {
final String gaName = mes.getGame();
SOCGame ga = games.get(gaName);
if (ga == null)
// Not one of our games
return;
final int atype = mes.getActionType();
switch(atype) {
case SOCSimpleAction.BOARD_EDGE_SET_SPECIAL:
{
final SOCBoard bd = ga.getBoard();
if (bd instanceof SOCBoardLarge)
((SOCBoardLarge) bd).setSpecialEdge(mes.getValue1(), mes.getValue2());
}
break;
case SOCSimpleAction.TRADE_PORT_REMOVED:
if (ga.hasSeaBoard)
ga.removePort(null, mes.getValue1());
break;
case SOCSimpleAction.DEVCARD_BOUGHT:
case SOCSimpleAction.RSRC_TYPE_MONOPOLIZED:
case SOCSimpleAction.SC_PIRI_FORT_ATTACK_RESULT:
// game data updates are sent in preceding or following messages, can ignore this one
break;
default:
// ignore unknown types
// Since the bots and server are almost always the same version, this
// shouldn't often occur: print for debugging.
System.err.println("handleSIMPLEACTION: Unknown type ignored: " + atype + " in game " + gaName);
}
}
use of soc.game.SOCBoardLarge in project JSettlers2 by jdmonin.
the class SOCDisplaylessPlayerClient method handlePOTENTIALSETTLEMENTS.
/**
* handle the "list of potential settlements" message
* @param mes the message
* @param games The hashtable of client's {@link SOCGame}s; key = game name
* @throws IllegalStateException if the board has
* {@link SOCBoardLarge#getAddedLayoutPart(String) SOCBoardLarge.getAddedLayoutPart("AL")} != {@code null} but
* badly formed (node list number 0, or a node list number not followed by a land area number).
* This Added Layout Part is rarely used, and this would be discovered quickly while testing
* the board layout that contained it.
*/
public static void handlePOTENTIALSETTLEMENTS(SOCPotentialSettlements mes, Hashtable<String, SOCGame> games) throws IllegalStateException {
SOCGame ga = games.get(mes.getGame());
if (ga == null)
return;
final List<Integer> vset = mes.getPotentialSettlements();
final HashSet<Integer>[] las = mes.landAreasLegalNodes;
// must set for players after pl.setPotentialAndLegalSettlements, if not null
final int[] loneSettles;
// usually null, except in _SC_PIRI
final int[][] legalSeaEdges = mes.legalSeaEdges;
int pn = mes.getPlayerNumber();
if (ga.hasSeaBoard) {
SOCBoardLarge bl = ((SOCBoardLarge) ga.getBoard());
if ((pn == -1) || ((pn == 0) && bl.getLegalSettlements().isEmpty()))
bl.setLegalSettlements(vset, mes.startingLandArea, // throws IllegalStateException if board layout
las);
// has malformed Added Layout Part "AL"
// usually null, except in _SC_PIRI
loneSettles = bl.getAddedLayoutPart("LS");
} else {
loneSettles = null;
}
if (pn != -1) {
SOCPlayer player = ga.getPlayer(pn);
player.setPotentialAndLegalSettlements(vset, true, las);
if (loneSettles != null)
player.addLegalSettlement(loneSettles[pn], false);
if (legalSeaEdges != null)
player.setRestrictedLegalShips(legalSeaEdges[0]);
} else {
for (pn = ga.maxPlayers - 1; pn >= 0; --pn) {
SOCPlayer pl = ga.getPlayer(pn);
pl.setPotentialAndLegalSettlements(vset, true, las);
if (loneSettles != null)
pl.addLegalSettlement(loneSettles[pn], false);
if (legalSeaEdges != null)
pl.setRestrictedLegalShips(legalSeaEdges[pn]);
}
}
}
Aggregations