예제 #1
0
        public ConstructJob(IJobObserver parent, ConstructMode mode, IItemObject[] items, IEnvironmentObject environment, IntPoint3 location)
            : base(parent)
        {
            m_mode = mode;
            m_items = items;
            m_environment = environment;
            m_location = location;

            m_state = 0;

            DirectionSet positioning;

            switch (mode)
            {
                case ConstructMode.Floor:
                    positioning = DirectionSet.Planar;
                    break;

                case ConstructMode.Pavement:
                    positioning = DirectionSet.Exact;
                    break;

                case ConstructMode.Wall:
                    positioning = DirectionSet.Planar;
                    break;

                default:
                    throw new Exception();
            }

            AddSubJob(new FetchItems(this, m_environment, m_location, items, positioning));
        }
예제 #2
0
        bool CanWaterFlow(IntPoint3 from, IntPoint3 to)
        {
            if (!m_env.Contains(to))
                return false;

            IntVector3 v = to - from;

            Debug.Assert(v.IsNormal);

            var dstTerrain = m_env.GetTerrain(to);
            var dstInter = m_env.GetInterior(to);

            if (dstTerrain.IsBlocker || dstInter.IsBlocker)
                return false;

            if (v.Z == 0)
                return true;

            Direction dir = v.ToDirection();

            if (dir == Direction.Up)
                return dstTerrain.IsPermeable == true;

            var srcTerrain = m_env.GetTerrain(from);

            if (dir == Direction.Down)
                return srcTerrain.IsPermeable == true;

            throw new Exception();
        }
예제 #3
0
        public override LivingObject[] SetupWorldForNewPlayer(Player player)
        {
            const int NUM_DWARVES = 1;

            // XXX entry location
            var env = this.World.AllObjects.OfType<Dwarrowdelf.Server.EnvironmentObject>().First();

            var list = new List<LivingObject>();

            for (int i = 0; i < NUM_DWARVES; ++i)
            {
                IntPoint3 p;
                do
                {
                    p = new IntPoint3(m_random.Next(env.Width), m_random.Next(env.Height), env.HomeLocation.Z);
                } while (!EnvironmentHelpers.CanEnter(env, p));

                var l = CreateDwarf(i);

                if (!l.MoveTo(env, p))
                    throw new Exception();

                list.Add(l);
            }

            return list.ToArray();
        }
예제 #4
0
        /* Parallel */
        /// <summary>
        /// Returns if dst can be reached from src
        /// </summary>
        public static bool CanReach(IAStarEnvironment environment, IntPoint3 src, IntPoint3 dst, DirectionSet dstPositioning)
        {
            Debug.Assert(environment != null);

            // Do pathfinding to both directions simultaneously to detect faster if the destination is blocked
            CancellationTokenSource cts = new CancellationTokenSource();

            AStarResult resBackward = null;
            AStarResult resForward = null;

            var taskForward = new Task(delegate
            {
                resForward = Find(environment, src, DirectionSet.Exact, dst, dstPositioning, 200000, cts.Token);
            });
            taskForward.Start();

            var taskBackward = new Task(delegate
            {
                resBackward = Find(environment, dst, dstPositioning, src, DirectionSet.Exact, 200000, cts.Token);
            });
            taskBackward.Start();

            Task.WaitAny(taskBackward, taskForward);

            cts.Cancel();

            Task.WaitAll(taskBackward, taskForward);

            if (resForward.Status == AStarStatus.Found || resBackward.Status == AStarStatus.Found)
                return true;
            else
                return false;
        }
예제 #5
0
        public void MoveTo(ContainerObject dst, IntPoint3 dstLoc)
        {
            var src = this.Parent;
            var srcLoc = this.Location;

            if (src != dst)
            {
                if (src != null)
                    src.RemoveChild(this);

                this.Parent = dst;
            }

            if (srcLoc != dstLoc)
            {
                this.Location = dstLoc;
                if (dst != null && src == dst)
                    dst.MoveChild(this, srcLoc, dstLoc);
            }

            if (src != dst)
            {
                if (dst != null)
                    dst.AddChild(this);
            }

            if (src != dst || srcLoc != dstLoc)
                if (ObjectMoved != null)
                    ObjectMoved(this, this.Parent, this.Location);
        }
 public MapSelection(IntPoint3 start, IntPoint3 end)
     : this()
 {
     this.SelectionStart = start;
     this.SelectionEnd = end;
     this.IsSelectionValid = true;
 }
예제 #7
0
 public ItemObject ContainsPoint(IntPoint3 p)
 {
     var data = m_jobDataList.Where(d => d.Mode == InstallMode.Install && d.Location == p).FirstOrDefault();
     if (data == null)
         return null;
     return data.Item;
 }
예제 #8
0
        public override bool Sees(IntPoint3 p)
        {
            if (!m_environment.Contains(p))
                return false;

            return GetVisible(p);
        }
예제 #9
0
 protected MoveBaseAssignment(IJobObserver parent, IEnvironmentObject environment, IntPoint3 location)
     : base(parent)
 {
     this.Environment = environment;
     this.Location = location;
     m_state = 0;
 }
예제 #10
0
        bool GetVisible(IntPoint3 p)
        {
            if (m_visibilityArray == null)
                return false;

            return m_visibilityArray[p.Z, p.Y, p.X];
        }
예제 #11
0
        public void InitializeWorld(World world)
        {
            CreateTerrain();

            IntPoint3? stairs = null;

            foreach (var p2 in m_terrainData.Size.Plane.Range())
            {
                var z = m_terrainData.GetHeight(p2);

                var p = new IntPoint3(p2, z);
                var td = m_terrainData.GetTileData(p);
                if (td.TerrainID == TerrainID.StairsDown)
                {
                    stairs = p;
                    break;
                }
            }

            if (stairs.HasValue == false)
                throw new Exception();

            m_env = EnvironmentObject.Create(world, m_terrainData, VisibilityMode.LivingLOS, stairs.Value);

            CreateMonsters();

            CreateDebugMonsterAtEntry();
        }
예제 #12
0
        static DirectionSet GetPossiblePositioning(IEnvironmentObject env, IntPoint3 p, MineActionType mineActionType)
        {
            DirectionSet pos;

            var down = p + Direction.Down;

            switch (mineActionType)
            {
                case MineActionType.Mine:
                    pos = DirectionSet.Planar;

                    if (EnvironmentHelpers.CanMoveFrom(env, down, Direction.Up))
                        pos |= DirectionSet.Down;

                    break;

                case MineActionType.Stairs:
                    pos = DirectionSet.Planar | DirectionSet.Up;

                    if (EnvironmentHelpers.CanMoveFrom(env, down, Direction.Up))
                        pos |= DirectionSet.Down;

                    break;

                case MineActionType.Channel:
                    pos = DirectionSet.Planar;
                    break;

                default:
                    throw new Exception();
            }

            return pos;
        }
예제 #13
0
 public MineAssignment(IJobObserver parent, IEnvironmentObject environment, IntPoint3 location, MineActionType mineActionType)
     : base(parent)
 {
     m_environment = environment;
     m_location = location;
     m_mineActionType = mineActionType;
 }
예제 #14
0
        public override LivingObject[] SetupWorldForNewPlayer(Player player)
        {
            const int NUM_DWARVES = 1;

            // XXX entry location
            var env = this.World.AllObjects.OfType <Dwarrowdelf.Server.EnvironmentObject>().First();

            var list = new List <LivingObject>();

            for (int i = 0; i < NUM_DWARVES; ++i)
            {
                IntPoint3 p;
                do
                {
                    p = new IntPoint3(m_random.Next(env.Width), m_random.Next(env.Height), env.HomeLocation.Z);
                } while (!EnvironmentHelpers.CanEnter(env, p));

                var l = CreateDwarf(i);

                if (!l.MoveTo(env, p))
                {
                    throw new Exception();
                }

                list.Add(l);
            }

            return(list.ToArray());
        }
예제 #15
0
        public static void CreateGrass(TerrainData terrain, Random random, int grassLimit)
        {
            var grid = terrain.TileGrid;
            var heightMap = terrain.HeightMap;

            int w = terrain.Width;
            int h = terrain.Height;

            var materials = Materials.GetMaterials(MaterialCategory.Grass).ToArray();
            for (int y = 0; y < h; ++y)
            {
                for (int x = 0; x < w; ++x)
                {
                    int z = heightMap[y, x];

                    var p = new IntPoint3(x, y, z);

                    if (z < grassLimit)
                    {
                        var td = grid[p.Z, p.Y, p.X];

                        if (Materials.GetMaterial(td.TerrainMaterialID).Category == MaterialCategory.Soil &&
                            (td.TerrainID.IsFloor() || td.TerrainID.IsSlope()))
                        {
                            td.InteriorID = InteriorID.Grass;
                            td.InteriorMaterialID = materials[random.Next(materials.Length)].ID;

                            grid[p.Z, p.Y, p.X] = td;
                        }
                    }
                }
            }
        }
예제 #16
0
 public ConstructAssignment(IJobObserver parent, ConstructMode mode, IEnvironmentObject environment, IntPoint3 location, IItemObject[] items)
     : base(parent)
 {
     m_mode = mode;
     m_environment = environment;
     m_location = location;
     m_items = items;
 }
예제 #17
0
        public IEnumerable<ItemObject> GetItemsByDistance(IntPoint3 location, Func<ItemObject, bool> filter)
        {
            var items = m_items
                .Where(filter)
                .OrderBy(i => (i.Location - location).ManhattanLength);

            return items;
        }
예제 #18
0
 public MoveConstructAssignment(IJobObserver parent, ConstructMode mode, IItemObject[] items, IEnvironmentObject environment, IntPoint3 location)
     : base(parent, environment, items[0].Location)
 {
     m_mode = mode;
     m_items = items;
     m_environment = environment;
     m_location = location;
 }
예제 #19
0
 public MWCRandom(IntPoint3 p, int seed)
 {
     m_z = Hash.HashUInt32((uint)p.GetHashCode());
     m_w = (uint)seed;
     if (m_z == 0)
         m_z = 1;
     if (m_w == 0)
         m_w = 1;
 }
예제 #20
0
 public FetchItemAssignment(IJobObserver parent, IEnvironmentObject env, IntPoint3 location, IItemObject item, DirectionSet positioning)
     : base(parent)
 {
     this.Item = item;
     m_environment = env;
     m_location = location;
     m_state = State.None;
     m_positioning = positioning;
     this.LaborID = Dwarrowdelf.LaborID.Hauling;
 }
예제 #21
0
        public void SetContext(EnvironmentObject env, IntPoint3 location)
        {
            m_env = env;
            m_location = location;

            var items = m_env.ItemTracker.GetItemsByDistance(m_location,
                i => i.ItemInfo.IsInstallable && i.IsReserved == false && i.IsInstalled == false);

            listBox.ItemsSource = items;
        }
예제 #22
0
        public InstallItemJob(IJobObserver parent, IItemObject item, IEnvironmentObject env, IntPoint3 location)
            : base(parent)
        {
            m_item = item;
            m_location = location;

            m_state = 0;

            AddSubJob(new AssignmentGroups.FetchItemAssignment(this, env, location, item));
        }
예제 #23
0
        public static IEnumerable<ILivingObject> FindEnemies(IEnvironmentObject env, IntPoint3 location, int range, LivingCategory categories)
        {
            int maxSide = 2 * range + 1;

            var rect = new IntGrid2Z(location.X - maxSide / 2, location.Y - maxSide / 2, maxSide, maxSide, location.Z);

            return env.GetContents(rect)
                .OfType<ILivingObject>()
                .Where(o => (o.LivingCategory & categories) != 0)
                .OrderBy(o => (location - o.Location).Length);
        }
예제 #24
0
        public FetchItems(IJobObserver parent, IEnvironmentObject env, IntPoint3 location, IEnumerable<IItemObject> items, DirectionSet positioning)
            : base(parent)
        {
            foreach (var item in items)
            {
                var job = new AssignmentGroups.FetchItemAssignment(this, env, location, item, positioning);
                AddSubJob(job);
            }

            Debug.Assert(this.SubJobs.Count > 0);
        }
예제 #25
0
 public ushort GetHeuristic(IntPoint3 location)
 {
     var v = m_destination - location;
     #if !asd
     int hDiagonal = Math.Min(Math.Min(Math.Abs(v.X), Math.Abs(v.Y)), Math.Abs(v.Z));
     int hStraight = v.ManhattanLength;
     int h = AStarFinder.COST_DIAGONAL * hDiagonal + AStarFinder.COST_STRAIGHT * (hStraight - 2 * hDiagonal);
     #else
     int h = v.ManhattanLength * AStar.COST_STRAIGHT;
     #endif
     return (ushort)h;
 }
