📄 citybuilder.java
字号:
/* * MegaMek - Copyright (C) 2000-2005 Ben Mazur (bmazur@sev.org) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */package megamek.common.util;import java.util.Enumeration;import java.util.HashSet;import java.util.Vector;import megamek.common.Building;import megamek.common.Compute;import megamek.common.Coords;import megamek.common.IBoard;import megamek.common.IHex;import megamek.common.ITerrain;import megamek.common.ITerrainFactory;import megamek.common.MapSettings;import megamek.common.Terrains;/** * * @author Torren + Coelocanth * */public class CityBuilder { static final int N = 0; static final int NE = 1; static final int SE = 2; static final int S = 3; static final int SW = 4; static final int NW = 5; //Had to off set West and East as MM doesn't use them for hexes. static final int W = 6; static final int E = 7; private MapSettings mapSettings; private IBoard board; private HashSet<Coords> cityPlan; public CityBuilder(MapSettings mapSettings, IBoard board) { super(); // Auto-generated constructor stub this.mapSettings = mapSettings; this.board = board; } /** * This function will generate a city with a grid lay out. * 4 rounds running North and South and 4 roads running east west * * @author Torren (Jason Tighe) * @param buildingTemplate * @return */ public Vector generateCity(boolean genericRoad){ int width = mapSettings.getBoardWidth(); int height = mapSettings.getBoardHeight(); int roads = mapSettings.getCityBlocks(); roads = (roads * Math.min(width, height)) / 16; //scale for bigger maps String cityType = mapSettings.getCityType(); cityPlan = new HashSet<Coords>(); if(genericRoad) { addGenericRoad(); } if ( cityType.equalsIgnoreCase("HUB") ) buildHubCity(width,height,roads); else if ( cityType.equalsIgnoreCase("METRO") ) buildMetroCity(width,height); else if ( cityType.equalsIgnoreCase("GRID")) buildGridCity(width,height,(roads+5) / 6); else if ( cityType.equalsIgnoreCase("TOWN")) return buildTown(width,height,roads,mapSettings.getTownSize()); else return new Vector(); return placeBuildings(0); } public Vector placeBuildings(int radius) { int width = mapSettings.getBoardWidth(); int height = mapSettings.getBoardHeight(); Vector<BuildingTemplate> buildingList = new Vector<BuildingTemplate>(); HashSet<Coords> buildingUsed = new HashSet<Coords>(); Vector coordList = new Vector(); Coords centre = new Coords(width/2,height/2); double falloff = (double)mapSettings.getCityDensity() / (double)(radius*radius); for ( int x = 0; x < width; x++){ for ( int y = 0; y < height; y++ ){ Coords coord = new Coords(x,y); if(cityPlan.contains(coord) || buildingUsed.contains(coord) || !board.contains(coord) || !isHexBuildable(board.getHex(coord))) { continue; } int localdensity = mapSettings.getCityDensity(); if(radius > 0) { int distance = coord.distance(centre); localdensity = (int)(mapSettings.getCityDensity() - (falloff*distance*distance)); } if(Compute.randomInt(100) > localdensity) { continue; //empty lot } coordList = new Vector(); coordList.add(coord); buildingUsed.add(coord); while(Compute.randomInt(100) < localdensity) { //try to make a bigger building! int dir = Compute.randomInt(6); Coords next = coord.translated(dir); if(cityPlan.contains(next) || buildingUsed.contains(next) || !board.contains(next) || !isHexBuildable(board.getHex(next))) { break; //oh well, cant expand here } coordList.add(next); buildingUsed.add(next); } int floors = mapSettings.getCityMaxFloors()-mapSettings.getCityMinFloors(); if ( floors <= 0 ) floors = mapSettings.getCityMinFloors(); else floors = Compute.randomInt(floors + 1)+mapSettings.getCityMinFloors(); int totalCF = mapSettings.getCityMaxCF()-mapSettings.getCityMinCF(); if ( totalCF <= 0) totalCF = mapSettings.getCityMinCF(); else totalCF = Compute.randomInt(totalCF + 1)+mapSettings.getCityMinCF(); int type = getBuildingTypeByCF(totalCF); buildingList.add(new BuildingTemplate(type,coordList,totalCF,floors,-1)); } } return buildingList; } private void buildGridCity(int maxX, int maxY,int roads){ for( int y = 0; y < roads; y++){ int startY = Compute.randomInt(maxY/roads)+((y*maxY)/roads); //int start = Compute.randomInt(2); Coords coords = new Coords(-1,startY); int roadStyle = Compute.randomInt(2) + 1; int dir = Compute.randomInt(2) + NE; buildStraightRoad(coords, dir, roadStyle); startY = Compute.randomInt(maxY/roads)+((y*maxY)/roads); coords = new Coords(maxX,startY); dir = Compute.randomInt(2) + SW; buildStraightRoad(coords, dir, roadStyle); } for ( int x = 0; x < roads; x++){ int startX = Compute.randomInt(maxX/roads)+(x*(maxX/roads)); Coords coords = new Coords(startX,-1); int roadStyle = Compute.randomInt(2) + 1; buildStraightRoad(coords, S, roadStyle); } } private Vector buildTown(int maxX, int maxY, int roads, int size) { buildHubCity(maxX,maxY,roads * size / 100); return placeBuildings(Math.min(maxX,maxY) * size / 200); } private void buildHubCity(int maxX, int maxY,int roads){ int midX = maxX/2; int midY = maxY/2; Vector<Integer> directions = new Vector<Integer>(8); directions.add(N); directions.add(NE); directions.add(SE); directions.add(S); directions.add(SW); directions.add(NW); directions.add(E); directions.add(W); roads = Math.max(roads,4); cityPlan.add(new Coords(midX,midY)); int x=0; int y=0; for ( int dir = 0; dir < roads; dir++){ int baseDirection = -1; int roadStyle = Compute.randomInt(2) + 1; if(dir < 8) { x = midX; y = midY; baseDirection = directions.remove(Compute.randomInt(directions.size())); } else { switch(Compute.randomInt(4)) { case 1: x = Compute.randomInt(maxX); y = -1; baseDirection = S; break; case 2: x = Compute.randomInt(maxX); y = maxY; baseDirection = N; break; case 3: x = -1; y = Compute.randomInt(maxY); baseDirection = NE + Compute.randomInt(2); break; default: x = maxX; y = Compute.randomInt(maxY); baseDirection = SW + Compute.randomInt(2); break; } } Coords coords = new Coords(x,y); int nextDirection = baseDirection; while (coords.x >= -1 && coords.x <= maxX && coords.y >= -1 && coords.y <= maxY ){ int choice = Compute.randomInt(10); if(board.contains(coords)) { //don't change direction offboard if(choice < 4) { //keep going
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -