Beispiel #1
0
 public MoveToPointAction(Unit.Unit unit, Grid.Grid.Node destination, Transform toMove = null, bool twoWayCollisions = false)
 {
     _destination      = destination;
     _twoWayCollisions = twoWayCollisions;
     _unit             = unit;
     _transformToMove  = toMove ?? unit.transform;
 }
        protected override State OnExecute(AgentContext context)
        {
            var occupant = context.Agent.GetComponent <GridOccupantBehaviour>();

            if (occupant == null)
            {
                return(State.Failed);
            }

            Vector2Int newPos       = Vector2Int.zero;
            var        node         = new Grid.Grid.Node();
            bool       noPointFound = true;

            while (noPointFound)
            {
                var direction = Random.Range(0, 2) == 1 ? Vector2Int.right : Vector2Int.up;
                var magnitude = Random.Range(0, 2) == 1 ? 1 : -1;

                newPos = occupant.CurrentNodeIdx + (magnitude * direction);

                if (occupant.Get().Value.TryGetNodeAt(newPos.x, newPos.y, ref node))
                {
                    noPointFound = node.Cost < 0;
                }
            }
            context.AgentBlackboard.Add <Grid.Grid.Node?>(outputKey, node);
            return(State.Succeeded);
        }
        public override void Check(Blackboard agentBoard)
        {
            var col = Physics2D.OverlapBox(transform.position, _size, 0, targetLayers);



            if (col?.transform != null)
            {
                var node = new Grid.Grid.Node();

                if (_grid.Get().Value.TryGetNodeAtWorldPosition(col.transform.position, ref node))
                {
                    _hasTarget    = true;
                    _agent.Target = col.transform;
                    agentBoard.Add <Grid.Grid.Node?>(targetNodeKey, node);
                    return;
                }
            }

            if (removeTargetOnExit)
            {
                _hasTarget    = false;
                _agent.Target = null;
                agentBoard.Remove(targetNodeKey);
            }
        }
        public override bool CanTarget(GridOccupant target, GridOccupant wielder, Grid.Grid grid)
        {
            var direction = target.Position - wielder.Position;

            if (!direction.IsCardinal() || direction.CardinalMagnitude() > 1)
            {
                return(false);
            }

            var node = new Grid.Grid.Node();

            if (grid.TryGetNodeAt(wielder.Position, ref node))
            {
                return(node.Occupants.Any(it => TargetTypes.Contains(it.Type)));
            }

            return(false);
        }
        public void Fire(Unit.Unit unit, Grid.Grid.Node destination, Action onComplete)
        {
            _move.Move(unit, destination, () =>
            {
                // spawn item??
                // destroy
                if (pickupPrefab)
                {
                    unit.QueueAction(new SpawnPickupAction(pickupPrefab, transform.position, item));
                    unit.QueueAction(new DestroyGameObjectAction(gameObject));
                }
                else
                {
                    _unit.Occupant.UpdateGrid(transform.position);
                }

                onComplete();
            });
        }
Beispiel #6
0
        public virtual List <Grid.Grid.Node> FindEffectedNodes(GridOccupant wielder, Vector2Int direction, Grid.Grid grid)
        {
            var occupants = FindTargets(wielder, direction, grid);
            var nodes     = new List <Grid.Grid.Node>();

            foreach (var occupant in occupants)
            {
                if (nodes.FindIndex(it => it.Position == occupant.Position) > -1)
                {
                    var n = new Grid.Grid.Node();
                    if (grid.TryGetNodeAt(occupant.Position, ref n))
                    {
                        nodes.Add(n);
                    }
                }
            }

            return(nodes);
        }
        protected override State OnExecute(AgentContext context)
        {
            if (!context.AgentBlackboard.Contains(targetDirKey))
            {
                return(State.Failed);
            }
            var dir = context.AgentBlackboard.RetrieveData <Vector2Int>(targetDirKey);

            var occupant = context.Agent.GetComponent <GridOccupantBehaviour>();

            if (occupant == null)
            {
                return(State.Failed);
            }

            var agentNode = occupant.CurrentNode;

            if (agentNode == null)
            {
                return(State.Failed);
            }

            dir.x = MathUtils.ClampInt(dir.x, -1, 1);
            dir.y = MathUtils.ClampInt(dir.y, -1, 1);

            dir   *= speed;
            dir.x += agentNode.Value.X;
            dir.y += agentNode.Value.Y;

            var moveNode = new Grid.Grid.Node();

            if (occupant.Get().Value.TryGetNodeAt(dir.x, dir.y, ref moveNode))
            {
                context.AgentBlackboard.Add <Grid.Grid.Node?>(outputKey, moveNode);
                return(State.Succeeded);
            }
            else
            {
                return(State.Failed);
            }
        }
        // public override Grid.Grid.Node[] FindTargets(Grid.Grid.Node wielder, Grid.Grid grid)
        // {
        //     var neighbours = grid.GetNeighbours(wielder);
        //
        //     // todo(chris) consider optimising as this will be used by every mellee enemy on the grid
        //     return neighbours.Where(node => node.Occupants.Any(it => it.Tags.Intersect(TargetTypes).Any())).ToArray();
        // }

        // todo(chris) shouldnt this only find targets in direction??
        public override GridOccupant[] FindTargets(GridOccupant wielder, Vector2Int direction, Grid.Grid grid)
        {
            var node = new Grid.Grid.Node();

            if (grid.TryGetNodeAt(wielder.Position, ref node))
            {
                var neighbours = grid.GetNeighbours(node);

                var targets = new List <GridOccupant>();

                foreach (var neighbour in neighbours)
                {
                    var validOccupants = neighbour.Occupants.Where(it => TargetTypes.Contains(it.Type));
                    targets.AddRange(validOccupants);
                }

                return(targets.ToArray());
            }

            return(null);
        }
