Search in sources :

Example 11 with SOCBoardLarge

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

the class SOCDisplaylessPlayerClient method handleBOARDLAYOUT2.

/**
 * handle the "board layout" message, new format
 * @param games  Games the client is playing, for method reuse by SOCPlayerClient
 * @param mes  the message
 * @since 1.1.08
 * @return True if game was found and layout understood, false otherwise
 */
public static boolean handleBOARDLAYOUT2(Map<String, SOCGame> games, SOCBoardLayout2 mes) {
    SOCGame ga = games.get(mes.getGame());
    if (ga == null)
        return false;
    SOCBoard bd = ga.getBoard();
    final int bef = mes.getBoardEncodingFormat();
    if (bef == SOCBoard.BOARD_ENCODING_LARGE) {
        // v3
        ((SOCBoardLarge) bd).setLandHexLayout(mes.getIntArrayPart("LH"));
        ga.setPlayersLandHexCoordinates();
        int hex = mes.getIntPart("RH");
        if (hex != 0)
            bd.setRobberHex(hex, false);
        hex = mes.getIntPart("PH");
        if (hex != 0)
            ((SOCBoardLarge) bd).setPirateHex(hex, false);
        int[] portLayout = mes.getIntArrayPart("PL");
        if (portLayout != null)
            bd.setPortsLayout(portLayout);
        int[] x = mes.getIntArrayPart("PX");
        if (x != null)
            ((SOCBoardLarge) bd).setPlayerExcludedLandAreas(x);
        x = mes.getIntArrayPart("RX");
        if (x != null)
            ((SOCBoardLarge) bd).setRobberExcludedLandAreas(x);
        x = mes.getIntArrayPart("CV");
        if (x != null)
            ((SOCBoardLarge) bd).setVillageAndClothLayout(x);
        x = mes.getIntArrayPart("LS");
        if (x != null)
            ((SOCBoardLarge) bd).addLoneLegalSettlements(ga, x);
        HashMap<String, int[]> others = mes.getAddedParts();
        if (others != null)
            ((SOCBoardLarge) bd).setAddedLayoutParts(others);
    } else if (bef <= SOCBoard.BOARD_ENCODING_6PLAYER) {
        // v1 or v2
        bd.setHexLayout(mes.getIntArrayPart("HL"));
        bd.setNumberLayout(mes.getIntArrayPart("NL"));
        bd.setRobberHex(mes.getIntPart("RH"), false);
        int[] portLayout = mes.getIntArrayPart("PL");
        if (portLayout != null)
            bd.setPortsLayout(portLayout);
    } else {
        // Should not occur: Server has sent an unrecognized format
        System.err.println("Cannot recognize game encoding v" + bef + " for game " + ga.getName());
        return false;
    }
    ga.updateAtBoardLayout();
    return true;
}
Also used : SOCBoardLarge(soc.game.SOCBoardLarge) SOCBoard(soc.game.SOCBoard) SOCGame(soc.game.SOCGame)

Example 12 with SOCBoardLarge

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

the class SOCBoardPanel method flushBoardLayoutAndRepaint.

/**
 * Clear the board layout (as rendered in the empty-board buffer) and trigger a repaint.
 *<P>
 * If needed, update margins and visual shift from Added Layout Part {@code "VS"}.
 * Doing so will call {@link #rescaleBoard(int, int, boolean)} and may change
 * the board panel's minimum size and/or current size. Returns true if current size changes
 * here: If so, caller must re-do layout of this panel within its container.
 *<P>
 * "VS" is part of the initial board layout from the server and its value won't change at
 * start of the game. This method and {@code rescaleBoard} check for zero or changed margins because
 * the board layout and margins are unknown (0) at SOCBoardPanel construction time.
 *
 * @return  Null unless current {@link #getSize()} has changed from Visual Shift ({@code "VS"}).
 *     If not null, the delta change (new - old) in this panel's width and height
 * @since 1.1.08
 * @see SOCPlayerInterface#updateAtNewBoard()
 */
public Dimension flushBoardLayoutAndRepaint() {
    Dimension ret = null;
    if (board instanceof SOCBoardLarge) {
        final int prevSBX = panelShiftBX, prevSBY = panelShiftBY;
        final int sBX, sBY;
        boolean changed = false;
        int[] boardVS = ((SOCBoardLarge) board).getAddedLayoutPart("VS");
        if (boardVS != null) {
            sBY = (boardVS[0] * halfdeltaY) / 2;
            sBX = (boardVS[1] * halfdeltaX) / 2;
        } else {
            sBY = 0;
            sBX = 0;
        }
        if (sBX != prevSBX) {
            if (prevSBX > 0)
                panelMinBW -= prevSBX;
            panelShiftBX = sBX;
            changed = true;
            if (sBX > 0)
                panelMinBW += sBX;
        }
        if (sBY != prevSBY) {
            if (prevSBY > 0)
                panelMinBH -= prevSBY;
            panelShiftBY = sBY;
            changed = true;
            if (sBY > 0)
                panelMinBH += sBY;
        }
        if (changed) {
            final int w = scaledPanelW, h = scaledPanelH;
            rescaleBoard(w, h, true);
            // If margins increased, also may have updated minSize, panelMinBW, scaledPanelH, etc.
            if ((w != scaledPanelW) || (h != scaledPanelH)) {
                ret = new Dimension(scaledPanelW - w, scaledPanelH - h);
                super.setSize(scaledPanelW, scaledPanelH);
            }
        }
    }
    if (emptyBoardBuffer != null) {
        emptyBoardBuffer.flush();
        emptyBoardBuffer = null;
    }
    if (isScaled) {
        // reset the image-scaling timeout
        scaledAt = System.currentTimeMillis();
        scaledMissedImage = false;
    }
    repaint();
    return ret;
}
Also used : SOCBoardLarge(soc.game.SOCBoardLarge) Dimension(java.awt.Dimension)

Example 13 with SOCBoardLarge

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

the class SOCBoardPanel method drawBoardEmpty.

/**
 * Draw the whole board (water, hexes, ports, numbers) but no placed pieces.
 * This is drawn once, then stored.
 * If the board layout changes (at start of game or
 * {@link SOCBoardLarge#FOG_HEX fog hex} reveal, for example),
 * call {@link #flushBoardLayoutAndRepaint()} to clear the buffered copy.
 *<P>
 * For scenario option {@link SOCGameOption#K_SC_CLVI _SC_CLVI},
 * <tt>drawBoardEmpty</tt> draws the board's {@link SOCVillage}s.
 *<P>
 * If {@link #panelMarginX} or {@link #panelMarginY} != 0, do not translate {@code g}
 * before calling. This method will internally translate.
 *
 * @param g Graphics, typically from {@link #emptyBoardBuffer}
 * @since 1.1.08
 * @see SOCPlayerInterface#updateAtNewBoard()
 */
