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); } }
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); } }
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()); }
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)); } } }
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 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); }
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); }
// 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); }
public abstract bool CanTarget(GridOccupant target, GridOccupant wielder, Grid.Grid grid);
public override List <GridOccupant> FindAllPossibleTargets(GridOccupant wielder, Grid.Grid grid) { return(FindTargets(wielder, Vector2Int.down, grid).ToList()); }
public override List <Grid.Grid.Node> FindEffectedNodes(GridOccupant wielder, Vector2Int direction, Grid.Grid grid) { return(CalculatePath(wielder, direction, grid).Travelled); }
public override bool CanTarget(GridOccupant target, GridOccupant wielder, Grid.Grid grid) { var path = CalculatePath(wielder, target.Position - wielder.Position, grid); return(path.IsLastNodeTarget); }
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); }
public LaunchProjectileAction(GridOccupant wielder, Grid.Grid.Node endPoint, ProjectileBehaviour projectile) { _wielder = wielder; _endPoint = endPoint; _projectile = projectile; }
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); }
// 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);
public override List <Grid.Grid.Node> FindAllPossibleEffectedNodes(GridOccupant wielder, Grid.Grid grid) { return(FindEffectedNodes(wielder, Vector2Int.down, grid)); }
private bool ItObstructsMe(GridOccupant occupant) { return(occupant.Cost < 0); }