public override bool Do(Model model, Entity e) { if (data is null) { data = ResourceLoader.Load <ReachAttackData>("res://Crawler/Model/Attacks/ReachAttacks/Poke.tres"); } GD.Print(data.ResourceName); (int x, int y)targetPos = GetTargetPos(e.position); if (data.startup > 0) { model.CoolerApiEvent(e.id, "AttackStartup", new Vector2(targetPos.x, targetPos.y)); } e.nextMove += data.startup; e.queuedAction = new ReachAttackActive(data).SetTarget(targetPos); return(true); }
public ReachAttackAction(ReachAttackData data) { this.data = data ?? ResourceLoader.Load <ReachAttackData>("res://Crawler/Model/Attacks/ReachAttacks/VeryPositive.tres"); }
// not sure if this is the right access modifier. internal ReachAttackActive(ReachAttackData data) { this.data = data; }
public override Action GetMove(Model model, Entity e) { List<Entity> entities = model.GetEntitiesInRadius(e.position, 6); List<(int, int)> enemyPositions = new List<(int, int)>(); List<(int, int)> allyPositions = new List<(int, int)>(); foreach (Entity other in entities) { if (other.downed) { continue; } if (other == e) { continue; } if (other.team == e.team) { allyPositions.Add(other.position); } else { if (GridHelper.Distance(e.position, other.position) <= 4) { enemyPositions.Add(other.position); } } } // Attack the closest enemy. int closestDistance = 100; foreach((int, int) pos in enemyPositions) { int distance = GridHelper.Distance(e.position, pos); if (distance <= closestDistance) { closestDistance = distance; } } if (closestDistance <= 1 && e.species.rushAttack != null) { // Attack an enemy in melee range // TODO: randomly walk away. foreach((int, int) pos in enemyPositions) { if (GridHelper.Distance(e.position, pos) <= 1.5f) { return new RushAttackAction().SetTarget(pos); } } } else { // get reach attacks in range. for (int i = 0; i < e.species.attacks.Count; i++) { ReachAttackData data = e.species.attacks[i]; if (closestDistance <= data.range) { foreach ((int, int) pos in enemyPositions) { if (GridHelper.Distance(e.position, pos) == closestDistance) { return new ReachAttackAction(data).SetTarget(pos); } } } } // Select a move and try to attack an enemy in range. // AttackData bestAttack = e.species.bumpAttack; // float bestRangeMax = 1.5f; // foreach ((int, int) pos in enemyPositions) // { // float distance = GridHelper.Distance(e.position, pos); // if (distance <= bestRangeMax) // { // return new AttackAction().SetTarget(pos); // } // } } // Move towards enemies. // Pathfinding should be cheap since the paths are short and probably straight lines. // PathFinder.PathResult result = PathFinder.ShortestPathToMany(e.position, enemyPositions, Walkable(api)); PathFinder.PathResult result = PathFinder.ShortestPathToMany(e.position, enemyPositions, Walkable(model, e)); if (result.success) { return new MoveAction().SetTarget(result.nextStep); } // low priority todo: big clumps of ai. result = PathFinder.ShortestPathToMany(e.position, allyPositions, WalkThroughAllies(model)); if (result.success) { if (result.steps > 2.5f) { return new MoveAction().SetTarget(result.nextStep); } return new MoveAction().SetTarget(e.position); } return new MoveAction().SetTarget(e.position); }