private void drawBoardEmpty(Graphics g) {
    // ask for antialiasing if available
    if (g instanceof Graphics2D)
        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    Set<Integer> landHexShow;
    final int SC_6;
    if (debugShowPotentials[8] && isLargeBoard) {
        landHexShow = ((SOCBoardLarge) board).getLandHexCoordsSet();
        SC_6 = scaleToActual(6);
    } else {
        // almost always null, unless debugging large board
        landHexShow = null;
        // unused unless debugging large board
        SC_6 = 0;
    }
    g.setPaintMode();
    g.setColor(getBackground());
    g.fillRect(0, 0, scaledPanelW, scaledPanelH);
    if (scaledPorts[0] == null) {
        // Check if port graphics are ready.  This probably isn't needed, because
        // doLayout already called position/sizing methods which call rescaleBoard.
        renderPortImages();
    }
    final boolean xlat = (panelMarginX != 0) || (panelMarginY != 0);
    if (xlat)
        g.translate(panelMarginX, panelMarginY);
    // drawHex will set scaledMissedImage if missed.
    if (!isLargeBoard) {
        // Draw water hexes to all edges of the panel;
        // these are outside the board coordinate system.
        boolean isRowOffset = isRotated;
        for (int hy = -deltaY; hy < panelMinBH; hy += deltaY, isRowOffset = !isRowOffset) {
            int hx = 0;
            if (isRowOffset)
                hx -= halfdeltaX;
            for (; hx < panelMinBW; hx += deltaX) if (0 == findHex(hx, hy))
                drawHex(g, hx, hy, SOCBoard.WATER_HEX, -1, -1);
        }
        if (is6player)
            drawPortsRing(g);
        for (int i = 0; i < hexX.length; i++) if ((inactiveHexNums == null) || !inactiveHexNums[i])
            drawHex(g, i);
    } else {
        // Large Board has a rectangular array of hexes.
        // (r,c) are board coordinates.
        // (x,y) are unscaled pixel coordinates.
        // Top border rows:
        final int bMarginX = scaleFromActual(panelMarginX), marginNumHex = (bMarginX + deltaX - 1) / deltaX;
        // Top border ("row -2"): Needed only when panelMarginY is +1 or more "VS" units (1/4 or more of row height)
        if (panelMarginY >= (halfdeltaY / 2)) {
            final int y = -halfdeltaY - deltaY, xmin = -(deltaX * marginNumHex) - halfdeltaX;
            for (int x = xmin; x < panelMinBW; x += deltaX) {
                drawHex(g, x, y, SOCBoard.WATER_HEX, -1, -1);
            }
        }
        // The initial x-coord formula aligns just enough water hexes to cover -panelMarginX.
        for (int x = -(deltaX * marginNumHex); x < panelMinBW; x += deltaX) {
            drawHex(g, x, -halfdeltaY, SOCBoard.WATER_HEX, -1, -1);
        }
        // In-bounds board hexes and bottom border:
        final int bw = board.getBoardWidth(), bh = board.getBoardHeight();
        for (int r = 1, y = halfdeltaY; r < bh || y < (scaledPanelH + HEXY_OFF_SLOPE_HEIGHT); r += 2, y += deltaY) {
            final int rshift = (r << 8);
            int c, x;
            if (((r / 2) % 2) == 1) {
                // odd hex rows start at 1
                c = 1;
                x = 0;
            } else {
                // top row, even rows start at 2
                c = 2;
                x = halfdeltaX;
            }
            if ((panelMarginX != 0) || (x != 0)) {
                // xleft drawn at >= 0 after g.translate for panelMarginX
                for (int xleft = x; xleft > -(panelMarginX + deltaX); xleft -= deltaX) drawHex(g, xleft, y, SOCBoard.WATER_HEX, -1, -1);
            }
            for (; c < bw; c += 2, x += deltaX) {
                final int hexCoord = rshift | c;
                final int hexType = (r < bh) ? board.getHexTypeFromCoord(hexCoord) : SOCBoard.WATER_HEX;
                drawHex(g, x, y, hexType, -1, hexCoord);
                if ((landHexShow != null) && landHexShow.contains(new Integer(hexCoord))) {
                    g.setColor(Color.RED);
                    g.drawRoundRect(scaleToActual(x + (halfdeltaX / 2)), scaleToActual(y + ((halfdeltaY + HEXY_OFF_SLOPE_HEIGHT) / 2) + 1), scaleToActual(halfdeltaX), scaleToActual(halfdeltaY + 1), SC_6, SC_6);
                }
            }
            // If board is narrower than panel, fill in with water
            int xmax = panelMinBW - 1;
            if (panelMarginX < 0)
                xmax -= panelMarginX;
            while (x < xmax) {
                final int hexCoord = rshift | c;
                drawHex(g, x, y, SOCBoard.WATER_HEX, -1, hexCoord);
                c += 2;
                x += deltaX;
            }
        }
        // All ports
        drawPorts_LargeBoard(g);
        // For scenario _SC_PIRI, check for the Pirate Path and Lone Settlement locations.
        // Draw path only if the pirate fleet is still on the board
        // Draw our player's permitted sea edges for ships, if restricted
        {
            final int[] ppath = ((SOCBoardLarge) board).getAddedLayoutPart("PP");
            if ((ppath != null) && (0 != ((SOCBoardLarge) board).getPirateHex()))
                drawBoardEmpty_drawPiratePath(g, ppath);
            final int[] ls = ((SOCBoardLarge) board).getAddedLayoutPart("LS");
            if (ls != null) {
                for (int pn = 0; pn < ls.length; ++pn) if (ls[pn] != 0)
                    drawSettlement(g, ls[pn], pn, false, true);
            }
            final HashSet<Integer> lse = (player != null) ? player.getRestrictedLegalShips() : null;
            if (lse != null)
                drawSeaEdgeLines(g, null, lse);
        }
        // For scenario _SC_FTRI, draw markers at the SVP edges and dev card edges (added layout parts "CE", "VE")
        if (((SOCBoardLarge) board).hasSpecialEdges())
            drawBoardEmpty_specialEdges(g);
        // For scenario _SC_CLVI, draw the cloth villages
        HashMap<Integer, SOCVillage> villages = ((SOCBoardLarge) board).getVillages();
        if (villages != null) {
            Iterator<SOCVillage> villIter = villages.values().iterator();
            while (villIter.hasNext()) drawVillage(g, villIter.next());
        }
        // For scenario _SC_WOND, draw special nodes (layout parts N1, N2, N3)
        if (game.isGameOptionSet(SOCGameOption.K_SC_WOND)) {
            // brown
            drawBoardEmpty_specialNodes(g, "N1", new Color(180, 90, 40));
            // violet
            drawBoardEmpty_specialNodes(g, "N2", new Color(120, 40, 120));
            drawBoardEmpty_specialNodes(g, "N3", Color.RED);
        }
        // check debugShowPotentials[0 - 9]
        drawBoardEmpty_drawDebugShowPotentials(g);
    }
    if (xlat)
        g.translate(-panelMarginX, -panelMarginY);
    if (scaledMissedImage) {
        // With recent board resize, one or more rescaled images still hasn't
        // been completed after 7 seconds.  We've asked for a new scaled copy
        // of this image.  Repaint now, and repaint 3 seconds later.
        // (The delay gives time for the new scaling to complete.)
        scaledAt = System.currentTimeMillis();
        repaint();
        new DelayedRepaint(this).start();
    }
}
Also used : SOCVillage(soc.game.SOCVillage) SOCBoardLarge(soc.game.SOCBoardLarge) Color(java.awt.Color) Graphics2D(java.awt.Graphics2D) HashSet(java.util.HashSet)

