Ability[] GetAbilities(params int[] IDs) { return(craft.GetAbilities().Where((x) => { return (x != null) && IDs.Contains(x.GetID()); }).ToArray()); }
private void Update() { if (!craft.GetIsDead()) { // find target Entity target = getNearestEntity <Entity>(craft.transform.position, craft.faction, true, craft.Terrain); craft.GetTargetingSystem().SetTarget(target ? target.transform : null); foreach (Ability a in craft.GetAbilities()) { if (a) { a.Tick(0); } } // shouldn't tick if dead or in cutscene, give control to the cutscene if (aggression != AIAggression.KeepMoving && aggroSearchTimer < Time.time && !DialogueSystem.isInCutscene) { // stop or follow target, give up if it's outside range if (target && (target.transform.position - craft.transform.position).sqrMagnitude < 800f) { aggroTarget = target; //Debug.Log("AggroTarget: " + aggroTarget.name + " Factions: " + aggroTarget.faction + " - " + craft.faction); } aggroSearchTimer = Time.time + 1f; } // shouldn't tick if dead or in cutscene, give control to the cutscene if (aggroTarget && !FactionManager.IsAllied(aggroTarget.faction, craft.faction) && !DialogueSystem.isInCutscene) { if (aggroTarget.GetIsDead() || aggroTarget.IsInvisible) { aggroTarget = null; aggroSearchTimer = 0f; } else { // if(craft as Drone && Input.GetKey(KeyCode.D)) Debug.Log(aggroTarget); switch (aggression) { case AIAggression.FollowInRange: var aggroPos = aggroTarget.transform.position; if (timer >= 0.3F) { timer = 0; movement.SetMoveTarget(aggroPos + new Vector3(Random.Range(-1F, 1F), Random.Range(-1F, 1F)), 9); } else { timer += Time.deltaTime; } float dist = movement.DistanceToTarget; if (dist > 1000f) { aggroTarget = null; } if (module is FollowAI && (module as FollowAI).followTarget) { if (((module as FollowAI).followTarget.position - craft.transform.position).sqrMagnitude > 150f) { aggroTarget = null; } } //// Stealth if module is not BattleAI to not interfere with it //if (!(module is BattleAI) && craft.GetHealth()[0] < craft.GetMaxHealth()[0] * 0.25f) //{ // var abilities = craft.GetAbilities(); // if(abilities != null) // { // var stealths = abilities.Where((x) => { return (x != null) && x.GetID() == 24; }); // foreach (var stealth in stealths) // { // stealth.Tick("activate"); // if (stealth.GetActiveTimeRemaining() > 0) // break; // } // } //} break; case AIAggression.StopToAttack: movement.SetMoveTarget(craft.transform.position); break; case AIAggression.KeepMoving: // Back to module's movement aggroTarget = null; break; default: break; } } } else { aggroTarget = null; aggroSearchTimer = 0f; } if (module != null) { if (state == AIState.Active) { module.StateTick(); if (aggroTarget == null) { module.ActionTick(); } if (allowRetreat) { // check if retreat necessary if (craft.GetHealth()[0] < retreatTreshold * craft.GetMaxHealth()[0]) { state = AIState.Retreating; //Debug.Log(craft.name + "[ " + craft.faction + " ] retreating!"); } } } else if (state == AIState.Retreating) { if ((!retreatTargetFound && retreatSearchTimer < Time.time) || retreatSearchTimer < Time.time) { Entity enemy = getNearestEntity <Entity>(craft.transform.position, craft.faction, true, Entity.TerrainType.All); if (enemy && (enemy.transform.position - craft.transform.position).sqrMagnitude < 1600f) { retreatTarget = craft.transform.position + (craft.transform.position - enemy.transform.position).normalized * 20f; //Debug.Log(craft.name + "[ " + craft.faction + " ] Initial retreat target : " + retreatTarget); IntRect bounds = SectorManager.instance.current.bounds; if (!bounds.contains(retreatTarget)) { retreatTarget = craft.spawnPoint; //Debug.Log(craft.name + "[ " + craft.faction + " ] Updated to Spawn point : " + retreatTarget); } // stay inside sector (just in case the spawn point is outside) if (retreatTarget.x > bounds.x + bounds.w) { retreatTarget = new Vector2(bounds.x + bounds.w, retreatTarget.y); } if (retreatTarget.x < bounds.x) { retreatTarget = new Vector2(bounds.x, retreatTarget.y); } if (retreatTarget.y < bounds.y - bounds.h) { retreatTarget = new Vector2(retreatTarget.x, bounds.y - bounds.h); } if (retreatTarget.y > bounds.y) { retreatTarget = new Vector2(retreatTarget.x, bounds.y); } retreatTargetFound = true; //Debug.Log(craft.name + "[ " + craft.faction + " ] Sector bounds: " + bounds.x + ", " + bounds.y + ", " + bounds.w + ", " + bounds.h); //Debug.Log(craft.name + "[ " + craft.faction + " ] Found a retreat target! : " + retreatTarget); } else { retreatTarget = craft.spawnPoint; retreatTargetFound = true; } retreatSearchTimer = Time.time + 3.0f; } else if (retreatTargetFound) { movement.SetMoveTarget(retreatTarget); if (movement.targetIsInRange() && retreatTarget != (Vector2)craft.spawnPoint) { retreatSearchTimer = 0f; } } else { movement.SetMoveTarget(craft.spawnPoint); } // check if retreating is still necessary if (craft.GetHealth()[0] > retreatTreshold * craft.GetMaxHealth()[0]) { state = AIState.Active; //Debug.Log(craft.name + "[ " + craft.faction + " ] stopped retreating!"); } } else { if (state == AIState.Inactive) { module.Init(); state = AIState.Active; } } } //else //{ // state = AIState.Inactive; //} movement.Update(); abilityControl.Update(); } }