Beispiel #1
0
        private static bool Path(CreatureMovement mover, Voxel start, GoalRegion goal, ChunkManager chunks, int maxExpansions, ref List<Creature.MoveAction> toReturn, bool reverse)
        {
            VoxelChunk startChunk = chunks.ChunkData.ChunkMap[start.ChunkID];
            VoxelChunk endChunk = chunks.ChunkData.ChunkMap[goal.GetVoxel().ChunkID];

            if(startChunk.IsCompletelySurrounded(start) || endChunk.IsCompletelySurrounded(goal.GetVoxel()))
            {
                toReturn = null;
                return false;
            }

            HashSet<Voxel> closedSet = new HashSet<Voxel>();

            HashSet<Voxel> openSet = new HashSet<Voxel>
            {
                start
            };

            Dictionary<Voxel, Creature.MoveAction> cameFrom = new Dictionary<Voxel, Creature.MoveAction>();
            Dictionary<Voxel, float> gScore = new Dictionary<Voxel, float>();
            PriorityQueue<Voxel> fScore = new PriorityQueue<Voxel>();
            gScore[start] = 0.0f;
            fScore.Enqueue(start, gScore[start] + Heuristic(start, goal.GetVoxel()));

            int numExpansions = 0;

            List<Voxel> manhattanNeighbors = new List<Voxel>(6);
            for (int i = 0; i < 6; i++)
            {
                manhattanNeighbors.Add(new Voxel());
            }
            while(openSet.Count > 0 && numExpansions < maxExpansions)
            {
                Voxel current = GetVoxelWithMinimumFScore(fScore, openSet);

                if (current == null)
                {
                    current = start;
                    numExpansions++;
                }
                numExpansions++;
                if (goal.IsInGoalRegion(current))
                {
                    Creature.MoveAction first = new Creature.MoveAction()
                    {
                        Voxel = current,
                        MoveType = Creature.MoveType.Walk
                    };
                    toReturn = ReconstructPath(cameFrom, first);
                    return true;
                }

                openSet.Remove(current);
                closedSet.Add(current);

                VoxelChunk currentChunk = chunks.ChunkData.ChunkMap[current.ChunkID];

                List<Creature.MoveAction> neighbors = null;

                neighbors = mover.GetMoveActions(current);
                currentChunk.GetNeighborsManhattan(current, manhattanNeighbors);

                if(manhattanNeighbors.Contains(goal.GetVoxel()))
                {
                    Creature.MoveAction first = new Creature.MoveAction()
                    {
                        Voxel = current,
                        MoveType = Creature.MoveType.Walk
                    };
                    Creature.MoveAction last = new Creature.MoveAction()
                    {
                        Voxel = goal.GetVoxel(),
                        MoveType = Creature.MoveType.Walk
                    };
                    List<Creature.MoveAction> subPath = ReconstructPath(cameFrom, first);
                    subPath.Add(last);
                    toReturn = subPath;
                    return true;
                }

                foreach(Creature.MoveAction n in neighbors)
                {
                    if(closedSet.Contains(n.Voxel))
                    {
                        continue;
                    }

                    float tenativeGScore = gScore[current] + GetDistance(current, n.Voxel, n.MoveType, chunks);

                    if(openSet.Contains(n.Voxel) && !(tenativeGScore < gScore[n.Voxel]))
                    {
                        continue;
                    }

                    openSet.Add(n.Voxel);
                    Creature.MoveAction cameAction = n;
                    cameAction.Voxel = current;

                    cameFrom[n.Voxel] = cameAction;
                    gScore[n.Voxel] = tenativeGScore;
                    fScore.Enqueue(n.Voxel, gScore[n.Voxel] + Heuristic(n.Voxel, goal.GetVoxel()));
                }

                if(numExpansions >= maxExpansions)
                {
                    return false;
                }
            }
            toReturn = null;
            return false;
        }
Beispiel #2
0
        public List<Creature.MoveAction> GetMoveActions(Voxel voxel)
        {
            List<Creature.MoveAction> toReturn = new List<Creature.MoveAction>();
           
            CollisionManager objectHash = PlayState.ComponentManager.CollisionManager;

            Voxel[,,] neighborHood = GetNeighborhood(voxel);
            int x = (int)voxel.GridPosition.X;
            int y = (int)voxel.GridPosition.Y;
            int z = (int)voxel.GridPosition.Z;
            bool inWater = (neighborHood[1, 1, 1] != null && neighborHood[1, 1, 1].WaterLevel > 5);
            bool standingOnGround = (neighborHood[1, 0, 1] != null && !neighborHood[1, 0, 1].IsEmpty);
            bool topCovered = (neighborHood[1, 2, 1] != null && !neighborHood[1, 2, 1].IsEmpty);
            bool hasNeighbors = HasNeighbors(neighborHood);


            List<Creature.MoveAction> successors = new List<Creature.MoveAction>();

            //Climbing ladders
            IEnumerable<IBoundedObject> objectsInside =
                objectHash.Hashes[CollisionManager.CollisionType.Static].GetItems(
                    new Point3(MathFunctions.FloorInt(voxel.Position.X),
                        MathFunctions.FloorInt(voxel.Position.Y),
                        MathFunctions.FloorInt(voxel.Position.Z)));

            bool blockedByObject = false;
            if (objectsInside != null)
            {
                var bodies = objectsInside.OfType<GameComponent>();
                var enumerable = bodies as IList<GameComponent> ?? bodies.ToList();
                // TODO: This is supposed to be done when the door is a NEIGHBOR of this voxel only!!
                foreach (GameComponent body in enumerable)
                {
                    Door door = body.GetRootComponent().GetChildrenOfType<Door>(true).FirstOrDefault();

                    if (door != null)
                    {
                        if (
                            PlayState.Diplomacy.GetPolitics(door.TeamFaction, Creature.Faction).GetCurrentRelationship() ==
                            Relationship.Hateful)
                        {

                            if (IsEmpty(neighborHood[0, 1, 1]))
                                // +- x
                                successors.Add(new Creature.MoveAction()
                                {
                                    Diff = new Vector3(0, 1, 1),
                                    MoveType = Creature.MoveType.DestroyObject,
                                    InteractObject = door,
                                    Voxel = neighborHood[0, 1, 1]
                                });

                            if (IsEmpty(neighborHood[2, 1, 1]))
                                successors.Add(new Creature.MoveAction()
                                {
                                    Diff = new Vector3(2, 1, 1),
                                    MoveType = Creature.MoveType.DestroyObject,
                                    InteractObject = door,
                                    Voxel = neighborHood[2, 1, 1]
                                });

                            if (IsEmpty(neighborHood[1, 1, 0]))
                                // +- z
                                successors.Add(new Creature.MoveAction()
                                {
                                    Diff = new Vector3(1, 1, 0),
                                    MoveType = Creature.MoveType.DestroyObject,
                                    InteractObject = door,
                                    Voxel = neighborHood[1, 1, 0]
                                });

                            if (IsEmpty(neighborHood[1, 1, 2]))
                                successors.Add(new Creature.MoveAction()
                                {
                                    Diff = new Vector3(1, 1, 2),
                                    MoveType = Creature.MoveType.DestroyObject,
                                    InteractObject = door,
                                    Voxel = neighborHood[1, 1, 2]
                                });


                            blockedByObject = true;
                        }
                    }
                }

                if (blockedByObject)
                {
                    return successors;
                }

                if (CanClimb)
                {
                    bool hasLadder = enumerable.Any(component => component.Tags.Contains("Climbable"));
                    if (hasLadder)
                    {
                        successors.Add(new Creature.MoveAction()
                        {
                            Diff = new Vector3(1, 2, 1),
                            MoveType = Creature.MoveType.Climb
                        });

                        if (!standingOnGround)
                        {
                            successors.Add(new Creature.MoveAction()
                            {
                                Diff = new Vector3(1, 0, 1),
                                MoveType = Creature.MoveType.Climb
                            });
                        }

                        standingOnGround = true;
                    }
                }
            }


            if (standingOnGround || (CanSwim && inWater))
            {
                Creature.MoveType moveType = inWater ? Creature.MoveType.Swim : Creature.MoveType.Walk;
                if (IsEmpty(neighborHood[0, 1, 1]))
                    // +- x
                    successors.Add(new Creature.MoveAction()
                    {
                        Diff = new Vector3(0, 1, 1),
                        MoveType = moveType
                    });

                if (IsEmpty(neighborHood[2, 1, 1]))
                    successors.Add(new Creature.MoveAction()
                    {
                        Diff = new Vector3(2, 1, 1),
                        MoveType = moveType
                    });

                if (IsEmpty(neighborHood[1, 1, 0]))
                    // +- z
                    successors.Add(new Creature.MoveAction()
                    {
                        Diff = new Vector3(1, 1, 0),
                        MoveType = moveType
                    });

                if (IsEmpty(neighborHood[1, 1, 2]))
                    successors.Add(new Creature.MoveAction()
                    {
                        Diff = new Vector3(1, 1, 2),
                        MoveType = moveType
                    });

                if (!hasNeighbors)
                {
                    if (IsEmpty(neighborHood[2, 1, 2]))
                        // +x + z
                        successors.Add(new Creature.MoveAction()
                        {
                            Diff = new Vector3(2, 1, 2),
                            MoveType = moveType
                        });

                    if (IsEmpty(neighborHood[2, 1, 0]))
                        successors.Add(new Creature.MoveAction()
                        {
                            Diff = new Vector3(2, 1, 0),
                            MoveType = moveType
                        });

                    if (IsEmpty(neighborHood[0, 1, 2]))
                        // -x -z
                        successors.Add(new Creature.MoveAction()
                        {
                            Diff = new Vector3(0, 1, 2),
                            MoveType = moveType
                        });

                    if (IsEmpty(neighborHood[0, 1, 0]))
                        successors.Add(new Creature.MoveAction()
                        {
                            Diff = new Vector3(0, 1, 0),
                            MoveType = moveType
                        });
                }

            }

            if (!topCovered && (standingOnGround || (CanSwim && inWater)))
            {
                for (int dx = 0; dx <= 2; dx++)
                {
                    for (int dz = 0; dz <= 2; dz++)
                    {
                        if (dx == 1 && dz == 1) continue;

                        if (!IsEmpty(neighborHood[dx, 1, dz]))
                        {
                            successors.Add(new Creature.MoveAction()
                            {
                                Diff = new Vector3(dx, 2, dz),
                                MoveType = Creature.MoveType.Jump
                            });
                        }
                    }
                }

            }


            // Falling
            if (!inWater && !standingOnGround)
            {
                successors.Add(new Creature.MoveAction()
                {
                    Diff = new Vector3(1, 0, 1),
                    MoveType = Creature.MoveType.Fall
                });
            }

            if (CanFly)
            {
                for (int dx = 0; dx <= 2; dx++)
                {
                    for (int dz = 0; dz <= 2; dz++)
                    {
                        for (int dy = 0; dy <= 2; dy++)
                        {
                            if (dx == 1 && dz == 1 && dy == 1) continue;

                            if (IsEmpty(neighborHood[dx, 1, dz]))
                            {
                                successors.Add(new Creature.MoveAction()
                                {
                                    Diff = new Vector3(dx, dy, dz),
                                    MoveType = Creature.MoveType.Fly
                                });
                            }
                        }
                    }
                }
            }


            foreach (Creature.MoveAction v in successors)
            {
                Voxel n = neighborHood[(int)v.Diff.X, (int)v.Diff.Y, (int)v.Diff.Z];
                if (n != null && (n.IsEmpty || n.WaterLevel > 0))
                {
                    Creature.MoveAction newAction = v;
                    newAction.Voxel = n;
                    toReturn.Add(newAction);
                }
            }


            return toReturn;
        }
Beispiel #3
0
        private static bool Path(CreatureMovement mover, Voxel start, GoalRegion goal, ChunkManager chunks, int maxExpansions, ref List <Creature.MoveAction> toReturn, bool reverse, float weight)
        {
            if (!goal.IsPossible())
            {
                toReturn = null;
                return(false);
            }


            HashSet <Voxel> closedSet = new HashSet <Voxel>();

            HashSet <Voxel> openSet = new HashSet <Voxel>
            {
                start
            };

            Dictionary <Voxel, Creature.MoveAction> cameFrom = new Dictionary <Voxel, Creature.MoveAction>();
            Dictionary <Voxel, float> gScore = new Dictionary <Voxel, float>();
            PriorityQueue <Voxel>     fScore = new PriorityQueue <Voxel>();

            gScore[start] = 0.0f;
            fScore.Enqueue(start, gScore[start] + weight * goal.Heuristic(start));

            int numExpansions = 0;

            List <Voxel> manhattanNeighbors = new List <Voxel>(6);

            for (int i = 0; i < 6; i++)
            {
                manhattanNeighbors.Add(new Voxel());
            }
            while (openSet.Count > 0 && numExpansions < maxExpansions)
            {
                Voxel current = GetVoxelWithMinimumFScore(fScore, openSet);

                if (current == null)
                {
                    current = start;
                    numExpansions++;
                }
                numExpansions++;
                if (goal.IsInGoalRegion(current))
                {
                    Creature.MoveAction first = new Creature.MoveAction()
                    {
                        Voxel    = current,
                        MoveType = Creature.MoveType.Walk
                    };
                    toReturn = ReconstructPath(cameFrom, first);
                    return(true);
                }

                openSet.Remove(current);
                closedSet.Add(current);

                VoxelChunk currentChunk = chunks.ChunkData.ChunkMap[current.ChunkID];

                List <Creature.MoveAction> neighbors = null;

                neighbors = mover.GetMoveActions(current);
                currentChunk.GetNeighborsManhattan(current, manhattanNeighbors);

                if (manhattanNeighbors.Contains(goal.GetVoxel()))
                {
                    Creature.MoveAction first = new Creature.MoveAction()
                    {
                        Voxel    = current,
                        MoveType = Creature.MoveType.Walk
                    };
                    Creature.MoveAction last = new Creature.MoveAction()
                    {
                        Voxel    = goal.GetVoxel(),
                        MoveType = Creature.MoveType.Walk
                    };
                    List <Creature.MoveAction> subPath = ReconstructPath(cameFrom, first);
                    subPath.Add(last);
                    toReturn = subPath;
                    return(true);
                }

                foreach (Creature.MoveAction n in neighbors)
                {
                    if (closedSet.Contains(n.Voxel))
                    {
                        continue;
                    }

                    float tenativeGScore = gScore[current] + GetDistance(current, n.Voxel, n.MoveType, chunks);

                    if (openSet.Contains(n.Voxel) && !(tenativeGScore < gScore[n.Voxel]))
                    {
                        continue;
                    }

                    openSet.Add(n.Voxel);
                    Creature.MoveAction cameAction = n;
                    cameAction.Voxel = current;

                    cameFrom[n.Voxel] = cameAction;
                    gScore[n.Voxel]   = tenativeGScore;
                    fScore.Enqueue(n.Voxel, gScore[n.Voxel] + weight * goal.Heuristic(n.Voxel));
                }

                if (numExpansions >= maxExpansions)
                {
                    return(false);
                }
            }
            toReturn = null;
            return(false);
        }