Example 14 with SOCBoardLarge

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

the class SOCBoardPanel method setDebugShowPotentialsFlag.

/**
 * Set or clear a debug flag to show player 0's potential/legal coordinate sets.
 * Currently implemented only for the sea board layout ({@link SOCBoardLarge}).
 * @param pieceType  Piece type; 0=road, 1=settle, 2=city, 3=ship;
 *         Use 8 for land hexes, 9 for nodes on board.  Or, -1 for all.
 *         See {@link #debugShowPotentials} javadoc for all values.
 * @param setPotential  If true, show/hide the potential set, not the legal set
 * @param setOn  If true, set the flag; if false, clear it
 * @since 2.0.00
 */
void setDebugShowPotentialsFlag(int pieceType, final boolean setPotential, final boolean setOn) {
    if (pieceType == -1) {
        // all flags
        Arrays.fill(debugShowPotentials, setOn);
    } else {
        if (setPotential && (pieceType < 4))
            pieceType += 4;
        if (setOn == debugShowPotentials[pieceType])
            // nothing to do
            return;
        debugShowPotentials[pieceType] = setOn;
    }
    // force redraw of the empty board
    scaledMissedImage = true;
    // to call drawBoard, drawBoardEmpty
    repaint();
    if (setOn && ((pieceType == 2) || (pieceType == -1))) {
        int[] vs = (board instanceof SOCBoardLarge) ? ((SOCBoardLarge) board).getAddedLayoutPart("VS") : null;
        if (vs == null)
            vs = new int[] { 0, 0 };
        System.err.println("debugShowPotentials: Board size (height, width) = 0x" + Integer.toHexString(board.getBoardWidth()) + ",0x" + Integer.toHexString(board.getBoardHeight()) + ", VS (down, right) = " + vs[0] + "," + vs[1]);
        System.err.println("  Panel size (width, height): unscaled = " + panelMinBW + "," + panelMinBH + ((isRotated) ? ", rotated" : "") + ", current = " + scaledPanelW + "," + scaledPanelH + ", margin (left, top) = " + panelMarginX + "," + panelMarginY + ", unscaled shift (right, down) = " + panelShiftBX + "," + panelShiftBY);
        int w = playerInterface.getWidth(), h = playerInterface.getHeight();
        Insets ins = playerInterface.getInsets();
        System.err.println("  PI window size (width, height) = " + w + "," + h + ", inner = " + (w - ins.left - ins.right) + "," + (h - ins.top - ins.bottom) + ", insets (left, right, top, bottom) = " + ins.left + "," + ins.right + "," + ins.top + "," + ins.bottom);
    }
}
Also used : SOCBoardLarge(soc.game.SOCBoardLarge) Insets(java.awt.Insets)

