예제 #1
0
 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);
             }
         }
     }
 }
예제 #2
0
 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);
     }
 }
예제 #3
0
 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;
         }
     }
 }
예제 #4
0
    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);
            }
        }
    }