예제 #26
0
        public void AddInstallJob(ItemObject item, IntPoint3 location)
        {
            var data = new InstallJobData()
            {
                Mode = InstallMode.Install,
                Item = item,
                Location = location,
            };

            item.ReservedBy = this;

            m_jobDataList.Add(data);

            m_environment.OnTileExtraChanged(location);
        }
예제 #27
0
        /// <summary>
        /// Tile can be entered and stood upon
        /// </summary>
        public static bool CanEnter(IEnvironmentObject env, IntPoint3 location)
        {
            if (!env.Contains(location))
                return false;

            var td = env.GetTileData(location);

            if (td.IsUndefined)
                return false;

            var terrain = Terrains.GetTerrain(td.TerrainID);
            var interior = Interiors.GetInterior(td.InteriorID);
            var itemBlocks = (td.Flags & TileFlags.ItemBlocks) != 0;

            return terrain.IsSupporting && !terrain.IsBlocker && !interior.IsBlocker && !itemBlocks;
        }
예제 #28
0
        static IntPoint3? GetLocNearEntry(EnvironmentObject env)
        {
            foreach (var p in IntPoint2.SquareSpiral(env.StartLocation.ToIntPoint(), env.Width / 2))
            {
                if (env.Size.Plane.Contains(p) == false)
                    continue;

                var z = env.GetDepth(p);

                var p3 = new IntPoint3(p, z);

                if (EnvironmentHelpers.CanEnter(env, p3))
                    return p3;
            }

            return null;
        }
예제 #29
0
        IntPoint3 GetRandomSurfaceLocation(Environment env, int zLevel)
        {
            IntPoint3 p;
            int       iter = 0;

            do
            {
                if (iter++ > 10000)
                {
                    throw new Exception();
                }

                p = new IntPoint3(m_random.Next(env.Width), m_random.Next(env.Height), zLevel);
            } while (!EnvironmentHelpers.CanEnter(env, p));

            return(p);
        }
예제 #30
0
        /// <summary>
        /// For PlanarUpDown directions, return Direction.None if the direction cannot be entered,
        /// or the direction, adjusted by slopes (i.e. or'ed with Up or Down)
        /// </summary>
        public static Direction AdjustMoveDir(IEnvironmentObject env, IntPoint3 location, Direction dir)
        {
            Debug.Assert(dir.IsValid());
            Debug.Assert(dir != Direction.None);
            Debug.Assert(dir.IsPlanarUpDown());

            if (EnvironmentHelpers.CanMoveFromTo(env, location, dir))
                return dir;

            if (dir == Direction.Up || dir == Direction.Down)
                return Direction.None;

            if (EnvironmentHelpers.CanMoveFromTo(env, location, dir | Direction.Up))
                return dir | Direction.Up;

            if (EnvironmentHelpers.CanMoveFromTo(env, location, dir | Direction.Down))
                return dir | Direction.Down;

            return Direction.None;
        }
예제 #31
0
        public ItemObject GetReachableItemByDistance(IntPoint3 location, IItemFilter filter,
			Unreachables unreachables)
        {
            var items = m_items
                .Where(i => i.IsReserved == false && i.IsInstalled == false && unreachables.IsUnreachable(i.Location) == false)
                .Where(i => filter.Match(i))
                .OrderBy(i => (i.Location - location).ManhattanLength);

            foreach (var item in items)
            {
                var found = AStar.AStarFinder.CanReach(m_env, location, item.Location, DirectionSet.Exact);

                if (found)
                    return item;

                unreachables.Add(item.Location);
            }

            return null;
        }
예제 #32
0
        /// <summary>
        /// Can the given tile be seen from any direction
        /// </summary>
        public static bool CanBeSeen(IEnvironmentObject env, IntPoint3 location)
        {
            bool hidden = true;

            foreach (var d in DirectionExtensions.PlanarDirections)
            {
                var p = location + d;

                if (env.Contains(p) && env.GetTileData(p).IsSeeThrough)
                {
                    hidden = false;
                    break;
                }
            }

            if (hidden)
            {
                var p = location + Direction.Up;
                if (env.Contains(p) && env.GetTileData(p).IsSeeThroughDown)
                    hidden = false;
            }

            return !hidden;
        }