package Factory.GameLogic; import EnvironmentPluginAPI.TransportTypes.TMapMetaData; import Factory.GameLogic.Enums.Faction; import Factory.GameLogic.GameActors.*; import Factory.GameLogic.TransportTypes.TPosition; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * Created with IntelliJ IDEA. * User: TwiG * Date: 23.05.12 * Time: 11:08 * To change this template use File | Settings | File Templates. */ public class MapGenerator implements java.io.Serializable { // ------------------------------ FIELDS ------------------------------ private AbstractField[][] board; private TMapMetaData metaData; private List<Factory> factories; private Random randomGenerator; private int upperMirrorEdge; private int lowerMirrorEdge; private int topBorder; private int leftBorder; private int bottomBorder; private int rightBorder; private List<Factory> blueSideFactories; private List<Factory> redSideFactories; private Factory redStartFactory; private Factory blueStartFactory; private int factoryID = 0; private TPosition factoryDirection; private TPosition factoryMirrorDirection; // --------------------------- CONSTRUCTORS --------------------------- public MapGenerator(TMapMetaData metaData, List<Factory> factoryList) { this.metaData = metaData; this.factories = factoryList; randomGenerator = new Random(metaData.getSeed()); this.board = new AbstractField[metaData.getEdgeLength()][metaData.getEdgeLength()]; upperMirrorEdge = (metaData.getEdgeLength() / 2) - 1; lowerMirrorEdge = upperMirrorEdge + metaData.getEdgeLength() % 2; topBorder = 0; leftBorder = 0; bottomBorder = metaData.getEdgeLength() - 1; rightBorder = metaData.getEdgeLength() - 1; blueSideFactories = new ArrayList<Factory>(); redSideFactories = new ArrayList<Factory>(); } // -------------------------- OTHER METHODS -------------------------- public AbstractField[][] generateMap() { //1. initializing board board = new AbstractField[metaData.getEdgeLength()][metaData.getEdgeLength()]; for (int i = 0; i < metaData.getEdgeLength(); i++) { for (int j = 0; j < metaData.getEdgeLength(); j++) { board[i][j] = new NormalField(); } } //2. spawning Factories if (metaData.getSymmetry() == 0) { //horizontal Symmetry factoryDirection = new TPosition(1, 1); factoryMirrorDirection = new TPosition(1, -1); if (upperMirrorEdge == lowerMirrorEdge) { //horizontal symmetry wont spawn factories in the middle upperMirrorEdge -= 1; lowerMirrorEdge += 1; } //2.1. generate up to upperMirrorEdge //2.2. generate factory on Mirrored position for (int x = leftBorder; x <= rightBorder; x++) { for (int y = topBorder; y <= upperMirrorEdge; y++) { if (randomGenerator.nextInt(999) + 1 <= metaData.getFactoryNumberFactor()) { if (board[y][x] instanceof NormalField) { generateFactories(new TPosition(x, y)); } } } } } else { //TODO horizontal and vertical Symmetry } //3. Set Starting Factories and units if (blueSideFactories.isEmpty()) { blueStartFactory = spawnFactory(new TPosition(0, 0), 1, factoryDirection, blueSideFactories); redStartFactory = spawnFactory(new TPosition(leftBorder, bottomBorder), 1, factoryMirrorDirection, redSideFactories); } else { int theChosenOne = randomGenerator.nextInt(blueSideFactories.size()); blueStartFactory = blueSideFactories.get(theChosenOne); redStartFactory = redSideFactories.get(theChosenOne); } blueStartFactory.setController(Faction.BLUE); redStartFactory.setController(Faction.RED); blueStartFactory.totalInfluence=blueStartFactory.size; redStartFactory.totalInfluence=-blueStartFactory.size; blueStartFactory.spawn(); redStartFactory.spawn(); factories.addAll(blueSideFactories); factories.addAll(redSideFactories); return board; } private void generateFactories(TPosition position) { int xFactoryCheck = position.getX(); int yFactoryCheck = position.getY(); // 1. calculate Size int actualFactorySize; for (actualFactorySize = metaData.getMaximumFactorySize(); actualFactorySize > 1; actualFactorySize--) { if (randomGenerator.nextInt(99) + 1 <= metaData.getFactorySizeFactor()) { break; } } // 2. reduce Size if there is a factory in the way //checking only on static symmetric size; // Improvement : Make a method that checks in direction //checking if there is a factory in the way ; -1 because of the influenceEdge //if there is not a NormalField actualFactorySize will be lowered //actualFactorySize will then serve as a Sentinel finding the smaller size from the direction x and y int x = xFactoryCheck; int y = yFactoryCheck; for (int i = -1; i <= actualFactorySize; i++) { if (!(board[y][x] instanceof NormalField)) { actualFactorySize = i; } y = yFactoryCheck; for (int j = -1; j <= actualFactorySize; j++) { if (!(board[y][x] instanceof NormalField)) { actualFactorySize = j; } if (y == upperMirrorEdge) { actualFactorySize = j; } else { y += factoryDirection.getY(); } } if (x == rightBorder) { actualFactorySize = i; } else { x += factoryDirection.getX(); } } //3. spawning factories if they have a size if (actualFactorySize > 0) { spawnFactory(position, actualFactorySize, factoryDirection, blueSideFactories); spawnFactory(getHorizontalMirrorPosition(position), actualFactorySize, factoryMirrorDirection, redSideFactories); } } TPosition getHorizontalMirrorPosition(TPosition position) { int x = position.getX(); int y = position.getY(); return new TPosition(x, bottomBorder - y); } private Factory spawnFactory(TPosition position, int actualFactorySize, TPosition direction, List<Factory> factorySideList) { int factorySizeWithInfluenceFields = actualFactorySize + 2; int factoryX = position.getX(); int factoryY = position.getY(); List<InfluenceField> influenceFields = new ArrayList<InfluenceField>(); List<FactoryField> factoryFields = new ArrayList<FactoryField>(); //Iterate Size x Size times. factoryX and Y represent the position of the factory on the board //adding direction on in beforehand because of the influence edge //adding FactoryFields int x = factoryX; int y = factoryY; for (int i = 0; i < actualFactorySize; i++) { x += direction.getX(); y = factoryY; for (int j = 0; j < actualFactorySize; j++) { y += direction.getY(); FactoryField factoryField = new FactoryField(factoryID); board[y][x] = factoryField; factoryFields.add(factoryField); } } //adding InfluenceFields //this thing is not performance optimized. //Checks everything in factorySizeWithInfluenceFields and replace normal fields with influence fields x = factoryX; y = factoryY; for (int i = 0; i < factorySizeWithInfluenceFields; i++) { y = factoryY; for (int j = 0; j < factorySizeWithInfluenceFields; j++) { if (board[y][x] instanceof NormalField) { InfluenceField influenceField = new InfluenceField(factoryID); board[y][x] = influenceField; influenceFields.add(influenceField); } y += direction.getY(); } x += direction.getX(); } Factory factory = new Factory(actualFactorySize, factoryFields, influenceFields, factoryID); factorySideList.add(factory); factoryID++; return factory; } TPosition getDiagonalMirrorPosition(TPosition position) { int x = position.getX(); int y = position.getY(); return new TPosition(rightBorder - x, bottomBorder - y); } }