📄 citybuilder.java
字号:
} else if (choice < 6) { // turn left nextDirection = (5 + nextDirection) % 6; } else if (choice < 8) { //turn right nextDirection = (1 + nextDirection) % 6; } else { //turn towards base direction nextDirection = baseDirection; } } coords = extendRoad(coords, nextDirection, roadStyle); if(coords == null || (cityPlan.contains(coords) && x!=midX && y!=midY)) { break; } cityPlan.add(coords); x = coords.x; y = coords.y; } } } private void buildMetroCity(int maxX, int maxY){ int midX = maxX/2; int midY = maxY/2; cityPlan.add(new Coords(midX,midY)); //have the city hub be the mid point with all the hexes around it cleared out for ( int hex=0; hex < 6; hex++ ) cityPlan.add(new Coords(Coords.xInDir(midX,midY,hex),Coords.yInDir(midX,midY,hex))); //first east west road Coords coords = new Coords(-1, midY/2); buildStraightRoad(coords, E, 1); //second east west road coords = new Coords(-1, midY+(midY/2)); buildStraightRoad(coords, E, 1); //First North South Road coords = new Coords(midX/2, -1); buildStraightRoad(coords, S, 1); //second North South Road coords = new Coords(midX+(midX/2), -1); buildStraightRoad(coords, S, 1); for ( int dir = 0; dir < 8; dir++){ coords = new Coords(midX,midY); buildStraightRoad(coords, dir, 2); } } private Coords selectNextGrid(int dir, Coords coords){ Coords result = coords.translated(dir); if ( dir == E ) result.x++; if ( dir == W ) result.x--; return result; } /** * * @param hex * @return true if it is reasonable to build on this hex */ private boolean isHexBuildable(IHex hex) { if(hex.containsTerrain(Terrains.WATER) || hex.containsTerrain(Terrains.IMPASSABLE) || hex.containsTerrain(Terrains.MAGMA) || hex.containsTerrain(Terrains.SWAMP)) { return false; //uneconomic to build here } if(hex.getElevation() >= 4) { return false; //don't build on mountaintops (aesthetics) } return true; } /** * * @param hex * @return true if the hex needs a bridge to cross */ private boolean hexNeedsBridge(IHex hex) { if(hex.containsTerrain(Terrains.ROAD) || hex.containsTerrain(Terrains.BRIDGE)) return false; return(hex.containsTerrain(Terrains.WATER) || hex.containsTerrain(Terrains.MAGMA)); } private void addRoad(IHex hex, int exitDirection, int type) { ITerrainFactory tf = Terrains.getTerrainFactory(); if(hex.containsTerrain(Terrains.WATER)) { hex.removeTerrain(Terrains.WATER); hex.addTerrain(tf.createTerrain(Terrains.WATER, 0)); type = 1; } hex.addTerrain(tf.createTerrain(Terrains.ROAD, type, true, (1<<exitDirection) & 63)); } private void addBridge(IHex hex, int exits, int altitude, int cf) { ITerrainFactory tf = Terrains.getTerrainFactory(); int bridgeElevation = altitude - hex.getElevation(); hex.addTerrain(tf.createTerrain(Terrains.BRIDGE, getBuildingTypeByCF(cf), true, (exits & 63))); hex.addTerrain(tf.createTerrain(Terrains.BRIDGE_ELEV, bridgeElevation)); hex.addTerrain(tf.createTerrain(Terrains.BRIDGE_CF, cf)); } private void connectHexes(Coords src, Coords dest, int roadStyle) { if(board.contains(src)) { IHex hex = board.getHex(src); ITerrain t = hex.getTerrain(Terrains.ROAD); if(t == null) { t = hex.getTerrain(Terrains.BRIDGE); } if(t == null) { addRoad(hex, src.direction(dest), roadStyle); } else { t.setExit(src.direction(dest), true); } } } /** * Build a bridge across an obstacle * @todo: use a bridge not a road when bridges are working * @param board * @param start * @param direction * @return coordinates to resume roadbuilding */ private Coords tryToBuildBridge(Coords start, int direction) { if(!board.contains(start))return null; Vector<Coords> hexes = new Vector(7); Coords end = null; Coords next = start.translated(direction); while(hexes.size() < 6) { if(!board.contains(next)) { //offboard, why bother? break; } if(!hexNeedsBridge(board.getHex(next))) { end = next; break; } hexes.add(next); next = next.translated(direction); } if(end != null) { //got start and end, can we make a bridge? if(hexes.size() == 0) return null; int elev1 = board.getHex(start).getElevation(); int elev2 = board.getHex(end).getElevation(); int elevBridge = board.getHex(end).terrainLevel(Terrains.BRIDGE); if(elevBridge >=0) { if(Math.abs(elev2 + elevBridge - elev1) > 2) return null; elev1 = elev2 + elevBridge; } else { if(Math.abs(elev1-elev2) > 4) { //nobody could use the bridge, give up return null; } elev1 = (elev1 + elev2) / 2; } //build the bridge int exits = (1<<direction) | (1<<((direction + 3) %6)); int cf = mapSettings.getCityMinCF() + Compute.randomInt(1 + mapSettings.getCityMaxCF() - mapSettings.getCityMinCF()); for(Enumeration<Coords> e=hexes.elements();e.hasMoreElements();) { Coords c = e.nextElement(); addBridge(board.getHex(c), exits, elev1, cf); } connectHexes(start, hexes.firstElement(), 1); connectHexes(end, hexes.lastElement(), 1); } return end; } private Coords extendRoad(Coords coords, int nextDirection, int roadStyle) { Coords next = selectNextGrid(nextDirection,coords); if(board.contains(next) && hexNeedsBridge(board.getHex(next))) { if(nextDirection==E || nextDirection==W) { nextDirection = coords.direction(next); } Coords end = tryToBuildBridge(coords, nextDirection); return end; } connectHexes(coords, next, roadStyle); connectHexes(next, coords, roadStyle); return next; } private Coords resumeAfterObstacle(Coords coords, int nextDirection) { Coords next = selectNextGrid(nextDirection, coords); while(board.contains(next) && !isHexBuildable(board.getHex(next))) { next = selectNextGrid(nextDirection, next); } return next; } private void buildStraightRoad(Coords start, int direction, int roadStyle) { Coords coords = start; while ( coords != null && coords.x <= board.getWidth() && coords.x >= -1 && coords.y <= board.getHeight() && coords.y >= -1){ cityPlan.add(coords); Coords next = extendRoad(coords, direction, roadStyle); if(next == null) { coords = resumeAfterObstacle(coords, direction); } else coords = next; } } /** * Utility function for setting building type from CF table * @param cf * @return building type */ public static int getBuildingTypeByCF(int cf) { if(cf <= 15) return Building.LIGHT; if(cf <= 40) return Building.MEDIUM; if(cf <= 90) return Building.HEAVY; return Building.HARDENED; } /** * Adds an Road to the map. Goes from one border to another, and * has one turn in it. Map must be at least 3x3. */ private void addGenericRoad() { Coords c = new Coords(Compute.randomInt(board.getWidth()), Compute.randomInt(board.getHeight())); int side0 = Compute.randomInt(6); int side1 = Compute.randomInt(5); if (side1 >= side0) { side1++; } buildStraightRoad(c, side0, 1); buildStraightRoad(c, side1, 1); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -