/// <summary> /// /// </summary> /// <param name="count"></param> /// <returns></returns> protected Location pickPlace(int count) { while (count-- > 0) { Location loc = target.baseLocation; WorldDefinition w = WorldDefinition.World; int amp = F_PopAmpBase + (int)(Math.Pow(w[loc].LandPrice, F_PopAmpPower) * F_PopAmpScale); // then randomly pick nearby voxel loc.x = Rand(loc.x, amp); loc.y = Rand(loc.y, amp); loc.z = w.GetGroundLevel(loc); if (w.IsOutsideWorld(loc)) { continue; } if (loc.z < w.WaterLevel) { continue; // below water } Voxel v = w[loc]; if (v != null) { if (!IsReplaceable(v.Entity, v.LandPrice)) { continue; } } return(loc); } return(Location.Unplaced); }
/// <summary> /// Creates a ULV of the specified surface. /// </summary> /// <param name="cube"> /// a surface specified as a cube. The height of the cube must be zero. /// </param> /// <returns> /// null if unable to to compute ULV or if any voxel in the cube is owned by /// the user. /// </returns> public static ULV create(Cube cube) { Debug.Assert(cube.SizeZ == 0); int mx = cube.x2; int my = cube.y2; int z = cube.z1; int landValue = 0, entityValue = 0; WorldDefinition world = WorldDefinition.World; Set s = new Set(); if (z < world.WaterLevel) { return(null); // underwater } for (int x = cube.x1; x < mx; x++) { for (int y = cube.y1; y < my; y++) { if (world.GetGroundLevel(x, y) != z) { return(null); // not on the ground } Voxel v = world[x, y, z]; if (v != null) { IEntity e = v.Entity; if (e.isOwned) // cannot reclaim this voxel. { return(null); } if (!s.Contains(e)) { // new entity s.Add(e); entityValue += e.EntityValue; } } landValue += world.LandValue[new Location(x, y, z)]; } } return(new ULV(landValue, entityValue)); }
/// <summary> /// Gets 4*height + mountain height. /// /// This method computes the height of the given location in fine scale. /// It returns -1 if the given location is out of the world. /// </summary> public static int getTotalHeight(Location loc, Direction d) { WorldDefinition w = WorldDefinition.World; if (w.IsOutsideWorld(loc)) { return(-1); } int z = w.GetGroundLevel(loc); MountainVoxel mv = MountainVoxel.get(new Location(loc.x, loc.y, z)); if (mv == null) { return(z * 4); } else { return(z * 4 + mv.getHeight(d)); } }
private void drawGround(DrawContext display, Point pt, int heightCutDiff) { Point basePt = pt; WorldDefinition world = WorldDefinition.World; if (heightCutDiff == 0) { ResourceUtil.EmptyChip.DrawShape(display.Surface, pt, isUnderWater ? waterColors[3] : currentMountainColors[3]); return; } if (isFlattened) { if (ground != null) { ground.Draw(display.Surface, pt); } return; } pt.Y -= getHeight(0) * 4; // apply offset // compute target colors Color[] dstColors = new Color[] { selectColor(), mapColor(isUnderWater ? Color.Navy : currentMountainColors[0]) }; int tdiff = (getHeight(0) - getHeight(2) + 4); int umax = Math.Min(tdiff + 2, 6); Size sz = new Size(16, tdiff * 4 + 2 * 4 + 1); // draw left half int ldiff = (getHeight(0) - getHeight(3) + 2); bool vflip; if (ldiff < tdiff - ldiff) { vflip = true; ldiff = tdiff - ldiff; } else { vflip = false; } int lidx = (umax - ldiff); Rectangle src = new Rectangle(lidx * 32, 0, sz.Width, sz.Height); Rectangle dst = new Rectangle(pt.X, pt.Y - (2 * 4), sz.Width, sz.Height); if (vflip) { //flippedImages[tdiff].clipVflip(ref dst, ref src); display.Surface.Blit(dst.Location, flippedImages[tdiff], src.Location, src.Size); } else { flippedImages[tdiff].ResetClipRect(); //flippedImages[tdiff].clipRectangle(ref dst, ref src); display.Surface.Blit(new Point(pt.X, pt.Y), images[tdiff], src.Location, src.Size); } { // left cliff Location neighbor = Location + Direction.WEST; if (!(world[neighbor] is MountainVoxel) && getHeight(2) + getHeight(3) > 0 && world.GetGroundLevel(neighbor) <= world.GetGroundLevel(Location)) { cliff[0, getHeight(3), getHeight(2)].Draw(display.Surface, basePt); } } // right half int rdiff = (getHeight(0) - getHeight(1) + 2); if (rdiff < tdiff - rdiff) { vflip = true; rdiff = tdiff - rdiff; } else { vflip = false; } int ridx = (umax - rdiff); pt.X += 16; src = new Rectangle(ridx * 32 + 16, 0, sz.Width, sz.Height); dst = new Rectangle(pt.X, pt.Y - (2 * 4), sz.Width, sz.Height); if (vflip) { ////flippedImages[tdiff].clipVflip(ref dst, ref src); display.Surface.Blit(dst.Location, flippedImages[tdiff], src.Location, src.Size); } else { flippedImages[tdiff].ResetClipRect(); //flippedImages[tdiff].clipRectangle(ref dst, ref src); display.Surface.Blit(new Point(pt.X, pt.Y), images[tdiff], src.Location, src.Size); } { basePt.X += 16; // right cliff Location neighbor = Location + Direction.SOUTH; if (!(world[neighbor] is MountainVoxel) && getHeight(2) + getHeight(1) > 0 && world.GetGroundLevel(neighbor) <= world.GetGroundLevel(Location)) { cliff[1, getHeight(2), getHeight(1)].Draw(display.Surface, basePt); } } }
// clean it up by using MountainVoxel.isCornerMatched private bool canBeLowered(ref Location loc) { WorldDefinition world = WorldDefinition.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 (WorldDefinition.World[l.x, l.y, l.z + 1] != null) { return(false); } // and nothing is under it if (WorldDefinition.World[l.x, l.y, l.z] != null) { return(false); } } } if (WorldDefinition.World.IsOutsideWorld(loc)) { return(false); } return(true); }
// clean it up by using MountainVoxel.isCornerMatched /// <summary> /// Return true iff the north-eastern corner of the given location /// can be raised by a quarter height unit. /// </summary> private bool canBeRaised(Location loc) { WorldDefinition w = WorldDefinition.World; if (!isFourAdjacentCornersMatched(loc)) { return(false); } Voxel baseVoxel = w[loc]; int glevel = w.GetGroundLevel(loc); if (loc.z != glevel) { return(false); //mountain can be placed only at the ground level } // true if this ground level is too close to the roof. bool nearRoof = (glevel == WorldDefinition.World.Size.z - 1); 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 if (w.IsOutsideWorld(l)) { continue; // it's OK if it's beyond the border } Voxel v = w[l]; if (glevel != w.GetGroundLevel(l)) { return(false); // different ground level } if (v == null) { continue; // this voxel is unoccupied. } if (v is MountainVoxel) { int h = ((MountainVoxel)v).getHeight(d); if (h == 4) { return(false); // corner saturated. } if (nearRoof && h == 3) { return(false); // too close to the roof } continue; // otherwise OK } return(false); // occupied for another purpose } } if (WorldDefinition.World.IsOutsideWorld(loc)) { return(false); } return(true); }