/// <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); }
/// <summary> /// Gets the land that should be used to fill (x,y) within [x1,y1]-[x2,y2] (inclusive). /// </summary> public override void create(int x1, int y1, int x2, int y2, int z, bool owned) { for (int x = x1; x <= x2; x++) { for (int y = y1; y <= y2; y++) { Location loc = new Location(x, y, z); if (canBeBuilt(loc, ControlMode.player)) { byte[] patterns = createRandomTrees(); if (patterns.Length != 0) { MountainVoxel v; if (World.world[loc] is MountainVoxel) { v = (MountainVoxel)World.world[loc]; } else { v = new MountainVoxel(loc, 0, 0, 0, 0); } v.setTrees(ground, sprites, patterns, price); v.isOwned = owned; World.world.onVoxelUpdated(loc); } } } } }
public void onClick(MapViewWindow view, Location loc, Point ab) { MountainVoxel mv = World.world[loc] as MountainVoxel; if (mv == null) { MainWindow.showError("Can only be placed on mountainsides"); //! MainWindow.showError("山肌しか工事できません"); return; } int h = World.world.getGroundLevel(loc); for (int i = 0; i < 4; i++) { if (World.world.getGroundLevel(loc + Direction.get(i * 2)) > h) { MainWindow.showError("This location is inappropriate"); //! MainWindow.showError("設置位置が不適切です"); return; } } World.world.remove(mv); }
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); } }
public void onClick(MapViewWindow view, Location loc, Point ab) { MountainVoxel mv = World.world[loc] as MountainVoxel; if (mv == null) { MainWindow.showError("Can only be placed on mountainsides"); //! MainWindow.showError("山肌にしか設置できません"); return; } TerraceVoxel.create(mv); }
/// <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> /// Raises the north-eastern corner of the specified voxel /// </summary> /// <returns>false if the operation was unsuccessful.</returns> private bool raise(Location loc) { World w = World.world; // make sure that four surrounding voxels can be raised, // and the ground levels of them are the same if (!canBeRaised(loc)) { return(false); } // then actually change the terrain 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); Voxel vx = w[l]; if (vx is World.OutOfWorldVoxel) { continue; // this is beyond the border } MountainVoxel v = vx as MountainVoxel; Direction d = Direction.get(1 - x * 2, -y * 2 - 1); // corner to modify if (v == null) { v = new MountainVoxel(l, 0, 0, 0, 0); } // raise the corner v.setHeight(d, v.getHeight(d) + 1); if (v.isSaturated) { // if the voxel is saturated, raise the ground level w.raiseGround(l); w.remove(l); // remove this voxel } } } return(true); }
/// <summary> /// Checks the height agreement of the four corners adjacent to /// the north-eastern corner of the given location. /// </summary> /// <param name="loc"></param> /// <returns></returns> private bool isFourAdjacentCornersMatched(Location loc) { Direction d = Direction.NORTH; for (int i = 0; i < 4; i++) { if (!MountainVoxel.isCornerMatched(loc, d.left)) { return(false); } loc += d; d = d.right90; } return(true); }
/// <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); } }
public static void bulldoze(Location loc1, Location loc2) { int z = loc1.z; for (int x = loc1.x; x <= loc2.x; x++) { for (int y = loc1.y; y <= loc2.y; y++) { // edited by 477 (04/02/14) //if( World.world.isReusable(x,y,z) && World.world[x,y,z]!=null ) Voxel v = World.world[x, y, z]; if (v != null) { if (v is MountainVoxel) { MountainVoxel mv = v as MountainVoxel; if (mv.isFlattened) { World.world.remove(x, y, z); } else { mv.removeTrees(); } } else if (v.entity != null) { v.entity.remove(); } else { World.world.remove(x, y, z); } } } } }
/// <summary> /// Lowers the north-eastern corner of the specified voxel. /// </summary> /// <returns>false if the operation was unsuccessful.</returns> private bool lower(Location loc) { World world = World.world; if (!canBeLowered(ref loc)) { return(false); } // then actually change the terrain 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); Direction d = Direction.get(1 - x * 2, -y * 2 - 1); // corner to modify MountainVoxel mv = MountainVoxel.get(l); if (mv == null) { World.world.lowerGround(l); mv = new MountainVoxel(l, 4, 4, 4, 4); } mv.setHeight(d, mv.getHeight(d) - 1); if (mv.isFlattened) // completely flattened { world.remove(mv); } } } return(true); }
// 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); }