Ejemplo n.º 1
0
    /// <summary>
    /// Object initialization
    /// </summary>
    public override void Awake()
    {
        _info = Info.get.of(race, type);
        _auto = this;
        Troop = null;

        // Call GameEntity awake
        base.Awake();

        // Get DetourAgent and set basic variables
        _detourAgent = GetComponent <DetourAgent>();
    }
Ejemplo n.º 2
0
        public override void controlUnits(Squad squad)
        {
            if (!isEnabled || squad.Units.Count == 0)
            {
                return;
            }

            if (squad.Units[0].type == Storage.UnitTypes.HERO && squad.Units.Count == 1 && Time.time > HERO_GO_TO_BASE && !destinatedToBase)
            {
                squad.Units[0].moveTo(new Vector3(ai.rootBasePosition.x + 30f, ai.rootBasePosition.y, ai.rootBasePosition.z + 10f));
                this.destinatedToBase = true;
                return;
            }

            if (squad.Units[0].type == Storage.UnitTypes.HERO && destinatedToBase)
            {
                return;
            }

            // Update squads exploring
            ++numberSquadsExploring;

            if (fowManager.Enabled)
            {
                bool lostHero = (heroLastPos != Vector3.zero && !heroVisible);

                // Static values
                FOWManager.visible[] grid = fowManager.aiVision;
                Vector2 gridSize          = fowManager.getGridSize();

                // Get a random unit as a reference point
                Unit        reference = squad.Units[D6.get.rollN(squad.Units.Count)];
                DetourAgent agent     = reference.Agent;

                if (agent.TargetState == DetourAgent.MoveRequestState.DT_CROWDAGENT_TARGET_REQUESTING ||
                    agent.TargetState == DetourAgent.MoveRequestState.DT_CROWDAGENT_TARGET_WAITING_FOR_PATH ||
                    agent.TargetState == DetourAgent.MoveRequestState.DT_CROWDAGENT_TARGET_WAITING_FOR_QUEUE)
                {
                    return;
                }

                // Check if target is already explored
                Vector3 direction = (agent.TargetPoint - reference.transform.position).normalized;
                // Set the further point as the targetPoint + sighRange - offset
                Vector3 targetFOWPos = agent.TargetPoint + direction * (reference.info.attributes.sightRange - RescheduleSightRange);
                Vector2 targetGrid   = fowManager.CoordtoGrid(targetFOWPos);
                // Check grid status
                bool targetExplored = ((FOWManager.visible.explored & grid[(int)(targetGrid.x + targetGrid.y * gridSize.y)]) == FOWManager.visible.explored);

                // If we are moving to a not seen target, don't reschedule at first, otherwise go to a random position in a circle around current position
                RescheduleType reschedule = RescheduleType.RANDOM_IN_CURRENT_POSITION;
                if (targetExplored && agent.IsMoving)
                {
                    reschedule = RescheduleType.RANDOM_IN_DIRECTION;
                }
                else if (agent.IsMoving)
                {
                    reschedule = RescheduleType.NONE;
                }

                // Throw a dice
                int diceValue = D6.get.rollN(ReschuduleDiceFaces);
                if (diceValue >= RescheduleRandomPointValue)
                {
                    // Change target point taking into account current direction (but not distance!)
                    reschedule = RescheduleType.RANDOM_IN_DIRECTION;
                }
                else if (diceValue >= RescheduleRandomAroundTargetValue && knownPositions.Count > 0)
                {
                    reschedule = RescheduleType.RANDOM_AROUND_TARGET;
                }
                else if (diceValue >= RescheduleRandomDirectionValue)
                {
                    // Change target point taking into account distance (but not direction!)
                    // Do note that direction is implicitelly taken into account because FOWManager reports
                    // some areas as explored
                    reschedule = RescheduleType.RANDOM_IN_CURRENT_TARGET;
                }

                // If we are moving and we don't have to reschedule, skip this squad
                if (agent.IsMoving && !targetExplored && reschedule == RescheduleType.NONE)
                {
                    return;
                }

                // If we've lost the hero, seek it with the closer unit, regardless of what FOWManager tells us
                if (lostHero)
                {
                    float dist = (reference.transform.position - heroLastPos).sqrMagnitude;
                    if (dist < reference.info.attributes.sightRange) // Nota, aixo implica "distancia_actual < sqrt(sightRange)"
                    {
                        heroLastPos = Vector3.zero;
                        lostHero    = false;
                    }
                }

                // Switch to current reschedule type and find a target point
                bool result = false;
                switch (reschedule)
                {
                case RescheduleType.NONE:
                    return;

                case RescheduleType.RANDOM_IN_DIRECTION:
                    result = findPlaceToExplore(grid, gridSize, out targetPos, true, reference.transform.position, agent.TargetPoint);
                    break;

                case RescheduleType.RANDOM_IN_CURRENT_TARGET:
                    result = findPlaceToExplore(grid, gridSize, out targetPos, agent.TargetPoint, 25f);
                    break;

                case RescheduleType.RANDOM_IN_CURRENT_POSITION:
                    result = findPlaceToExplore(grid, gridSize, out targetPos, reference.transform.position, 75f);
                    break;

                case RescheduleType.RANDOM_AROUND_TARGET:
                    result = findPlaceToExplore(grid, gridSize, out targetPos, knownPositions[D6.get.rollN(knownPositions.Count)], 5f);
                    break;
                }

                // If we failed to find a valid target and we are not moving (thus we are IDLE), find a random point along all the map
                if (!result && (!agent.IsMoving || targetExplored))
                {
                    result = findPlaceToExplore(fowManager.aiVision, fowManager.getGridSize(), out targetPos);
                }

                if (!result)
                {
                    return;
                }

                if (lostHero)
                {
                    squad.MoveTo(heroLastPos, u =>
                    {
                        if (AIController.AI_DEBUG_ENABLED)
                        {
                            ai.aiDebug.registerDebugInfoAboutUnit(u, agentName);
                        }
                    });
                }
                else
                {
                    targetPos.y = terrain.SampleHeight(targetPos);
                    squad.MoveTo(targetPos, u =>
                    {
                        if (AIController.AI_DEBUG_ENABLED)
                        {
                            ai.aiDebug.registerDebugInfoAboutUnit(u, agentName);
                        }
                    });
                }
            }
        }