Beispiel #4
0
        public static List <Creature.MoveAction> ReconstructPath(Dictionary <Voxel, Creature.MoveAction> cameFrom, Creature.MoveAction currentNode)
        {
            List <Creature.MoveAction> toReturn = new List <Creature.MoveAction>();

            if (cameFrom.ContainsKey(currentNode.Voxel))
            {
                toReturn.AddRange(ReconstructPath(cameFrom, cameFrom[currentNode.Voxel]));
                toReturn.Add(currentNode);
                return(toReturn);
            }
            else
            {
                toReturn.Add(currentNode);
                return(toReturn);
            }
        }
Beispiel #5
0
        public IEnumerable <Status> AvoidTarget(float range, float time)
        {
            if (Target == null)
            {
                yield return(Status.Fail);

                yield break;
            }
            Timer avoidTimer = new Timer(time, true, Timer.TimerMode.Game);

            while (true)
            {
                avoidTimer.Update(DwarfTime.LastTime);

                if (avoidTimer.HasTriggered)
                {
                    yield return(Status.Success);
                }

                float dist = (Target.Position - Agent.Position).Length();

                if (dist > range)
                {
                    yield return(Status.Success);

                    yield break;
                }

                List <Creature.MoveAction> neighbors = Agent.Movement.GetMoveActions(Agent.Position);
                neighbors.Sort((a, b) =>
                {
                    if (a.Equals(b))
                    {
                        return(0);
                    }

                    float da = (a.Voxel.Position - Target.Position).LengthSquared();
                    float db = (b.Voxel.Position - Target.Position).LengthSquared();

                    return(da.CompareTo(db));
                });

                neighbors.RemoveAll(
                    a => a.MoveType == Creature.MoveType.Jump || a.MoveType == Creature.MoveType.Climb);

                if (neighbors.Count == 0)
                {
                    yield return(Status.Fail);

                    yield break;
                }

                Creature.MoveAction furthest = neighbors.Last();
                bool  reachedTarget          = false;
                Timer timeout = new Timer(2.0f, true);
                while (!reachedTarget)
                {
                    Vector3 output = Creature.Controller.GetOutput(DwarfTime.Dt, furthest.Voxel.Position + Vector3.One * 0.5f,
                                                                   Agent.Position);
                    Creature.Physics.ApplyForce(output, DwarfTime.Dt);

                    if (Creature.AI.Movement.CanFly)
                    {
                        Creature.Physics.ApplyForce(Vector3.Up * 10, DwarfTime.Dt);
                    }

                    timeout.Update(DwarfTime.LastTime);

                    yield return(Status.Running);

                    if (timeout.HasTriggered || (furthest.Voxel.Position - Agent.Position).Length() < 1)
                    {
                        reachedTarget = true;
                    }
                    Agent.Creature.CurrentCharacterMode = Creature.CharacterMode.Walking;
                }
                yield return(Status.Success);

                yield break;
            }
        }
