public TownGenerator(int width, int height, String name, int wiggle, double radius, double treeDensity, OverworldCell overworldCell, Quinoa quinoa) { header = new RegionHeader(name); region = new Region(width, height); header.setRegion(region); header.setName(NameMaker.makeTrivialPlaceName()); this.wiggle = wiggle; this.radius = radius; this.treeDensity = treeDensity; this.quinoa = quinoa; this.overworldCell = overworldCell; }
public RegionMap() { regions = new Dictionary<String, RegionHeader>(); currentRegionID = ""; overworldWidth = Quinoa.OVERWORLD_WIDTH; overworldHeight = Quinoa.OVERWORLD_HEIGHT; overworldCells = new OverworldCell[overworldWidth,overworldHeight]; for(int x=0; x < overworldWidth; x++) { for(int y=0; y < overworldHeight; y++) { overworldCells[x,y] = new OverworldCell(); } } }
/** * @param overworldCells the overworldCells to set */ public void setOverworldCells(OverworldCell[,] overworldCells) { this.overworldCells = overworldCells; }
public override void generate(Quinoa quinoa) { //Fill the overworld cell array int owWidth = quinoa.getMap().getOverworldWidth(); int owHeight = quinoa.getMap().getOverworldHeight(); OverworldCell[,] owc = quinoa.getMap().getOverworldCells(); for(int x=0; x < owWidth; x++) { for(int y=0; y < owHeight; y++) { owc[x,y] = new OverworldCell(); } } //choose a random spot to be town, set as cross int townX = owWidth / 2 + ((int)(RandomNumber.RandomDouble() * 3) - 1); int townY = owHeight / 2 + ((int)(RandomNumber.RandomDouble() * 3) - 1); owc[townX,townY].cellType = CellType.MAIN_TOWN; owc[townX,townY].nExit = true; owc[townX,townY].eExit = true; owc[townX,townY].sExit = true; owc[townX,townY].wExit = true; //generate paths recursively this.addPathBranch(townX-1, townY, owWidth, owHeight, owc, 0, 2, 7); this.addPathBranch(townX+1, townY, owWidth, owHeight, owc, 0, 2, 7); this.addPathBranch(townX, townY-1, owWidth, owHeight, owc, 0, 2, 7); this.addPathBranch(townX, townY+1, owWidth, owHeight, owc, 0, 2, 7); //generate regions for each overworld cell for(int x=0; x < owWidth; x++) { for(int y=0; y < owHeight; y++) { if(owc[x,y].cellType == CellType.MAIN_TOWN) { TownGenerator townGen = new TownGenerator(100, 100, "main", 3, 0.75, 0.01, owc[x,y], quinoa); townGen.generate(); owc[x,y].header = townGen.header; townGen.header.storeRegion(true); this.addCaveBranch(townGen.header, 14, 14, 3 + (int)(RandomNumber.RandomDouble() * 3), quinoa); quinoa.getMap().addRegionHeader(owc[x,y].header); } else if(owc[x,y].cellType == CellType.TOWN) { TownGenerator townGen = new TownGenerator(100, 100, "town" + RandomNumber.RandomUUID().ToString(), 3, 0.75, 0.01, owc[x,y], quinoa); townGen.generate(); owc[x,y].header = townGen.header; townGen.header.storeRegion(true); quinoa.getMap().addRegionHeader(owc[x,y].header); } else if(owc[x,y].cellType == CellType.FOREST) { String forestName = "forest" + RandomNumber.RandomUUID().ToString(); int depthCount = 0; int depthTotal = 0; if(owc[x,y].nExit) { depthCount++; depthTotal = depthTotal + owc[x,y-1].depth; } if(owc[x,y].eExit) { depthCount++; depthTotal = depthTotal + owc[x + 1,y].depth; } if(owc[x,y].sExit) { depthCount++; depthTotal = depthTotal + owc[x,y+1].depth; } if(owc[x,y].wExit) { depthCount++; depthTotal = depthTotal + owc[x-1,y].depth; } depthTotal = depthTotal + owc[x,y].depth; depthCount = depthCount + 1; double treeDensity = 0.01 + ((depthTotal / depthCount) * 0.02); if(treeDensity > 0.55) { treeDensity = 0.55; } ForestGenerator forGen = new ForestGenerator(100, 100, forestName, treeDensity, quinoa); double waterDensity = 0.15 + (RandomNumber.RandomDouble() * 0.35); if(waterDensity > 0.65) { waterDensity = 0.65; } forGen.addWater(waterDensity, 4); forGen.generate(owc[x,y].nExit, owc[x,y].eExit, owc[x,y].sExit, owc[x,y].wExit); forGen.addSprings(); forGen.header.setName("Forest"); owc[x,y].header = forGen.header; //add cave branches if only one exit is present int exitCount = 0; if(owc[x,y].nExit) {exitCount++;} if(owc[x,y].eExit) {exitCount++;} if(owc[x,y].sExit) {exitCount++;} if(owc[x,y].wExit) {exitCount++;} if(exitCount == 1 && RandomNumber.RandomDouble() < 0.50) { this.addCaveBranch(owc[x,y].header, owc[x,y].header.getRegion().getWidth() / 2, owc[x,y].header.getRegion().getHeight() / 2, 2 + (int)(RandomNumber.RandomDouble() * (depthTotal / depthCount)), quinoa); } forGen.header.storeRegion(true); quinoa.getMap().addRegionHeader(owc[x,y].header); } } } //connect exits for(int x=0; x < owWidth; x++) { for(int y=0; y < owHeight; y++) { if(owc[x,y].header != null) { if(owc[x,y].nExit && y > 0) { this.connectExits(owc[x,y], owc[x,y-1], Direction.N); } if(owc[x,y].sExit && y < owHeight-1) { this.connectExits(owc[x,y], owc[x,y+1], Direction.S); } if(owc[x,y].eExit && x < owWidth-1) { this.connectExits(owc[x,y], owc[x+1,y], Direction.E); } if(owc[x,y].wExit && x > 0) { this.connectExits(owc[x,y], owc[x-1,y], Direction.W); } } } } //place the brother this.placeBrother(quinoa); this.initializePlayer(quinoa); }
public void connectExits(OverworldCell owc1, OverworldCell owc2, Direction exitDirection) { int exitX = 0; int exitY = 0; int dX = 0; int dY = 0; owc1.header.recallRegion(); owc2.header.recallRegion(); switch(exitDirection) { case Direction.N: exitX = (int)(owc1.header.getRegion().getWidth() / 2); exitY = 0; dX = (int)(owc2.header.getRegion().getWidth() / 2); dY = owc2.header.getRegion().getHeight() - 2; owc1.header.getExits().Add(new RegionExit(exitX, exitY,dX,dY,owc2.header.getId(), ExitDecorator.NONE)); break; case Direction.E: exitX = owc1.header.getRegion().getWidth() - 1; exitY = (owc1.header.getRegion().getHeight() / 2); dX = 1; dY = (owc2.header.getRegion().getHeight() / 2); owc1.header.getExits().Add(new RegionExit(exitX, exitY,dX,dY,owc2.header.getId(), ExitDecorator.NONE)); break; case Direction.S: exitX = (int)(owc1.header.getRegion().getWidth() / 2); exitY = owc1.header.getRegion().getHeight() - 1; dX = (int)(owc2.header.getRegion().getWidth() / 2); dY = 1; owc1.header.getExits().Add(new RegionExit(exitX, exitY,dX,dY,owc2.header.getId(), ExitDecorator.NONE)); break; case Direction.W: exitX = 0; exitY = (owc1.header.getRegion().getHeight() / 2); dX = owc2.header.getRegion().getWidth() - 2; dY = (owc2.header.getRegion().getHeight() / 2); owc1.header.getExits().Add(new RegionExit(exitX, exitY,dX,dY,owc2.header.getId(), ExitDecorator.NONE)); break; } owc1.header.storeRegion(true); owc2.header.storeRegion(true); }
public void addPathBranch(int x, int y, int width, int height, OverworldCell[,] owc, int depth, int branchCountdown, int townCounter) { int townCountdown = townCounter; if(owc[x,y].cellType != CellType.NULL) { return; } else { //figure out vital connections owc[x,y].cellType = CellType.FOREST; owc[x,y].depth = depth; if(y > 0 && owc[x,y-1].sExit) { owc[x,y].nExit = true; } if(y < height-1 && owc[x,y+1].nExit) { owc[x,y].sExit = true; } if(x > 0 && owc[x-1,y].eExit) { owc[x,y].wExit = true; } if(x < width-1 && owc[x+1,y].wExit) { owc[x,y].eExit = true; } //randomly try different directions //try to lower amount of branching by only allowing up to two exit follows int exitCount = 0; if(owc[x,y].nExit) { exitCount++; } if(owc[x,y].eExit) { exitCount++; } if(owc[x,y].sExit) { exitCount++; } if(owc[x,y].wExit) { exitCount++; } if(townCountdown == 0) { owc[x,y].cellType = CellType.TOWN; townCountdown = 6 + (int)(RandomNumber.RandomDouble() * 3); } branchCountdown = branchCountdown - 1; int branchMax = 2 + (int)(RandomNumber.RandomDouble() * 4); if(branchCountdown > 0) { if(owc[x,y].nExit && y < height - 1) { owc[x,y].sExit = true; owc[x,y+1].nExit = true; this.addPathBranch(x, y+1, width, height, owc, depth + 1, branchCountdown - 1, townCountdown - 1); } else if(owc[x,y].sExit && y > 0) { owc[x,y].nExit = true; owc[x,y-1].sExit = true; this.addPathBranch(x, y-1, width, height, owc, depth + 1, branchCountdown - 1, townCountdown - 1); } if(owc[x,y].eExit && x > 0) { owc[x,y].wExit = true; owc[x-1,y].eExit = true; this.addPathBranch(x-1, y, width, height, owc, depth + 1, branchCountdown - 1, townCountdown - 1); } else if(owc[x,y].wExit && x < width - 1) { owc[x,y].eExit = true; owc[x+1,y].wExit = true; this.addPathBranch(x+1, y, width, height, owc, depth + 1, branchCountdown - 1, townCountdown - 1); } } else { //branch off in any direction int exitCutoff = 2; double branchChance = 0.35; if(exitCount < exitCutoff && y > 0 && owc[x,y].nExit == false && RandomNumber.RandomDouble() < branchChance) { owc[x,y].nExit = true; owc[x,y-1].sExit = true; this.addPathBranch(x, y-1, width, height, owc, depth + 1, branchMax, townCountdown - 1); } if(exitCount < exitCutoff && y < height-1 && owc[x,y].sExit == false && RandomNumber.RandomDouble() < branchChance) { owc[x,y].sExit = true; owc[x,y+1].nExit = true; this.addPathBranch(x, y+1, width, height, owc, depth + 1, branchMax, townCountdown - 1); } if(exitCount < exitCutoff && x > 0 && owc[x,y].wExit == false && RandomNumber.RandomDouble() < branchChance) { owc[x,y].wExit = true; owc[x - 1,y].eExit = true; this.addPathBranch(x - 1, y, width, height, owc, depth + 1, branchMax, townCountdown - 1); } if(exitCount < exitCutoff && x < width-1 && owc[x,y].eExit == false && RandomNumber.RandomDouble() < branchChance) { owc[x,y].eExit = true; owc[x + 1,y].wExit = true; this.addPathBranch(x + 1, y, width, height, owc, depth + 1, branchMax, townCountdown - 1); } } } }