/// <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);
 }
Example #2
0
        /// <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));
        }
Example #3
0
        /// <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));
            }
        }
Example #4
0
        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);
                }
            }
        }
Example #5
0
        // 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);
        }
Example #6
0
        // 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);
        }