Beispiel #6
0
        public List <Creature.MoveAction> GetMoveActions(Voxel voxel)
        {
            List <Creature.MoveAction> toReturn = new List <Creature.MoveAction>();

            CollisionManager objectHash = PlayState.ComponentManager.CollisionManager;

            Voxel[,,] neighborHood = GetNeighborhood(voxel);
            int  x                = (int)voxel.GridPosition.X;
            int  y                = (int)voxel.GridPosition.Y;
            int  z                = (int)voxel.GridPosition.Z;
            bool inWater          = (neighborHood[1, 1, 1] != null && neighborHood[1, 1, 1].WaterLevel > 5);
            bool standingOnGround = (neighborHood[1, 0, 1] != null && !neighborHood[1, 0, 1].IsEmpty);
            bool topCovered       = (neighborHood[1, 2, 1] != null && !neighborHood[1, 2, 1].IsEmpty);
            bool hasNeighbors     = HasNeighbors(neighborHood);


            List <Creature.MoveAction> successors = new List <Creature.MoveAction>();

            //Climbing ladders
            List <IBoundedObject> bodiesInside =
                objectHash.Hashes[CollisionManager.CollisionType.Static].GetItems(
                    new Point3(MathFunctions.FloorInt(voxel.Position.X),
                               MathFunctions.FloorInt(voxel.Position.Y),
                               MathFunctions.FloorInt(voxel.Position.Z)));

            if (CanClimb && bodiesInside != null)
            {
                bool hasLadder =
                    bodiesInside.OfType <GameComponent>()
                    .Any(component => component.Tags.Contains("Climbable"));
                if (hasLadder)
                {
                    successors.Add(new Creature.MoveAction()
                    {
                        Diff     = new Vector3(1, 2, 1),
                        MoveType = Creature.MoveType.Climb
                    });

                    if (!standingOnGround)
                    {
                        successors.Add(new Creature.MoveAction()
                        {
                            Diff     = new Vector3(1, 0, 1),
                            MoveType = Creature.MoveType.Climb
                        });
                    }

                    standingOnGround = true;
                }
            }


            if (standingOnGround || (CanSwim && inWater))
            {
                Creature.MoveType moveType = inWater ? Creature.MoveType.Swim : Creature.MoveType.Walk;
                if (IsEmpty(neighborHood[0, 1, 1]))
                {
                    // +- x
                    successors.Add(new Creature.MoveAction()
                    {
                        Diff     = new Vector3(0, 1, 1),
                        MoveType = moveType
                    });
                }

                if (IsEmpty(neighborHood[2, 1, 1]))
                {
                    successors.Add(new Creature.MoveAction()
                    {
                        Diff     = new Vector3(2, 1, 1),
                        MoveType = moveType
                    });
                }

                if (IsEmpty(neighborHood[1, 1, 0]))
                {
                    // +- z
                    successors.Add(new Creature.MoveAction()
                    {
                        Diff     = new Vector3(1, 1, 0),
                        MoveType = moveType
                    });
                }

                if (IsEmpty(neighborHood[1, 1, 2]))
                {
                    successors.Add(new Creature.MoveAction()
                    {
                        Diff     = new Vector3(1, 1, 2),
                        MoveType = moveType
                    });
                }

                if (!hasNeighbors)
                {
                    if (IsEmpty(neighborHood[2, 1, 2]))
                    {
                        // +x + z
                        successors.Add(new Creature.MoveAction()
                        {
                            Diff     = new Vector3(2, 1, 2),
                            MoveType = moveType
                        });
                    }

                    if (IsEmpty(neighborHood[2, 1, 0]))
                    {
                        successors.Add(new Creature.MoveAction()
                        {
                            Diff     = new Vector3(2, 1, 0),
                            MoveType = moveType
                        });
                    }

                    if (IsEmpty(neighborHood[0, 1, 2]))
                    {
                        // -x -z
                        successors.Add(new Creature.MoveAction()
                        {
                            Diff     = new Vector3(0, 1, 2),
                            MoveType = moveType
                        });
                    }

                    if (IsEmpty(neighborHood[0, 1, 0]))
                    {
                        successors.Add(new Creature.MoveAction()
                        {
                            Diff     = new Vector3(0, 1, 0),
                            MoveType = moveType
                        });
                    }
                }
            }

            if (!topCovered && (standingOnGround || (CanSwim && inWater)))
            {
                for (int dx = 0; dx <= 2; dx++)
                {
                    for (int dz = 0; dz <= 2; dz++)
                    {
                        if (dx == 1 && dz == 1)
                        {
                            continue;
                        }

                        if (!IsEmpty(neighborHood[dx, 1, dz]))
                        {
                            successors.Add(new Creature.MoveAction()
                            {
                                Diff     = new Vector3(dx, 2, dz),
                                MoveType = Creature.MoveType.Jump
                            });
                        }
                    }
                }
            }


            // Falling
            if (!inWater && !standingOnGround)
            {
                successors.Add(new Creature.MoveAction()
                {
                    Diff     = new Vector3(1, 0, 1),
                    MoveType = Creature.MoveType.Fall
                });
            }

            if (CanFly)
            {
                for (int dx = 0; dx <= 2; dx++)
                {
                    for (int dz = 0; dz <= 2; dz++)
                    {
                        for (int dy = 0; dy <= 2; dy++)
                        {
                            if (dx == 1 && dz == 1 && dy == 1)
                            {
                                continue;
                            }

                            if (IsEmpty(neighborHood[dx, 1, dz]))
                            {
                                successors.Add(new Creature.MoveAction()
                                {
                                    Diff     = new Vector3(dx, dy, dz),
                                    MoveType = Creature.MoveType.Fly
                                });
                            }
                        }
                    }
                }
            }


            foreach (Creature.MoveAction v in successors)
            {
                Voxel n = neighborHood[(int)v.Diff.X, (int)v.Diff.Y, (int)v.Diff.Z];
                if (n != null && (n.IsEmpty || n.WaterLevel > 0))
                {
                    Creature.MoveAction newAction = v;
                    newAction.Voxel = n;
                    toReturn.Add(newAction);
                }
            }


            return(toReturn);
        }