protected virtual void Signalling() { signalTimer -= Time.deltaTime; if (signalTimer <= 0f) { for (int i = 0; i < hive.childBots.Count; i++) { GatherBot sibling = hive.childBots[i]; sibling.enemies = enemies; if (IsInCombat) { sibling.SetState(AIState.Escaping); } else { sibling.SetState(AIState.Attacking); } for (int j = 0; j < enemies.Count; j++) { ICombat enemy = enemies[j]; enemy.EngageInCombat(sibling); } } } }
protected virtual void AlertAll(ICombat threat) { for (int i = 0; i < hive?.childBots.Count; i++) { GatherBot sibling = hive.childBots[i]; sibling.AddThreat(threat); sibling.SetState(AIState.Attacking); } }
public override void DestroyedAnEntity(Entity target) { for (int i = 0; i < enemies.Count; i++) { if ((Entity)enemies[i] == target) { enemies[i].DisengageInCombat(this); enemies.RemoveAt(i); if (enemies.Count == 0) { for (int j = 0; j < hive?.childBots.Count; j++) { GatherBot bot = hive.childBots[j]; bot?.SetState(AIState.Collecting); } } return; } } }
protected virtual void Attacking() { if (enemies.Count == 0) { SetState(AIState.Collecting); } Vector2 currentPos = transform.position; //if sibling bots are nearby, get them to join the fight for (int i = 0; i < hive?.childBots.Count; i++) { GatherBot sibling = hive.childBots[i]; if (sibling.state == AIState.Attacking || sibling.state == AIState.Dying) { continue; } if (Vector2.Distance(currentPos, sibling.transform.position) < Constants.CHUNK_SIZE) { float scanAngle = -Vector2.SignedAngle(Vector2.up, (Vector2)sibling.transform.position - currentPos); StartCoroutine(ScanRings(scanAngle, 30f, false, 0.3f)); sibling.enemies = enemies; sibling.SetState(AIState.Attacking); } } //check if the target is too far away from this bot and its siblings targetEntity = (Entity)enemies[0]; Vector2 enemyPos = targetEntity.transform.position; bool found = SiblingsInRangeOfTarget(enemyPos); //if the target is out of range for too long then disengage from combat if (IncrementOutOfRangeCounter(found)) { return; } //bots attack by circling its target and firing float orbitAngle = Mathf.PI * 2f / (hive?.childBots.Count ?? 1) * dockID + Pause.timeSinceOpen * orbitSpeed; Vector2 orbitPos = new Vector2(Mathf.Sin(orbitAngle), Mathf.Cos(orbitAngle)) * orbitRange; float distanceFromTarget = Vector2.Distance(currentPos, enemyPos); Vector2 direction = enemyPos - currentPos; int count = Physics2D.RaycastNonAlloc(currentPos, direction, lineOfSight, distanceFromTarget); GoToLocation(enemyPos + orbitPos, count > 1, 0.2f, true, distanceFromTarget > firingRange ? null : (Vector2?)targetEntity.transform.position - transform.right); //fire will in range readyToFire = distanceFromTarget <= firingRange; if (readyToFire) { straightWeapon.aim = targetEntity.transform.position; } //run away if hp drops below 50% while also having lower health than the target if (!IsSwarmInCombat) { float hpRatio = healthComponent.CurrentRatio; if (hpRatio < 0.5f && hpRatio < targetEntity.HealthRatio) { scaryEntities.Add(targetEntity); SetState(AIState.Signalling); } } }