Beispiel #9
0
        protected override State OnExecute(AgentContext context)
        {
            if (!context.AgentBlackboard.Contains(relativePosKey))
            {
                return(State.Failed);
            }

            var relativePos = context.AgentBlackboard.RetrieveData <Vector2Int>(relativePosKey);
            var nodeIdx     = context.Occupant.CurrentNodeIdx + relativePos;

            var node = new Grid.Grid.Node();

            if (context.Occupant.Grid.TryGetNodeAt(nodeIdx.x, nodeIdx.y, ref node))
            {
                context.AgentBlackboard.Add <Grid.Grid.Node?>(outputKey, node);
                return(State.Succeeded);
            }
            else
            {
                return(State.Failed);
            }
        }
        public PathDetails CalculatePath(GridOccupant wielder, Vector2Int direction, Grid.Grid grid)
        {
            PathDetails path = new PathDetails
            {
                Travelled        = new List <Grid.Grid.Node>(),
                IsLastNodeTarget = false
            };

            var normalised = direction.CardinalNormalise();

            var magnitude = projectile.Range;
            var node      = new Grid.Grid.Node();

            for (int i = 1; i <= magnitude; i++)
            {
                if (grid.TryGetNodeAt(wielder.Position + i * normalised, ref node))
                {
                    path.Travelled.Add(node);

                    // if we have hit something that has a type then weve eiher hit something we cant move though
                    // or weve hit our target
                    if (node.Occupants.Any(it => it.Type != null))
                    {
                        path.IsLastNodeTarget = node.Occupants.Any(it => it.Type != null && TargetTypes.Contains(it.Type));
                        break;
                    }
                    // todo(chris) add back in when we implement penetration
                    // else
                    // {
                    //     var targetOccupants = node.Occupants.Where(it => TargetTypes.Contains(it.Type));
                    //
                    //     var gridOccupants = targetOccupants as GridOccupant[] ?? targetOccupants.ToArray();
                    //
                    //     // occupant isnt a target so cant go through
                    //     if (gridOccupants.Length == 0)
                    //     {
                    //         break;
                    //     }
                    //
                    //     path.Hits.Add(node);
                    //
                    //     var penetrating = gridOccupants.Where(occupant => projectile.PenitrationTags.Contains(occupant.Type));
                    //
                    //     var penetratingArray = penetrating as GridOccupant[] ?? penetrating.ToArray();
                    //
                    //     // cant penetrate target to this will be as far as we go
                    //     if (penetratingArray.Length == 0)
                    //     {
                    //         break;
                    //     }
                    //
                    //     // if we cant penetrate all then we are done
                    //     if (remainingDepth <= penetratingArray.Length)
                    //     {
                    //         break;
                    //     }
                    //
                    //    // continue;
                    // }
                }
                else
                {
                    break;
                }
            }

            if (path.IsLastNodeTarget && path.Travelled.Count == 0)
            {
                path = new PathDetails
                {
                    Travelled        = new List <Grid.Grid.Node>(),
                    IsLastNodeTarget = false
                };
            }
            else
            {
                path.Travelled.RemoveAt(0);
            }

            return(path);
        }
