示例#1
0
        public override List <IUnitAction> Use(GridOccupant wielder, Vector2Int direction, Grid.Grid grid)
        {
            var path = CalculatePath(wielder, direction, grid);

            if (path.Travelled.Count == 0)
            {
                return(null);
            }
            var endPoint = path.Travelled.Last();

            var outOfAmmo       = true;
            var spawnProjectile = true;

            var inventory = wielder.OccupantGameObject.GetComponent <IProvider <Inventory> >()?.Get();

            if (inventory != null)
            {
                if (initialAmmunition != null)
                {
                    AggregateSlot ammuntion;
                    if (inventory.RetrieveSlot(initialAmmunition.Key, out ammuntion))
                    {
                        if (ammuntion.Total < 1)
                        {
                            outOfAmmo       = true;
                            spawnProjectile = false;
                        }
                        else if (ammuntion.Total == 1)
                        {
                            outOfAmmo       = true;
                            spawnProjectile = true;
                        }
                        else
                        {
                            ammuntion.Total--;
                            inventory.UpdateSlot(initialAmmunition.Key, ammuntion);
                            spawnProjectile = true;
                            outOfAmmo       = false;
                        }
                    }
                }

                if (outOfAmmo && unequipWhenOutOfAmmo)
                {
                    inventory.RemoveWeaponSlot(_weaponKey);
                }
            }

            if (spawnProjectile)
            {
                return(new List <IUnitAction> {
                    new LaunchProjectileAction(wielder, endPoint, projectile)
                });
            }
            else
            {
                return(null);
            }
        }
示例#2
0
        public virtual List <Grid.Grid.Node> FindAllPossibleEffectedNodes(GridOccupant wielder, Grid.Grid grid)
        {
            var occupants = new List <Grid.Grid.Node>();

            occupants.AddNullableRange(FindEffectedNodes(wielder, Vector2Int.up, grid));
            occupants.AddNullableRange(FindEffectedNodes(wielder, Vector2Int.down, grid));
            occupants.AddNullableRange(FindEffectedNodes(wielder, Vector2Int.left, grid));
            occupants.AddNullableRange(FindEffectedNodes(wielder, Vector2Int.right, grid));

            return(occupants);
        }
 public List <IUnitAction> CollideWith(GridOccupant other, Grid.Grid.Node otherNode)
 {
     // if I hurt things on collision then hurt them
     if (OnCollisionEffects?.CanTarget(other, _occupant.Occupant, _occupant.Grid) == true)
     {
         var diff = new Vector2Int(otherNode.X, otherNode.Y) - _occupant.CurrentNodeIdx;
         return(OnCollisionEffects.Use(_occupant.Occupant, diff, _occupant.Grid));
     }
     else
     {
         return(null);
     }
 }
示例#4
0
        public override GridOccupant[] FindTargets(GridOccupant wielder, Vector2Int direction, Grid.Grid grid)
        {
            var path = CalculatePath(wielder, direction, grid);

            if (!path.IsLastNodeTarget)
            {
                return(null);
            }

            var targets = path.Travelled.Last().Occupants.Where(it => TargetTypes.Contains(it.Type));

            return(targets as GridOccupant[] ?? targets.ToArray());
        }
示例#5
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));
                }
            }
        }
示例#6
0
        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);
        }
示例#7
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);
        }
示例#8
0
        public virtual List <IUnitAction> Use(GridOccupant wielder, Vector2Int direction, Grid.Grid grid)
        {
            var actions = new List <IUnitAction>();

            var targets = FindTargets(wielder, direction, grid);

            foreach (var occupant in targets)
            {
                if (occupant != wielder || EffectSelf)
                {
                    foreach (var effect in Effects)
                    {
                        var r = effect.Apply(occupant.OccupantGameObject, wielder.OccupantGameObject);
                        actions.AddNullableRange(r);
                    }
                }
            }

            return(actions);
        }
示例#9
0
        // 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);
        }
示例#10
0
 public abstract bool CanTarget(GridOccupant target, GridOccupant wielder, Grid.Grid grid);
示例#11
0
 public override List <GridOccupant> FindAllPossibleTargets(GridOccupant wielder, Grid.Grid grid)
 {
     return(FindTargets(wielder, Vector2Int.down, grid).ToList());
 }
示例#12
0
 public override List <Grid.Grid.Node> FindEffectedNodes(GridOccupant wielder, Vector2Int direction, Grid.Grid grid)
 {
     return(CalculatePath(wielder, direction, grid).Travelled);
 }
示例#13
0
        public override bool CanTarget(GridOccupant target, GridOccupant wielder, Grid.Grid grid)
        {
            var path = CalculatePath(wielder, target.Position - wielder.Position, grid);

            return(path.IsLastNodeTarget);
        }
示例#14
0
        public override bool CanTarget(GridOccupant target, GridOccupant wielder, Grid.Grid grid)
        {
            var targets = FindTargets(wielder, target.Position - wielder.Position, grid);

            return(Array.IndexOf(targets, target) > -1);
        }
示例#15
0
 public LaunchProjectileAction(GridOccupant wielder, Grid.Grid.Node endPoint, ProjectileBehaviour projectile)
 {
     _wielder    = wielder;
     _endPoint   = endPoint;
     _projectile = projectile;
 }
示例#16
0
        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);
        }
示例#17
0
        // public abstract Grid.Grid.Node[] FindTargets(Grid.Grid.Node wielder, Grid.Grid grid);
        //
        // public virtual List<IUnitAction> Apply(Grid.Grid.Node target, GameObject wielder)
        // {
        //     var actions = new List<IUnitAction>();
        //     foreach (var occupant in target.Occupants)
        //     {
        //         if (occupant.OccupantGameObject != wielder || EffectSelf)
        //         {
        //             foreach (var effect in Effects)
        //             {
        //                 var r = effect.Apply(occupant.OccupantGameObject, wielder);
        //                 actions.AddNullableRange(r);
        //             }
        //         }
        //     }
        //
        //     return actions;
        // }

        public abstract GridOccupant[] FindTargets(GridOccupant wielder, Vector2Int direction, Grid.Grid grid);
示例#18
0
 public override List <Grid.Grid.Node> FindAllPossibleEffectedNodes(GridOccupant wielder, Grid.Grid grid)
 {
     return(FindEffectedNodes(wielder, Vector2Int.down, grid));
 }
示例#19
0
 private bool ItObstructsMe(GridOccupant occupant)
 {
     return(occupant.Cost < 0);
 }