Example 15 with SOCBoardLarge

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

the class SOCBoardPanel method drawBoardEmpty_specialEdges.

/**
 * For the {@link SOCGameOption#K_SC_FTRI _SC_FTRI} game scenario on {@link SOCBoardLarge},
 * draw markers at all Special Edges for the players to reach and be rewarded.
 *<P>
 * Each marker's color will be determined by its edge's type, such as {@link SOCBoardLarge#SPECIAL_EDGE_DEV_CARD}.
 * Unknown types will be drawn gray.
 * @since 2.0.00
 */
private final void drawBoardEmpty_specialEdges(final Graphics g) {
    Iterator<Map.Entry<Integer, Integer>> seIter = ((SOCBoardLarge) board).getSpecialEdges();
    while (seIter.hasNext()) {
        final Map.Entry<Integer, Integer> entry = seIter.next();
        // marker color
        final Color mc;
        switch(entry.getValue()) {
            case SOCBoardLarge.SPECIAL_EDGE_DEV_CARD:
                mc = Color.YELLOW;
                break;
            case SOCBoardLarge.SPECIAL_EDGE_SVP:
                mc = Color.GREEN;
                break;
            default:
                mc = Color.LIGHT_GRAY;
        }
        final int edge = entry.getKey();
        // col, row to calculate x, y
        int x = edge & 0xFF, y = edge >> 8;
        final boolean edgeNotVertical = ((y % 2) == 0);
        x = x * halfdeltaX;
        y = y * halfdeltaY + HALF_HEXHEIGHT;
        // its center is slightly offset from the grid
        if (edgeNotVertical)
            x += (halfdeltaX / 2);
        x = scaleToActual(x);
        y = scaleToActual(y);
        drawMarker(g, x, y, mc, -1);
    }
}
Also used : SOCBoardLarge(soc.game.SOCBoardLarge) Color(java.awt.Color) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

SOCBoardLarge (soc.game.SOCBoardLarge)19 SOCBoard (soc.game.SOCBoard)6 SOCPlayer (soc.game.SOCPlayer)6 SOCShip (soc.game.SOCShip)6 SOCGame (soc.game.SOCGame)5 ArrayList (java.util.ArrayList)4 SOCRoad (soc.game.SOCRoad)4 Graphics2D (java.awt.Graphics2D)3 SOCCity (soc.game.SOCCity)3 SOCFortress (soc.game.SOCFortress)3 SOCVillage (soc.game.SOCVillage)3 Color (java.awt.Color)2 HashSet (java.util.HashSet)2 Vector (java.util.Vector)2 SOCInventoryItem (soc.game.SOCInventoryItem)2 SOCResourceSet (soc.game.SOCResourceSet)2 SOCSettlement (soc.game.SOCSettlement)2 AlphaComposite (java.awt.AlphaComposite)1 BasicStroke (java.awt.BasicStroke)1 Composite (java.awt.Composite)1