예제 #1
0
 public DamageEvent(DoomEventType eventType, int damage, ActorBase damagedActor, params string[] listenerNames)
 {
     _eventType = eventType;
     _listenerNames = listenerNames;
     _damage = damage;
     _damagedActor = damagedActor;
 }
예제 #2
0
        public static IList<Tile> CalculateAStarPath(Tile start, Tile goal, Level level, ActorBase actor)
        {
            if (start == null || goal == null)
                return null;
            if (goal.ActorInTile != null)
                return null;

            var path = new List<Tile>();
            var nodes = new Node[level.Length,level.Width];
            for (int x = 0; x < level.Length; x++)
            {
                for (int y = 0; y < level.Width; y++)
                {
                    nodes[x, y] = new Node(x, y);
                }
            }

            return CalculatePath(start, goal, level, nodes, actor);
        }
예제 #3
0
        public static TileSelector StandardMovementTileSelector(Level level, Tile currentTile, ActorBase actor)
        {
            var selector = new TileSelector();
            int movementRange = actor.CurrentStats.MovementRange;
            for (int i = -movementRange; i <= movementRange; i++)
            {
                for (int j = -movementRange; j <= movementRange; j++)
                {
                    if (Math.Abs(i) + Math.Abs(j) <= movementRange)
                    {
                        Tile t = level.GetTileAt(currentTile.XCoord + j, currentTile.YCoord + i);
                        if (t != null && t.ActorInTile == null)
                        {
                            if (AStar.CalculateAStarPath(currentTile, t, level, actor) != null)
                            {
                                selector.AddValidTile(t);
                            }
                        }
                    }
                }
            }

            return selector;
        }
예제 #4
0
 public void OnChargeTimeReached(IDoomEvent doomEvent)
 {
     if (ActiveUnit == null)
     {
         var turnEvent = (TurnEvent)doomEvent;
         ActiveUnit = turnEvent.Actor;
         _stateMachine.SetState(new ActionSelection(this, ActiveUnit));
     }
 }
예제 #5
0
 public ActorEvent(DoomEventType eventType, ActorBase actor, params string[] listenerNames)
 {
     _eventType = eventType;
     _actor = actor;
     _listenerNames = listenerNames;
 }
예제 #6
0
 public bool IsAIControlled(ActorBase actor)
 {
     return (actor.Team != 1);
 }
예제 #7
0
        public static ActionAnimationScript MakeScript(IList<Tile> path, ActorBase actor)
        {
            var scriptBuilder = new ActionAnimationScriptBuilder().Name(actor.ActorId + "Move");
            for (int pathIndex = 1; pathIndex < path.Count; pathIndex++)
            {
                var tile = path[pathIndex];
                float tileYPos = tile.CreateBoundingBox().Max.Y;
                var tilePosition = tile.GetTopCenter();
                BoundingBox centerCheckBox = new BoundingBox(tilePosition - new Vector3(5.0f), tilePosition + new Vector3(5.0f));
                scriptBuilder = scriptBuilder
                    .Segment()
                    .OnStart((sv) =>
                    {
                        Vector3 directionToMove = actor.GetDirectionToPoint(tilePosition);
                        FaceAndMoveToPoint(tilePosition, actor);
                        if (directionToMove.Y > 0.0f)
                        {
                            actor.Velocity.Y *= 2;
                            sv.SetVariable("evalFunc", new Func<Vector3, bool>((v) => v.Y >= tileYPos));
                        }
                        else if (directionToMove.Y <= 0)
                        {
                            Vector3 currentPosition = actor.Position;
                            if (directionToMove.X >= 0.9f)
                            {
                                sv.SetVariable("evalFunc", new Func<Vector3, bool>((v) => v.X >= currentPosition.X + 32f));
                            }
                            else if (directionToMove.X <= -0.9f)
                            {
                                sv.SetVariable("evalFunc", new Func<Vector3, bool>((v) => v.X <= currentPosition.X - 32f));
                            }
                            else if (directionToMove.Z <= -0.9f)
                            {
                                sv.SetVariable("evalFunc", new Func<Vector3, bool>((v) => v.Z <= currentPosition.Z - 32f));
                            }
                            else if (directionToMove.Z >= 0.9f)
                            {
                                sv.SetVariable("evalFunc", new Func<Vector3, bool>((v) => v.Z >= currentPosition.Z + 32f));
                            }
                            actor.Velocity.Y = 0;
                        }
                    })
                    .EndCondition((sv) =>
                    {
                        bool result = sv.GetVariable<Func<Vector3, bool>>("evalFunc")(actor.Position);
                        return result;
                    });

                if (pathIndex == path.Count - 1)
                {
                    var removeFromTileEvent = new ActorEvent(DoomEventType.RemoveFromCurrentTile, actor);
                    scriptBuilder = scriptBuilder
                        .Segment()
                        .OnStart(() =>
                        {
                            if (path.Count == 2) MessagingSystem.DispatchEvent(removeFromTileEvent, actor.ActorId);
                            FaceAndMoveToPoint(tilePosition, actor);
                        })
                        .EndCondition(() =>
                        {
                            return centerCheckBox.Contains(actor.Position) == ContainmentType.Contains;
                        })
                        .OnComplete(() =>
                        {
                            actor.Velocity = Vector3.Zero;
                            actor.SnapToTile(tile);
                            tile.SetActor(actor);
                        });
                }
                else if (pathIndex == 1)
                {
                    var removeFromTileEvent = new ActorEvent(DoomEventType.RemoveFromCurrentTile, actor);
                    scriptBuilder = scriptBuilder
                        .Segment()
                        .OnStart(() =>
                        {
                            MessagingSystem.DispatchEvent(removeFromTileEvent, actor.ActorId);
                            FaceAndMoveToPoint(tilePosition, actor);
                        })
                        .EndCondition(() =>
                        {
                            return centerCheckBox.Contains(actor.Position) == ContainmentType.Contains;
                        });
                }
                else if (pathIndex != path.Count - 1)
                {
                    scriptBuilder = scriptBuilder
                        .Segment()
                        .OnStart(() =>
                        {
                            FaceAndMoveToPoint(tilePosition, actor);
                        })
                        .EndCondition(() =>
                        {
                            return centerCheckBox.Contains(actor.Position) == ContainmentType.Contains;
                        });
                }

            }
            return scriptBuilder.Build();
        }
예제 #8
0
 public ActionSelection(GameState gameState, ActorBase actionActor)
     : base(gameState)
 {
     InputProcessor = new ActionSelectionProcessor(gameState, this);
     _actionActor = actionActor;
 }
예제 #9
0
 public Tile GetTileOfActor(ActorBase actor)
 {
     return _tiles.FirstOrDefault(t => t.ActorInTile == actor);
 }
예제 #10
0
 private static void FaceAndMoveToPoint(Vector3 tilePosition, ActorBase actor)
 {
     Vector3 directionToMove = actor.GetDirectionToPoint(tilePosition);
     actor.FacePoint(tilePosition, true);
     actor.Velocity = actor.MovementVelocityModifier * directionToMove;
 }
예제 #11
0
        private Tile temp_GetTileClosestToEnemy(Level currentLevel, ActorBase targetActor)
        {
            var candidateTiles = TileSelectorHelper.StandardMovementTileSelector(currentLevel,
                                                                                currentLevel.GetTileOfActor(this), this).ValidTiles();
            Tile targetTile = currentLevel.GetTileOfActor(targetActor);
            int distance = Int16.MaxValue;
            Tile moveToTile = null;
            foreach (var candidateTile in candidateTiles)
            {
                int candidateDistance = MathUtils.DistanceBetweenTiles(candidateTile, targetTile);
                if (candidateDistance < distance)
                {
                    distance = candidateDistance;
                    moveToTile = candidateTile;
                }
            }

            return moveToTile;
        }
예제 #12
0
 private static float GetHeuristicCost(ActorBase actor, Tile tile, Tile goal)
 {
     return Math.Abs(tile.XCoord - goal.XCoord) + Math.Abs(tile.YCoord - goal.YCoord);
 }
예제 #13
0
 public static TileSelector OccupiedTileSelector(Level level, ActorBase exclude)
 {
     var tileList = level.Tiles.Where(x => x.ActorInTile != null && x.ActorInTile != exclude && x.ActorInTile.IsTargetable()).ToList();
     return new TileSelector(tileList);
 }
