Beispiel #1
0
    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();
        }
    }