internal bool addBud(short x, short y, int level, Direction dir, int sleep) { // ignore if the road is already exist. PointS at = PointS.pointFrom(x, y, dir, 1); if (!world.isInWorld(at.x, at.y)) { return(false); } Voxel toward = world[at.x, at.y]; if (toward.road != null && toward.road.getLevel(dir) <= level) { return(false); } vector key = new vector(x, y, dir); if (buds.ContainsKey(key)) { return(false); } RoadBud bud = new RoadBud(level, sleep); buds.Add(key, bud); Debug.WriteLine("new bud at:(" + x + "," + y + ") to " + dir); return(true); }
protected void extendRoad(RoadBud bud, PointS p, int length, Direction dir) { if (length < 0 || !world.isInWorld(p.x, p.y)) { return; } switch (dir) { case Direction.EAST: buildRoadE(bud.level, p.x, p.y, (short)length, bud); break; case Direction.WEST: buildRoadW(bud.level, p.x, p.y, (short)length, bud); break; case Direction.NORTH: buildRoadN(bud.level, p.x, p.y, (short)length, bud); break; case Direction.SOUTH: buildRoadS(bud.level, p.x, p.y, (short)length, bud); break; default: Debug.Assert(false); break; } }
protected void buildRoadW(int level, short x, short y, int length, RoadBud bud) { if (world[x, y].canBuildRoad) { if (bud == null) { addBud(x, y, level, Direction.EAST); } // west bound check int x2 = x - length; if (x2 <= 0) { length = x; if (length <= 0) { return; } x2 = 0; } // set road world[x, y].buildRoad(level, Direction.WEST, Direction.WEST); int ix; for (ix = 0; ix < length; ix++) { Voxel v = world[x - ix, y]; if (!v.canBuildRoad) { break; } v.buildRoad(level, Direction.WEST, Direction.EAST); } if (ix == length) { world[x2, y].buildRoad(level, Direction.EAST, Direction.EAST); if (bud == null) { addBud((short)x2, y, level, Direction.WEST); } else { addBud(bud, (short)x2, y, Direction.WEST); } } if (modH[level] == -1) { modH[level] = (short)(y % max_length[level]); } world.onVoxelUpdated(new Rectangle(x2, y, length, 1)); } }
protected void buildRoadS(int level, short x, short y, int length, RoadBud bud) { if (world[x, y].canBuildRoad) { if (bud == null) { addBud(x, y, level, Direction.NORTH); } // south bound check int y2 = y + length; if (y2 >= world.yWidth) { length = world.yWidth - y - 1; if (length <= 0) { return; } y2 = world.yWidth - 1; } // set road world[x, y].buildRoad(level, Direction.SOUTH, Direction.SOUTH); int iy; for (iy = 0; iy < length; iy++) { Voxel v = world[x, y + iy]; if (!v.canBuildRoad) { break; } v.buildRoad(level, Direction.NORTH, Direction.SOUTH); } if (iy == length) { world[x, y2].buildRoad(level, Direction.NORTH, Direction.NORTH); if (bud == null) { addBud(x, (short)y2, level, Direction.SOUTH); } else { addBud(bud, x, (short)y2, Direction.SOUTH); } } if (modV[level] == -1) { modV[level] = (short)(x % max_length[level]); } world.onVoxelUpdated(new Rectangle(x, y, 1, length)); } }
// retruns true if no road is extended. protected bool extend(vector key) { RoadBud bud = (RoadBud)buds[key]; if (bud == null) { return(false); } // remove if the road is already exist. PointS at = PointS.pointFrom(key.x, key.y, key.dir, 1); Voxel toward = world[at.x, at.y]; if (toward.road != null && toward.road.getLevel(key.dir) <= bud.level) { removeBud(key); return(true); } // sleep check bool f = bud.sleeping; if (f) { Debug.Write("."); bud.stepSleep(); } else { removeBud(key); int length = min_length[bud.level]; PointS p = adjustPoint(bud.level, key.x, key.y, length, key.dir); if (p == null || p.IsEmpty) { return(true); } extendRoad(bud, p, length, key.dir); if (bud.level < Configure.noTrunkLevel) { makeBranch(bud, p, length, key.dir); } Debug.WriteLine("extends from (" + p.x + "," + p.y + ") to " + key.dir + " by " + length + " voxels."); } return(f); }
internal bool addBud(RoadBud bud, short x, short y, Direction dir) { PointS at = PointS.pointFrom(x, y, dir, 1); if (!world.isInWorld(at.x, at.y)) { return(false); } Voxel toward = world[at.x, at.y]; if (toward.road != null && toward.road.getLevel(dir) <= bud.level) { return(false); } vector key = new vector(x, y, dir); if (buds.ContainsKey(key)) { buds.Remove(key); } buds.Add(key, bud); Debug.WriteLine("new bud at:(" + x + "," + y + ") to " + dir); return(true); }
protected int[] getLastBranches(RoadBud bud, PointS p, Direction dir) { if (!bud.sprouted || bud.lastBranch == null) { short w = min_length[0]; int n = w * 2; Direction r = DirConvertor.reverse(dir); int[] b0 = getNearestBranches(p, r, n); int[] bR = getNearestBranches(PointS.pointFrom(p, DirConvertor.rotR(dir), w), r, n); int[] bL = getNearestBranches(PointS.pointFrom(p, DirConvertor.rotL(dir), w), r, n); if (dir == Direction.WEST || dir == Direction.NORTH) { for (int i = 0; i < b0.Length; i++) { if (bR[i] > b0[i]) { b0[i] = bR[i]; } if (bL[i] > b0[i]) { b0[i] = bL[i]; } } } else { for (int i = 0; i < b0.Length; i++) { if (bR[i] > 0 && bR[i] < b0[i]) { b0[i] = bR[i]; } if (bL[i] > 0 && bL[i] < b0[i]) { b0[i] = bL[i]; } } } bud.lastBranch = b0; bud.sprouted = true; } // high level branch is substitutable for lower one int v; if (dir == Direction.WEST || dir == Direction.NORTH) { v = -1; } else { v = 1; } for (int i = 1; i <= Configure.RoadLevelMax; i++) { if (bud.lastBranch[i - 1] != -1) { if (bud.lastBranch[i] == -1) { bud.lastBranch[i] = bud.lastBranch[i - 1]; } else if ((bud.lastBranch[i - 1] - bud.lastBranch[i]) * v > 0) { bud.lastBranch[i] = bud.lastBranch[i - 1]; } } } return(bud.lastBranch); }
protected void makeBranch(RoadBud bud, PointS p, int length, Direction dir) { int[] b = getLastBranches(bud, p, dir); int d_min = min_length[Configure.RoadLevelMax]; // prepare arguments int start; if (dir == Direction.SOUTH || dir == Direction.NORTH) { start = p.y; } else { start = p.x; } int last = Math.Abs(b[Configure.RoadLevelMax] - start); int n = length / d_min + 1; // points proposed for branch short[] grid = new short[n]; // set first point grid[0] = (short)world.randEx(0, 2); if (last < d_min) { grid[0] += (short)d_min; } // set followed points for (int i = 1; i < n; i++) { grid[i] = (short)(grid[i - 1] + d_min + world.randEx(0, 2)); } // sleep count of the bud int[] counter = new int[n]; for (int lv = bud.level; lv <= Configure.RoadLevelMax; lv++) { for (int i = 0; i < n; i++) { counter[i] = -1; } last = Math.Abs(b[lv] - start); makeBranch2(lv, length, last, ref grid, ref counter); for (int i = 0; i < n; i++) { if (counter[i] > -1) { PointS p2 = PointS.pointFrom(p, dir, grid[i]); addBud(p2.x, p2.y, lv, DirConvertor.rotL(dir), counter[i]); addBud(p2.x, p2.y, lv, DirConvertor.rotR(dir), counter[i]); if (dir == Direction.EAST || dir == Direction.WEST) { bud.lastBranch[lv] = p2.x; } else { bud.lastBranch[lv] = p2.y; } } } } }