/// <summary> /// Selects the south-western voxel of the point selected by the mouse. /// The loc parameter and the ab parameter should point to the same location. /// </summary> private Location selectVoxel(MapViewWindow view, Location loc, Point ab) { // top-left corner of the selected location Point vxl = World.world.fromXYZToAB(loc); Point offset = new Point(ab.X - vxl.X, ab.Y - vxl.Y); if (offset.X < 8) { loc.x--; } else if (offset.X >= 24) { loc.y++; } else { MountainVoxel mv = MountainVoxel.get(loc); int h0 = (mv != null)?(int)mv.getHeight(Direction.NORTHEAST):0; int h2 = (mv != null)?(int)mv.getHeight(Direction.SOUTHWEST):0; if (offset.Y >= (16 - (h0 + h2) * 4) / 2) { loc.x--; loc.y++; } } return(loc); }
private int getHeight(Location loc, Direction d) { MountainVoxel mv = MountainVoxel.get(loc); if (mv != null) { return(mv.getHeight(d) + loc.z * 4); } else { return(loc.z * 4); } }
/// <param name="v">MountainVoxel to be replaced</param> public static TerraceVoxel create(MountainVoxel v) { // back up heights byte[] heights = new byte[4]; for (int i = 0; i < 4; i++) { heights[i] = (byte)v.getHeight(Direction.get(i * 2 + 1)); } World.world.remove(v); // raise the ground level by one World.world.raiseGround(v.location); return(new TerraceVoxel(v.location, heights)); }
/// <summary> /// /// </summary> /// <param name="here"></param> /// <param name="to"></param> public override void Build(Location here, Location to) { Debug.Assert(CanBeBuilt(here, to)); Direction d = here.getDirectionTo(to); while (true) { if (RailRoad.get(here) == null) { MountainVoxel mv = WorldDefinition.World[here] as MountainVoxel; if (mv != null) { // build a tunnel byte[] heights = new byte[4]; for (int i = 0; i < 4; i++) { heights[i] = (byte)mv.getHeight(Direction.get(i * 2 + 1)); } WorldDefinition.World.remove(here); // remove this mountain create(TrafficVoxel.getOrCreate(here), d, heights); } else { // build a normal tunnel new SingleRailRoad(TrafficVoxel.getOrCreate(here), RailPattern.get(d, d.opposite)); } } if (here == to) { return; } here = here.toward(to); } }
// clean it up by using MountainVoxel.isCornerMatched private bool canBeLowered(ref Location loc) { World world = World.world; if (!isFourAdjacentCornersMatched(loc)) { return(false); } MountainVoxel mvBase = MountainVoxel.get(loc); if (mvBase != null) { if (mvBase.getHeight(Direction.NORTHEAST) == 0) { return(false); // other corners need to be lowered first. } } else { int glevel = world.getGroundLevel(loc); if (glevel != loc.z && glevel != loc.z - 1) { return(false); } if (loc.z == 0) { return(false); // can't dig deeper } loc.z--; } // check other voxels for (int x = 0; x <= 1; x++) { for (int y = -1; y <= 0; y++) { Location l = new Location(loc.x + x, loc.y + y, loc.z); if (MountainVoxel.get(l) != null) { continue; // if it's mountain, OK. } // otherwise, make sure that nothing is on it. if (World.world[l.x, l.y, l.z + 1] != null) { return(false); } // and nothing is under it if (World.world[l.x, l.y, l.z] != null) { return(false); } } } if (World.world.isOutsideWorld(loc)) { return(false); } return(true); }