예제 #14
0
 public AIDecision(GameState gameState, ActorBase actor)
     : base(gameState)
 {
     _actor = actor;
     InputProcessor = new NoInputProcessor();
 }
예제 #15
0
 public void SetActor(ActorBase actorBase)
 {
     ActorInTile = actorBase;
 }
예제 #16
0
        private static IList<Tile> CalculatePath(Tile start, Tile goal, Level level, Node[,] nodes, ActorBase actor)
        {
            nodes[start.XCoord, start.YCoord].Cost = 0;
            nodes[start.XCoord, start.YCoord].Depth = 0;
            var open = new List<Node>();
            var closed = new List<Node>();
            var path = new List<Tile>();
            int depth = 0;

            open.Add(nodes[start.XCoord, start.YCoord]);

            while (depth < MaximumSearchDistance && (open.Count != 0))
            {
                Node current = open[0];
                if (current == nodes[goal.XCoord, goal.YCoord])
                {
                    break;
                }

                open.RemoveAt(0);
                closed.Add(current);
                for (int x = -1; x <= 1; x++)
                {
                    for (int y = -1; y <= 1; y++)
                    {
                        if (x == 0 && y == 0) continue;
                        if (x != 0 && y != 0) continue;

                        int candidateX = x + current.X;
                        int candidateY = y + current.Y;

                        if (CanMoveToTile(actor, level, start.XCoord, start.YCoord, current.X, current.Y, candidateX, candidateY))
                        {
                            float nextStepCost = current.Cost +
                                                 CalculateMovementCost(actor, level, current.X, current.Y, candidateX,
                                                                       candidateY);
                            Node neighbor = nodes[candidateX, candidateY];
                            if (nextStepCost < neighbor.Cost)
                            {
                                if (open.Contains(neighbor))
                                {
                                    open.Remove(neighbor);
                                }
                                if (closed.Contains(neighbor))
                                {
                                    closed.Remove(neighbor);
                                }
                            }

                            if (!open.Contains(neighbor) && !closed.Contains(neighbor))
                            {
                                neighbor.Cost = nextStepCost;
                                neighbor.Heuristic = GetHeuristicCost(actor, level.GetTileAt(candidateX, candidateY),
                                                                      goal);
                                depth = Math.Max(depth, neighbor.SetParent(current));
                                open.Add(neighbor);
                                open = open.OrderBy(o => o.TotalCost()).ToList();
                            }

                        }
                    }
                }
            }

            if (nodes[goal.XCoord, goal.YCoord].Parent == null) return null;
            Node target = nodes[goal.XCoord, goal.YCoord];
            while (target != nodes[start.XCoord, start.YCoord])
            {
                path.Insert(0, level.GetTileAt(target.X, target.Y));
                target = target.Parent;
            }
            path.Insert(0, start);
            if (path.Count > actor.CurrentStats.MovementRange + 1) return null;

            return path;
        }
예제 #17
0
 private static float CalculateMovementCost(ActorBase actor, Level level, int currentX, int currentY, int candidateX, int candidateY)
 {
     var currentTile = level.GetTileAt(currentX, currentY);
     var candidateTile = level.GetTileAt(candidateX, candidateY);
     return (float)Math.Abs(currentTile.GameHeight - candidateTile.GameHeight);
 }
예제 #18
0
 public DespawnActorEvent(DoomEventType eventType, ActorBase despawnTarget, params string[] listenerNames)
 {
     _eventType = eventType;
     _despawnTarget = despawnTarget;
     _listenerNames = listenerNames;
 }
예제 #19
0
        private static bool CanMoveToTile(ActorBase actor, Level level, int startX, int startY, int currentX, int currentY, int candidateX, int candidateY)
        {
            if (candidateX < 0 || candidateY < 0 || candidateX >= level.Length || candidateY >= level.Width || (candidateX == startX && candidateY == startY))
            {
                return false;
            }

            var currentTile = level.GetTileAt(currentX, currentY);
            var candidateTile = level.GetTileAt(candidateX, candidateY);

            if (Math.Abs(currentTile.GameHeight - candidateTile.GameHeight) > actor.CurrentStats.MaximumHeightCanMove)
                return false;

            if (candidateTile.ActorInTile != null && candidateTile.ActorInTile.Team != actor.Team)
                return false;

            return true;
        }