Beispiel #11
0
        private bool QueueActions(Vector3 position)
        {
            Grid.Grid.Node clickedNode        = new Grid.Grid.Node();
            var            isClickedNodeValid = _unit.Occupant.Grid.TryGetNodeAtWorldPosition(position, ref clickedNode);


            Grid.Grid.Node myNode        = new Grid.Grid.Node();
            var            isMyNodeValid = _unit.Occupant.Grid.TryGetNodeAtWorldPosition(transform.position, ref myNode);

            if (isMyNodeValid && isClickedNodeValid)
            {
                if (_isUsingBomb)
                {
                    if (_inventory == null)
                    {
                        return(false);
                    }

                    var diff = clickedNode.Position - myNode.Position;
                    if (!diff.IsCardinal())
                    {
                        return(false);
                    }

                    AggregateSlot slot;
                    if (!_inventory.RetrieveSlot(bombKey, out slot))
                    {
                        return(false);
                    }

                    slot.Total -= 1;

                    _inventory.UpdateSlot(bombKey, slot);

                    _unit.QueueRange(bombChucker.Use(_unit.Occupant.Occupant, diff, _unit.Occupant.Grid));

                    return(true);
                }
                else if (_isUsingItem)
                {
                    if (_item != null)
                    {
                        var direction = clickedNode.Position - _unit.Occupant.Occupant.Position;
                        var actions   = _item.Use(_unit.Occupant.Occupant, direction, _unit.Occupant.Grid);

                        if (actions != null && actions.Count > 0)
                        {
                            _unit.QueueRange(actions);
                            return(true);
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    // attack
                    var direction = clickedNode.Position - _unit.Occupant.Occupant.Position;
                    var targets   = mainWeapon.FindTargets(_unit.Occupant.Occupant, direction, _unit.Occupant.Grid);

                    if (Array.Exists(targets, it => it.Position == clickedNode.Position))
                    {
                        var actions = mainWeapon.Use(_unit.Occupant.Occupant, direction, _unit.Occupant.Grid);

                        if (actions != null && actions.Count > 0)
                        {
                            _unit.QueueRange(actions);
                            return(true);
                        }
                    }


                    // move
                    var path = _pathfinding.CalculatePath(transform.position, position);

                    if (path != null && path.Count > 0)
                    {
                        var first = path[0];

                        _unit.QueueAction(new MoveToPointAction(_unit, first));
                        return(true);
                    }
                }
            }

            return(false);
        }
Beispiel #12
0
 public LaunchProjectileAction(GridOccupant wielder, Grid.Grid.Node endPoint, ProjectileBehaviour projectile)
 {
     _wielder    = wielder;
     _endPoint   = endPoint;
     _projectile = projectile;
 }
Beispiel #13
0
        public override List <IUnitAction> Handle(PushWeaponEffect effect, GameObject wielder)
        {
            var actions = new List <IUnitAction>();

            Vector2Int direction = GetPush(effect, wielder);

            if (direction == Vector2Int.zero)
            {
                Debug.Log($"{wielder.name} Tried To Push {name} (0, 0)!!");

                return(actions);
            }

            var pos = _occupant.CurrentNodeIdx + direction;

            var node = new Grid.Grid.Node();

            if (_occupant.Get().Value.TryGetNodeAt(pos.x, pos.y, ref node))
            {
                // todo(chris) this doesnt really work with anything that isnt just in 1 direction
                actions.Add(new MoveToPointAction(_unit, node, twoWayCollisions: true));
            }

            return(actions);

            // Vector2Int magnitudes = new Vector2Int(Mathf.Abs(direction.x), Mathf.Abs(direction.y));
            // Vector2Int signs = new Vector2Int(Math.Sign(direction.x), Math.Sign(direction.y));
            //
            // var pos = _occupant.CurrentNodeIdx;
            //
            // var step = Vector2Int.one;
            //
            // // step along push path one by one (including diagonals as 1)
            // // until we either collide with something or reach our final destination
            // while (magnitudes != Vector2Int.zero)
            // {
            //     if (magnitudes.x < 1)
            //     {
            //         step.x = 0;
            //     }
            //
            //     if (magnitudes.y < 1)
            //     {
            //         step.y = 0;
            //     }
            //
            //     magnitudes.x = Mathf.Max(0, magnitudes.x - 1);
            //     magnitudes.y = Mathf.Max(0, magnitudes.y - 1);
            //
            //     var next = pos + signs * step;
            //
            //
            //     var n = new Grid.Grid.Node();
            //     if (_occupant.Get().Value.TryGetNodeAt(next.x, next.y, ref n))
            //     {
            //         var collider = n.Occupants.FirstOrDefault(ItObstructsMe);
            //         if (collider != null)
            //         {
            //             ResolveCollision(actions, collider, n);
            //
            //             break;
            //         }
            //     }
            //
            //     pos = next;
            // }
            //
            //
            // var node = new Grid.Grid.Node();
            // if (_occupant.Get().Value.TryGetNodeAt(pos.x, pos.y, ref node))
            // {
            //     // todo(chris) this doesnt really work with anything that isnt just in 1 direction
            //     actions.Add(new MoveToPointAction(_unit, node));
            // }
            //
            // return actions;
        }
Beispiel #14
0
        private void ResolveCollision(List <IUnitAction> actions, GridOccupant collider, Grid.Grid.Node n)
        {
            // if i have on collision effects then run them
            actions.AddNullableRange(_collisionBehaviour?.CollideWith(collider, n));


            // if the thing i bumped has collision effects then run them
            var collision = collider.OccupantGameObject.GetComponent <OnCollisionBehaviour>();

            if (collision != null)
            {
                var myNode = _occupant.CurrentNode;
                if (myNode != null)
                {
                    actions.AddNullableRange(collision.CollideWith(_occupant.Occupant, myNode.Value));
                }
            }
        }