Beispiel #1
0
    // Store information on whether each red unit is carrying a civilian or not
    void updateRedUnitDatabase()
    {
        // Clear
        redUnitDatabase.Clear();

        // Get all red units
        redUnits = new List <GameObject>();
        redUnits.AddRange(GameObject.FindGameObjectsWithTag("RedTruck"));
        redUnits.AddRange(GameObject.FindGameObjectsWithTag("RedDismount"));

        // Loop through all actor beliefs and update the database
        foreach (Belief_Actor b in actorBeliefs)
        {
            // We care only about red units
            Belief_Actor ba = (Belief_Actor)b;

            if (ba.getAffiliation().Equals((int)Affiliation.RED))
            {
                // Save the info if the belief is new enough
                // Note: Watch out for the difference of two unsigned numbers!
                if (thisSoaActor.getCurrentTime_ms() <= ba.getBeliefTime() ||
                    (float)(thisSoaActor.getCurrentTime_ms() - ba.getBeliefTime()) <= beliefTimeout_ms)
                {
                    RedUnitInfo redUnitInfo = new RedUnitInfo(ba, redUnits, redBases, protectedSites);
                    if (redUnitInfo.distToClosestRedBase > redBaseKeepoutDist * SimControl.KmToUnity)
                    {
                        redUnitDatabase.Add(ba.getId(), new RedUnitInfo(ba, redUnits, redBases, protectedSites));
                    }
                }
            }
        }
    }
Beispiel #2
0
    // Keeps track of a pursue list (really map) with hysterisis distances to closest base as condition
    // for being added/removed from map.  Each key is an actor ID for a red unit and the value is the
    // updated distance to closest base
    void markPursueCandidates()
    {
        // Look at each red unit in the database and determine if it should be a candidate to be pursued
        foreach (int id in redUnitDatabase.Keys)
        {
            // Get the record
            RedUnitInfo redUnitInfo = redUnitDatabase[id];

            // Estimate how long it takes for me to get there
            float myTravelTime = GetRangeTo(redUnitInfo.closestRedBasePos) / thisNavAgent.speed;

            // Estimate red unit round trip time
            float redRoundTripTime;
            if (redUnitInfo.hasCivilian)
            {
                // Guess that it is going straight to closest base
                redRoundTripTime = redUnitInfo.distToClosestRedBase / redUnitInfo.maxSpeed;

                // Determine if I can get it before it returns to base (include some inefficiencies)
                if (myTravelTime < redRoundTripTime)
                {
                    // Mark as someone who can be caught in time
                    redUnitInfo.isCatchable = true;
                }
            }
            else
            {
                if (redUnitInfo.distToClosestRedBase > redBaseKeepoutDist * SimControl.KmToUnity)
                {
                    // Guess that it will first go to closest protected site and then to closest base
                    redRoundTripTime = (redUnitInfo.distToClosestProtectedSite +
                                        Vector3.Distance(redUnitInfo.closestProtectedSitePos, redUnitInfo.closestRedBasePos))
                                       / redUnitInfo.maxSpeed;

                    // Determine if I can get it before it returns to base (include some inefficiencies)
                    if (myTravelTime < redRoundTripTime)
                    {
                        // Mark as someone who can be caught in time
                        redUnitInfo.isCatchable = true;
                    }
                }
            }
        }
    }
Beispiel #3
0
    // Assigns a task to current police unit based on the pursueList
    public void assignTask()
    {
        if (redUnitDatabase.Keys.Count == 0)
        {
            // Transition from pursue to patrol
            if (currTask != Task.PATROL)
            {
                // Pick a new patrol target
                currTask     = Task.PATROL;
                patrolTarget = assignNewProtectedSite(patrolTarget);
            }
            else if (Vector3.Distance(transform.position, patrolTarget.transform.position) <= clearPatrolRange * SimControl.KmToUnity)
            {
                // We are close enough to a target to clear it, choose to stay or leave with some probability
                if (Random.value <= transitionProbability)
                {
                    patrolTarget = assignNewProtectedSite(patrolTarget);
                }
                else
                {
                    // We choose to stay here for another update, keep the same task
                }
            }
            else
            {
                // We are patrolling but have not gotten to target yet, keep the same task
            }
        }
        else
        {
            // Set intent to pursue
            currTask = Task.PURSUE;

            // Create 4 lists for determining who to chase after
            List <int> isCatchableHasCivilian  = new List <int>();
            List <int> isCatchableNoCivilian   = new List <int>();
            List <int> notCatchableHasCivilian = new List <int>();
            List <int> notCatchableNoCivilian  = new List <int>();

            // Pick a pursuit candidate with civilian to pursue
            float minCost = float.PositiveInfinity;

            // Categorize the candidates
            foreach (int id in redUnitDatabase.Keys)
            {
                // Get the record
                RedUnitInfo redUnitInfo = redUnitDatabase[id];

                if (redUnitInfo.isCatchable && redUnitInfo.hasCivilian)
                {
                    isCatchableHasCivilian.Add(id);
                }
                else if (redUnitInfo.isCatchable && !redUnitInfo.hasCivilian)
                {
                    isCatchableNoCivilian.Add(id);
                }
                else if (!redUnitInfo.isCatchable && redUnitInfo.hasCivilian)
                {
                    notCatchableHasCivilian.Add(id);
                }
                else
                {
                    notCatchableNoCivilian.Add(id);
                }
            }

            // Find the pursuit target based on priority and min cost
            if (isCatchableHasCivilian.Count != 0)
            {
                // First priority: is catchable and has civilian
                foreach (int id in isCatchableHasCivilian)
                {
                    float actorCost = GetRangeTo(redUnitDatabase[id].pos);
                    if (actorCost < minCost)
                    {
                        minCost       = actorCost;
                        pursueActorID = id;
                    }
                }
            }
            if (float.IsInfinity(minCost) && isCatchableNoCivilian.Count != 0)
            {
                // Second priority: is catchable but no civilian
                foreach (int id in isCatchableNoCivilian)
                {
                    float actorCost = GetRangeTo(redUnitDatabase[id].pos);
                    if (actorCost < minCost)
                    {
                        minCost       = actorCost;
                        pursueActorID = id;
                    }
                }
            }
            if (float.IsInfinity(minCost) && notCatchableHasCivilian.Count != 0)
            {
                // Third priority: not catchable but has civilian
                foreach (int id in notCatchableHasCivilian)
                {
                    float actorCost = GetRangeTo(redUnitDatabase[id].pos);
                    if (actorCost < minCost)
                    {
                        minCost       = actorCost;
                        pursueActorID = id;
                    }
                }
            }
            if (float.IsInfinity(minCost) && notCatchableNoCivilian.Count != 0)
            {
                // Last priority: not catchable and no civilian
                foreach (int id in notCatchableNoCivilian)
                {
                    float actorCost = GetRangeTo(redUnitDatabase[id].pos);
                    if (actorCost < minCost)
                    {
                        minCost       = actorCost;
                        pursueActorID = id;
                    }
                }
            }
        }
    }