示例#1
0
 public void RemoveFact(WorkingMemoryFact fact)
 {
     if (fact != null)
     {
         Facts.Remove(fact);
     }
 }
示例#2
0
 public void BroadcastMemoryFact(WorkingMemoryFact fact)
 {
     foreach (Character member in Members)
     {
         member.MyAI.WorkingMemory.AddFact(fact);
     }
 }
示例#3
0
 public void AddFact(WorkingMemoryFact fact)
 {
     if (!Facts.Contains(fact))
     {
         Facts.Add(fact);
     }
 }
    public override bool ExecuteAction()
    {
        if (ParentCharacter.MyAI.BlackBoard.InvisibleEnemy == null)
        {
            return(false);
        }

        CsDebug.Inst.CharLog(ParentCharacter, "Start executing Mutant Search Enemy");

        ParentCharacter.MyAI.BlackBoard.NavTarget      = ParentCharacter.MyAI.BlackBoard.LastKnownEnemyPosition;
        ParentCharacter.MyAI.BlackBoard.IsNavTargetSet = true;

        WorkingMemoryFact fact   = ParentCharacter.MyAI.WorkingMemory.FindExistingFact(FactType.KnownEnemy, ParentCharacter.MyAI.BlackBoard.InvisibleEnemy);
        float             threat = fact.ThreatLevel;



        _searchDest      = ParentCharacter.MyAI.BlackBoard.NavTarget;
        _isSearchDestSet = true;
        ParentCharacter.CurrentStance = HumanStances.Run;


        ParentCharacter.MyAI.BlackBoard.GuardLevel = 2;


        _searchDuration = UnityEngine.Random.Range(20, 40);
        _searchTimer    = 0;

        UpdateAction();

        ParentCharacter.MyEventHandler.OnActionUpdateTimer -= UpdateAction;
        ParentCharacter.MyEventHandler.OnActionUpdateTimer += UpdateAction;

        return(true);
    }
示例#5
0
    public override bool ExecuteAction()
    {
        if (ParentCharacter.MyAI.BlackBoard.InvisibleEnemy == null)
        {
            return(false);
        }

        CsDebug.Inst.CharLog(ParentCharacter, "Start executing Search Enemy");

        ParentCharacter.MyAI.BlackBoard.NavTarget      = ParentCharacter.MyAI.BlackBoard.LastKnownEnemyPosition;
        ParentCharacter.MyAI.BlackBoard.IsNavTargetSet = true;

        WorkingMemoryFact fact   = ParentCharacter.MyAI.WorkingMemory.FindExistingFact(FactType.KnownEnemy, ParentCharacter.MyAI.BlackBoard.InvisibleEnemy);
        float             threat = fact.ThreatLevel;

        //if threat is low, just run towards last known location
        //if threat is high, keep aiming and go carefully towards a distance away from the last known location
        CsDebug.Inst.CharLog(ParentCharacter, "Action search enemy threat is " + threat);
        if (threat >= 0.66f)
        {
            Vector3 dist = ParentCharacter.MyAI.BlackBoard.InvisibleEnemy.transform.position - ParentCharacter.MyAI.BlackBoard.LastKnownEnemyPosition;

            _isSearchDestSet = SelectSearchDestination(ParentCharacter.MyAI.BlackBoard.LastKnownEnemyPosition + dist.normalized * -4, new Vector3(3, 3, 3), out _searchDest);



            ((HumanCharacter)ParentCharacter).CurrentStance = HumanStances.Walk;
        }
        else
        {
            _searchDest      = ParentCharacter.MyAI.BlackBoard.NavTarget;
            _isSearchDestSet = true;
            ParentCharacter.SendCommand(CharacterCommands.StopAim);
            ((HumanCharacter)ParentCharacter).CurrentStance = HumanStances.Run;
        }

        ParentCharacter.MyAI.BlackBoard.GuardLevel = 2;

        if (ParentCharacter.ActionState != HumanActionStates.SwitchWeapon && ParentCharacter.MyReference.CurrentWeapon == null)
        {
            ParentCharacter.SendCommand(CharacterCommands.SetAlert);
        }


        _searchDuration = UnityEngine.Random.Range(20, 40);
        _searchTimer    = 0;
        _nextTalkTime   = UnityEngine.Random.Range(3, 7);

        UpdateAction();

        ParentCharacter.MyEventHandler.OnActionUpdateTimer -= UpdateAction;
        ParentCharacter.MyEventHandler.OnActionUpdateTimer += UpdateAction;

        return(true);
    }
示例#6
0
    public bool CompareFact(WorkingMemoryFact fact1, WorkingMemoryFact fact2)
    {
        //returns true if the facts are the same
        // check if types and handle are same
        if(fact1.FactType == fact2.FactType && fact1.Target == fact2.Target)
        {
            return true;
        }

        return false;
    }
示例#7
0
    public WorkingMemoryFact AddFact(FactType type, object target, Vector3 lastKnownPos, float confidence, float dropRate)
    {
        WorkingMemoryFact fact = new WorkingMemoryFact();
        fact.Confidence = confidence;
        fact.ConfidenceDropRate = dropRate;
        fact.FactType = type;
        fact.Target = target;
        Facts.Add(fact);

        return fact;
    }
示例#8
0
    public bool CompareFact(WorkingMemoryFact fact1, WorkingMemoryFact fact2)
    {
        //returns true if the facts are the same
        // check if types and handle are same
        if (fact1.FactType == fact2.FactType && Object.Equals(fact1.Target, fact2.Target))
        {
            return(true);
        }

        return(false);
    }
示例#9
0
    public WorkingMemoryFact AddFact(FactType type, object target, Vector3 lastKnownPos, float confidence, float dropRate)
    {
        WorkingMemoryFact fact = new WorkingMemoryFact();

        fact.LastKnownPos       = lastKnownPos;
        fact.Confidence         = confidence;
        fact.ConfidenceDropRate = dropRate;
        fact.FactType           = type;
        fact.Target             = target;
        Facts.Add(fact);

        return(fact);
    }
示例#10
0
    public void RemoveFact(FactType type, object target)
    {
        WorkingMemoryFact fact = null;

        foreach (WorkingMemoryFact f in Facts)
        {
            if (f.FactType == type && Object.Equals(f.Target, target))
            {
                fact = f;
            }
        }
        if (fact != null)
        {
            Facts.Remove(fact);
        }
    }
示例#11
0
    public bool CheckActionViable(GoapAction action)
    {
        //check if working memory's list of failed actions
        WorkingMemoryFact fact = WorkingMemory.FindExistingFact(FactType.FailedAction, action.Name);

        if (fact != null)
        {
            //CsDebug.Inst.CharLog(_parentCharacter, "Determined action " + action.Name + " as not viable");
            return(false);
        }
        else
        {
            return(true);
        }

        return(true);
    }
示例#12
0
    private float CheckPersonalThreat(Character c)
    {
        //check if enemy is aiming at me. Add personal threat memory.
        if (c.MyReference.CurrentWeapon != null)
        {
            if (c.MyReference.CurrentWeapon.GetComponent <Weapon>().IsRanged)
            {
                float aimAngle = Vector3.Angle(_parentCharacter.transform.position - c.transform.position, c.MyReference.CurrentWeapon.transform.forward);
                if (aimAngle < 15)
                {
                    WorkingMemoryFact fact = _workingMemory.FindExistingFact(FactType.PersonalThreat, c);
                    if (fact == null)
                    {
                        fact                = _workingMemory.AddFact(FactType.PersonalThreat, c, c.transform.position, 1, 0.2f);
                        fact.ThreatLevel    = PersonalThreatLow;
                        fact.ThreatDropRate = 0.1f;
                    }
                    else
                    {
                        fact.Confidence = 1;
                        if (fact.ThreatLevel < PersonalThreatLow)
                        {
                            fact.ThreatLevel = PersonalThreatLow;
                        }
                        fact.LastKnownPos = c.transform.position;
                    }

                    _parentCharacter.MyAI.BlackBoard.AvgPersonalThreatDir = (fact.LastKnownPos - _parentCharacter.transform.position).normalized;
                    if (PersonalThreatLow > _parentCharacter.MyAI.BlackBoard.HighestPersonalThreat)
                    {
                        _parentCharacter.MyAI.BlackBoard.HighestPersonalThreat = PersonalThreatLow;
                    }

                    return(PersonalThreatLow);
                }
            }
        }



        return(0);
    }
示例#13
0
    private void DetectExplosive()
    {
        //check if there's live explosive near me
        GameObject [] explosives = GameObject.FindGameObjectsWithTag("Explosive");
        foreach (GameObject e in explosives)
        {
            Explosive explosive = e.GetComponent <Explosive>();
            if (explosive != null && explosive.IsEnabled)
            {
                Vector3 dist = e.transform.position - _parentCharacter.transform.position;
                if (dist.magnitude <= 7)               // && UnityEngine.Random.Range(0, 100) > 60)
                {
                    WorkingMemoryFact fact = _workingMemory.FindExistingFact(FactType.PersonalThreat, e);
                    if (fact == null)
                    {
                        fact                = _workingMemory.AddFact(FactType.PersonalThreat, e, e.transform.position, 1, 0.3f);
                        fact.ThreatLevel    = PersonalThreatCritical;
                        fact.ThreatDropRate = 0.1f;
                    }
                    else
                    {
                        fact.Confidence = 1;
                        if (fact.ThreatLevel < PersonalThreatCritical)
                        {
                            fact.ThreatLevel = PersonalThreatCritical;
                        }
                        fact.LastKnownPos = e.transform.position;
                    }

                    _parentCharacter.MyAI.BlackBoard.AvgPersonalThreatDir = (fact.LastKnownPos - _parentCharacter.transform.position).normalized;
                    if (PersonalThreatCritical > _parentCharacter.MyAI.BlackBoard.HighestPersonalThreat)
                    {
                        _parentCharacter.MyAI.BlackBoard.HighestPersonalThreat = PersonalThreatCritical;
                    }
                    Debug.Log("Detected grenade! ");
                    _parentCharacter.MyAI.OnImportantEvent(1f);
                }
            }
        }
    }
示例#14
0
    public void SetAttackTaskForSelectedMember(Character target)
    {
        SelectedMember.MyAI.BlackBoard.TargetEnemy    = target;
        SelectedMember.MyAI.BlackBoard.IsTargetLocked = true;
        WorkingMemoryFact fact = SelectedMember.MyAI.WorkingMemory.FindExistingFact(FactType.KnownEnemy, target);

        if (fact == null)
        {
            //didn't find it in working memory, create a new fact
            fact                = SelectedMember.MyAI.WorkingMemory.AddFact(FactType.KnownEnemy, target, target.transform.position, 0.99f, 0.01f);
            fact.ThreatLevel    = 1f;
            fact.ThreatDropRate = 0.03f;
        }
        else
        {
            //found it in working memory, refresh confidence level
            fact.Confidence   = 0.99f;
            fact.LastKnownPos = target.transform.position;
        }

        //SelectedMember.MyAI.ClearDynamicGoal(0);
        _lastAssignedMember = SelectedMember;
    }
示例#15
0
    public object EvaluateWorldState(GoapWorldState state)
    {
        if (state.Name == "IsThreatInSightInArea")
        {
            //loop through all known enemies whose confidence is 1 (in sight)
            //return true if any is found

            List <WorkingMemoryFact> knownEnemies = WorkingMemory.FindExistingFactOfType(FactType.KnownEnemy);
            foreach (WorkingMemoryFact fact in knownEnemies)
            {
                if (fact.Confidence >= 1 && fact.ThreatLevel > 0.1f)
                {
                    //if enemy is in sight, return true even if not in area
                    CsDebug.Inst.CharLog(_parentCharacter, "Evaluating IsThreatInSightInArea, enemy in sight " + ((Character)fact.Target).name);
                    SetCurrentWorldState(state, true);
                    return(true);
                }
            }

            //now loop through all known neutrals whose confidence is 1
            //return true if any is within area
            List <WorkingMemoryFact> knownNeutrals = WorkingMemory.FindExistingFactOfType(FactType.KnownNeutral);
            foreach (WorkingMemoryFact fact in knownNeutrals)
            {
                if (fact.Confidence >= 1 && fact.ThreatLevel > 0.1f)
                {
                    Vector3 position = ((Character)fact.Target).transform.position;

                    //check if the neutral is within patrol range
                    Vector3 targetLoc   = BlackBoard.PatrolLoc;
                    Vector3 targetRange = BlackBoard.CombatRange;
                    if (IsPositionInArea(position, targetLoc, targetRange))
                    {
                        CsDebug.Inst.CharLog(_parentCharacter, "Evaluation IsThreatInSightInArea, true, visible neutrals in area");
                        SetCurrentWorldState(state, true);
                        return(true);
                    }
                }
            }

            CsDebug.Inst.CharLog(_parentCharacter, "Evaluation IsThereThreatInArea, false");
            SetCurrentWorldState(state, false);
            return(false);
        }

        else if (state.Name == "IsThereInvisibleEnemy")
        {
            bool result = (_parentCharacter.MyAI.BlackBoard.InvisibleEnemy != null);
            SetCurrentWorldState(state, result);

            return(result);
        }

        else if (state.Name == "IsTargetAThreat")
        {
            Character target = BlackBoard.TargetEnemy;

            if (BlackBoard.TargetEnemyThreat < 0.1f)
            {
                SetCurrentWorldState(state, false);
                return(false);
            }

            if (target != null && target.MyStatus.Health <= 0)
            {
                SetCurrentWorldState(state, false);
                return(false);
            }

            if (target == null && BlackBoard.InvisibleEnemy != null)
            {
                target = BlackBoard.InvisibleEnemy;
            }

            if (target == null)
            {
                SetCurrentWorldState(state, false);
                return(false);
            }

            WorkingMemoryFact fact = WorkingMemory.FindExistingFact(FactType.KnownEnemy, target);

            if (fact != null && fact.Confidence >= 1)
            {
                SetCurrentWorldState(state, true);
                return(true);
            }
            else if (fact != null && fact.ThreatLevel >= 0.6f)
            {
                SetCurrentWorldState(state, true);
                return(true);
            }
            else if (fact != null)
            {
                //check if last known pos is inside area
                Vector3 position = fact.LastKnownPos;

                //check if the enemy is within patrol range
                Vector3 targetLoc   = BlackBoard.PatrolLoc;
                Vector3 targetRange = BlackBoard.CombatRange;
                if (IsPositionInArea(position, targetLoc, targetRange))
                {
                    SetCurrentWorldState(state, true);
                    return(true);
                }
            }


            SetCurrentWorldState(state, false);
            return(false);
        }

        else if (state.Name == "IsTherePersonalThreat")
        {
            bool result = BlackBoard.HighestPersonalThreat > 0;
            SetCurrentWorldState(state, result);
            CsDebug.Inst.CharLog(_parentCharacter, "Is there personal threat? " + BlackBoard.HighestPersonalThreat);
            return(result);
        }

        else if (state.Name == "IsThereCriticalPersonalThreat")
        {
            bool result = BlackBoard.HighestPersonalThreat >= 1;
            SetCurrentWorldState(state, result);
            return(result);
        }

        else if (state.Name == "IsRangedWeaponEquipped")
        {
            if (BlackBoard.EquippedWeapon != null)
            {
                SetCurrentWorldState(state, true);
                return(true);
            }
            else
            {
                SetCurrentWorldState(state, false);
                return(false);
            }
        }

        else if (state.Name == "IsThreatInSight")
        {
            List <WorkingMemoryFact> knownEnemies = WorkingMemory.FindExistingFactOfType(FactType.KnownEnemy);
            foreach (WorkingMemoryFact fact in knownEnemies)
            {
                //Debug.Log("Is Threat In Sight fact confidence " + fact.Confidence);
                if (fact.Confidence >= 1 && fact.ThreatLevel > 0.1f)
                {
                    SetCurrentWorldState(state, true);
                    return(true);
                }
            }

            SetCurrentWorldState(state, false);
            return(false);
        }

        else if (state.Name == "IsAmmoAvailable")
        {
            SetCurrentWorldState(state, true);
            return(true);
        }

        else if (state.Name == "IsBehindCover")
        {
            bool result = true;

            if (BlackBoard.SelectedCover == null)
            {
                result = false;
            }
            else
            {
                result = Vector3.Distance(_parentCharacter.transform.position, BlackBoard.SelectedCoverLoc) <= 2 ? true : false;
            }

            SetCurrentWorldState(state, result);
            return(result);
        }

        else if (state.Name == "IsBehindAttackCover")
        {
            bool result = true;

            if (BlackBoard.SelectedCover == null)
            {
                result = false;
            }
            else
            {
                if (Vector3.Distance(_parentCharacter.transform.position, BlackBoard.SelectedCoverLoc) <= 1 && BlackBoard.SelectedCover.IsForShooting)
                {
                    result = true;
                }
                else
                {
                    result = false;
                }
            }

            SetCurrentWorldState(state, result);
            return(result);
        }

        else if (state.Name == "IsThereDisturbance")
        {
            bool result = BlackBoard.HighestDisturbanceThreat > 0;
            SetCurrentWorldState(state, result);
            CsDebug.Inst.CharLog(_parentCharacter, "Is there disturbance? " + BlackBoard.HighestDisturbanceThreat);
            return(result);
        }

        else if (state.Name == "IsNearDefendPosition")
        {
            SetCurrentWorldState(state, false);
            return(false);

            if (!BlackBoard.HasPatrolInfo)
            {
                SetCurrentWorldState(state, false);
                return(false);
            }

            if (Vector3.Distance(_parentCharacter.transform.position, BlackBoard.PatrolLoc) > 1)
            {
                SetCurrentWorldState(state, false);
                return(false);
            }



            SetCurrentWorldState(state, true);
            return(true);
        }

        else if (state.Name == "IsInTargetArea")
        {
            bool result = IsPositionInArea(_parentCharacter.transform.position, BlackBoard.PatrolLoc, BlackBoard.PatrolRange);
            //CsDebug.Inst.CharLog(_parentCharacter, "Checking IsInTargetArea, result is " + result);
            SetCurrentWorldState(state, result);
            return(result);
        }

        else if (state.Name == "IsNearFollowingTarget")
        {
            SetCurrentWorldState(state, false);
            return(false);
        }

        else if (state.Name == "IsThereUncheckedCorpse")
        {
            if (BlackBoard.TargetCorpse != null && BlackBoard.TargetCorpse.ThreatLevel > 0 && Vector3.Distance(BlackBoard.TargetCorpse.LastKnownPos, _parentCharacter.transform.position) < 30)
            {
                SetCurrentWorldState(state, true);
                return(true);
            }

            SetCurrentWorldState(state, false);
            return(false);
        }
        else if (state.Name == "AlwaysFalse")
        {
            SetCurrentWorldState(state, false);
            return(false);
        }

        return(null);
    }
示例#16
0
	public void AddFact(WorkingMemoryFact fact)
	{
		if(!Facts.Contains(fact))
		{
			Facts.Add(fact);
		}
	}
示例#17
0
	public void RemoveFact(WorkingMemoryFact fact)
	{
		if(fact != null)
		{
			Facts.Remove(fact);
		}
	}
示例#18
0
    public void UpdatePerSecond()
    {
        //if(_parentCharacter.name != "HumanCharacter")
        //	Debug.Log("AITargeting Update full second " + _parentCharacter.name);

        _parentCharacter.SendCommand(CharacterCommands.SetAlert);

        if (UnityEngine.Random.value > 0.6f)
        {
            ResetLookAroundAngle();
        }

        //check current target. If it's still in sight (confidence 1) increase threat level
        //if no longer in sight, move it to invisible enemy
        //if no longer in memory then remove
        if (_parentCharacter.MyAI.BlackBoard.TargetEnemy != null)
        {
            WorkingMemoryFact currentTargetFact = _parentCharacter.MyAI.WorkingMemory.FindExistingFact(FactType.KnownEnemy, _parentCharacter.MyAI.BlackBoard.TargetEnemy);


            if (currentTargetFact != null && currentTargetFact.Confidence >= 1)
            {
                currentTargetFact.ThreatLevel += 0.05f;
                if (currentTargetFact.ThreatLevel > 1)
                {
                    currentTargetFact.ThreatLevel = 1;
                }
                _parentCharacter.MyAI.BlackBoard.TargetEnemyThreat      = currentTargetFact.ThreatLevel;
                _parentCharacter.MyAI.BlackBoard.LastKnownEnemyPosition = _parentCharacter.MyAI.BlackBoard.TargetEnemy.transform.position;
                if (currentTargetFact.ThreatLevel > 0.1f)
                {
                    _parentCharacter.MyAI.BlackBoard.GuardLevel = 3;
                }
                //_parentCharacter.MyAI.BlackBoard.IsTargetEnemyHittable = currentTargetFact.IsHittable;

                return;
            }
            else if (currentTargetFact != null)
            {
                //when confidence is low, move enemy to invisible (I know there's this guy but I don't see him)
                //Debug.Log("AI Targeting current target fact confidence is " + currentTargetFact.Confidence + " " + _parentCharacter.name);
                _parentCharacter.MyAI.BlackBoard.InvisibleEnemy = _parentCharacter.MyAI.BlackBoard.TargetEnemy;
                currentTargetFact.LastKnownPos = _parentCharacter.MyAI.BlackBoard.LastKnownEnemyPosition;
                _parentCharacter.MyAI.BlackBoard.TargetEnemy = null;
                //_parentCharacter.MyAI.BlackBoard.IsTargetEnemyHittable = currentTargetFact.IsHittable;

                currentTargetFact.ThreatLevel -= currentTargetFact.ThreatDropRate;
                if (currentTargetFact.ThreatLevel < 0)
                {
                    currentTargetFact.ThreatLevel = 0;
                }
                if (currentTargetFact.ThreatLevel > 0.1f)
                {
                    _parentCharacter.MyAI.BlackBoard.GuardLevel = 2;
                }
                _parentCharacter.MyAI.BlackBoard.TargetEnemyThreat = currentTargetFact.ThreatLevel;
            }
            else
            {
                _parentCharacter.MyAI.BlackBoard.TargetEnemy       = null;
                _parentCharacter.MyAI.BlackBoard.TargetEnemyThreat = 0;
                _parentCharacter.MyAI.BlackBoard.InvisibleEnemy    = null;
                //_parentCharacter.MyAI.BlackBoard.IsTargetEnemyHittable = false;
            }
        }


        //if(_parentCharacter.name != "HumanCharacter")
        //	Debug.Log("AITargeting Update full second FINISH " + _parentCharacter.name);
    }
示例#19
0
    public void UpdatePerHalfSecond()
    {
        //if(_parentCharacter.name != "HumanCharacter")
        //	Debug.Log("AITargeting Update half second " + _parentCharacter.name);

        //from working memory look for biggest enemy threat
        //if no threat present, look for nearest uninvestigated item
        List <WorkingMemoryFact> enemyFacts = _parentCharacter.MyAI.WorkingMemory.FindExistingFactOfType(FactType.KnownEnemy);

        //Debug.Log("Update Half Second for " + _parentCharacter.name + " enemyfacts " + enemyFacts.Count);
        if (enemyFacts.Count > 0)
        {
            //for now just get the closest enemy in sight
            WorkingMemoryFact selected = null;


            float minDist = 1000;
            foreach (WorkingMemoryFact f in enemyFacts)
            {
                float dist = Vector3.Distance(f.LastKnownPos, _parentCharacter.transform.position);
                if (dist < minDist && f.Confidence >= 1)
                {
                    minDist  = dist;
                    selected = f;
                }
            }

            if (selected != null)
            {
                if (_parentCharacter.MyAI.BlackBoard.TargetEnemy != null)
                {
                    //Debug.Log("Updating half second character targeting; current blackboard target is " + _parentCharacter.MyAI.BlackBoard.TargetEnemy.name);
                }
                else
                {
                    //Debug.Log("Updating half second character targeting; current blackboard target is null");
                }

                bool isNewTarget = (_parentCharacter.MyAI.BlackBoard.TargetEnemy != (Character)selected.Target && selected.Confidence >= 1f);

                //if targetEnemy is not null and target is locked, then we will not switch to new enemy
                if (_parentCharacter.MyAI.BlackBoard.IsTargetLocked && _parentCharacter.MyAI.BlackBoard.TargetEnemy != null)
                {
                    isNewTarget = false;
                }

                if (isNewTarget)
                {
                    //if not player faction and no previously known enemy then bark
                    bool willCallForHelp = false;

                    if (_parentCharacter.MyAI.BlackBoard.TargetEnemy == null && _parentCharacter.MyAI.BlackBoard.InvisibleEnemy == null &&
                        selected.ThreatLevel > 0.1f && _parentCharacter.MyAI.ControlType != AIControlType.Player)
                    {
                        //_parentCharacter.MyAI.Bark("Got intruder!");
                        _parentCharacter.PlayVocal(VocalType.Surprise);
                        willCallForHelp = true;
                    }

                    _parentCharacter.MyAI.BlackBoard.TargetEnemy       = (Character)selected.Target;
                    _parentCharacter.MyAI.BlackBoard.TargetEnemyThreat = selected.ThreatLevel;
                    _parentCharacter.MyAI.BlackBoard.InvisibleEnemy    = null;



                    //_parentCharacter.MyAI.BlackBoard.IsTargetEnemyHittable = true;
                    selected.LastKnownPos = _parentCharacter.MyAI.BlackBoard.TargetEnemy.transform.position;
                    _parentCharacter.MyAI.BlackBoard.LastKnownEnemyPosition = _parentCharacter.MyAI.BlackBoard.TargetEnemy.transform.position;
                    //trigger when a new target is selected
                    CsDebug.Inst.CharLog(_parentCharacter, "AITargeting found a new target!");

                    if (willCallForHelp)
                    {
                        _parentCharacter.MyAI.CallForHelp(_parentCharacter.MyAI.BlackBoard.TargetEnemy);
                    }

                    _parentCharacter.MyAI.OnImportantEvent(0.8f);
                }
                else
                {
                    _parentCharacter.MyAI.BlackBoard.TargetEnemy            = (Character)selected.Target;
                    _parentCharacter.MyAI.BlackBoard.TargetEnemyThreat      = selected.ThreatLevel;
                    _parentCharacter.MyAI.BlackBoard.InvisibleEnemy         = null;
                    _parentCharacter.MyAI.BlackBoard.LastKnownEnemyPosition = _parentCharacter.MyAI.BlackBoard.TargetEnemy.transform.position;
                }
            }
        }
        else
        {
            _parentCharacter.MyAI.BlackBoard.TargetEnemy    = null;
            _parentCharacter.MyAI.BlackBoard.InvisibleEnemy = null;
            //_parentCharacter.MyAI.BlackBoard.IsTargetEnemyHittable = false;
        }

        //if(_parentCharacter.name != "HumanCharacter")
        //	Debug.Log("AITargeting Update half second COMPLETED " + _parentCharacter.name);
    }
示例#20
0
	public void BroadcastMemoryFact(WorkingMemoryFact fact)
	{
		foreach(HumanCharacter member in Members)
		{
			member.MyAI.WorkingMemory.AddFact(fact);
		}
	}
示例#21
0
    /*
     * public bool GetTargetHittability(Character target)
     * {
     *      GameObject myEyes = _parentCharacter.MyReference.Eyes;
     *      RaycastHit hit;
     *      float colliderHeight = target.GetComponent<CapsuleCollider>().height;
     *      Vector3 rayTarget = target.transform.position + Vector3.up * colliderHeight * 0.75f;
     *      Ray ray = new Ray(myEyes.transform.position, rayTarget - myEyes.transform.position);
     *      if(Physics.Raycast(ray, out hit))
     *      {
     *              //Debug.Log("raycast hit in sensor: " + hit.collider.name);
     *              Character hitCharacter = hit.collider.GetComponent<Character>();
     *              if(hitCharacter == target)
     *              {
     *                      return true;
     *              }
     *      }
     *      else
     *      {
     *              return false;
     *      }
     *
     *      return false;
     * }
     */

    public void OnTakingDamage(Character attacker)
    {
        if (_parentCharacter.MyAI.ControlType == AIControlType.Player)
        {
            return;
        }

        CsDebug.Inst.CharLog(_parentCharacter, "Taking damage! " + _parentCharacter.name);
        //ignore friendly fire
        if (_parentCharacter.MyAI.IsCharacterFriendly(attacker))
        {
            return;
        }

        WorkingMemoryFact fact = _workingMemory.FindExistingFact(FactType.PersonalThreat, attacker);

        if (fact == null)
        {
            fact = _workingMemory.AddFact(FactType.PersonalThreat, attacker, attacker.transform.position, 1, 0.1f);

            fact.ThreatLevel = PersonalThreatHigh;

            fact.ThreatDropRate = 0.1f;
        }
        else
        {
            fact.Confidence = 1;
            if (fact.ThreatLevel < PersonalThreatHigh)
            {
                fact.ThreatLevel = PersonalThreatHigh;
            }
            fact.LastKnownPos = attacker.transform.position;
        }

        //raise threat to critical if health is low
        if (_parentCharacter.MyStatus.Health <= _parentCharacter.MyStatus.MaxHealth / 3 ||
            (_parentCharacter.MyAI.BlackBoard.TargetEnemy == null && _parentCharacter.MyAI.BlackBoard.InvisibleEnemy == null))
        {
            fact.ThreatLevel = PersonalThreatCritical;
        }

        if (attacker != null && attacker.MyAI.ControlType == AIControlType.Player)
        {
            if (_parentCharacter.MyAI.IsCharacterEnemy(attacker) > 0)
            {
                //reduce relationship
                float reduction = 0.25f;
                if (_parentCharacter.MyAI.BlackBoard.TargetEnemy != null)
                {
                    reduction = 0.07f;
                }
                GameManager.Inst.NPCManager.GetFactionData(Faction.Player).ReduceRelationshipByID(_parentCharacter.Faction, reduction);
                GameManager.Inst.NPCManager.GetFactionData(_parentCharacter.Faction).ReduceRelationshipByID(Faction.Player, reduction);
            }
        }

        //check if there's already a known enemy matching the shooter
        WorkingMemoryFact enemyFact = _workingMemory.FindExistingFact(FactType.KnownEnemy, attacker);

        if (enemyFact != null)
        {
            enemyFact.ThreatLevel = 1;
        }
        else
        {
            //if no existing known enemy fact from this attacker, add one
            fact                = _workingMemory.AddFact(FactType.KnownEnemy, attacker, attacker.transform.position, 0.5f, 0.01f);
            fact.ThreatLevel    = 1f;
            fact.ThreatDropRate = 0.01f;

            _parentCharacter.MyAI.BlackBoard.InvisibleEnemy         = attacker;
            _parentCharacter.MyAI.BlackBoard.LastKnownEnemyPosition = attacker.transform.position;

            _parentCharacter.MyAI.CallForHelp(attacker);
        }

        //check if there is currently invisible enemy; if not add it
        if (_parentCharacter.MyAI.BlackBoard.TargetEnemy == null && _parentCharacter.MyAI.BlackBoard.InvisibleEnemy == null)
        {
            _parentCharacter.MyAI.BlackBoard.InvisibleEnemy         = attacker;
            _parentCharacter.MyAI.BlackBoard.LastKnownEnemyPosition = attacker.transform.position;
        }

        //raise guard level
        _parentCharacter.MyAI.BlackBoard.GuardLevel        = 3;
        _parentCharacter.MyAI.BlackBoard.TargetEnemyThreat = 1;

        //only raise important event when the highest personal threat is lower than new threat, in order to damp the rate of replanning
        _parentCharacter.MyAI.BlackBoard.AvgPersonalThreatDir = (fact.LastKnownPos - _parentCharacter.transform.position).normalized;
        if (fact.ThreatLevel > _parentCharacter.MyAI.BlackBoard.HighestPersonalThreat)
        {
            //Debug.Log("VERY HIGH personal threat! new: " + fact.ThreatLevel + " old: " + _parentCharacter.MyAI.BlackBoard.HighestPersonalThreat + _parentCharacter.name);
            _parentCharacter.MyAI.BlackBoard.HighestPersonalThreat = fact.ThreatLevel;

            _parentCharacter.MyAI.OnImportantEvent(1);
        }
    }
示例#22
0
    private void DetectCorpse()
    {
        //skip this if there's threat
        if (_parentCharacter.MyAI.BlackBoard.InvisibleEnemy != null ||
            _parentCharacter.MyAI.BlackBoard.TargetEnemy != null)
        {
            return;
        }

        foreach (Character c in GameManager.Inst.NPCManager.AllCharacters)
        {
            if (c.MyStatus.Health > 0)
            {
                continue;
            }

            float      fov    = 170;
            float      range  = c.Stealth.Visibility;
            GameObject myEyes = _parentCharacter.MyReference.Eyes;

            bool isKnown           = false;
            WorkingMemoryFact fact = _workingMemory.FindExistingFact(FactType.NearbyCorpse, c);
            if (fact != null)
            {
                isKnown = true;
            }

            float distance = Vector3.Distance(c.transform.position, _parentCharacter.transform.position);
            if (distance <= range && Vector3.Angle(myEyes.transform.forward, (c.transform.position - _parentCharacter.transform.position)) <= fov / 2 && !isKnown)
            {
                //now do a raycast check if this character is behind walls.
                RaycastHit hit;
                float      colliderHeight = c.GetComponent <CapsuleCollider>().height;
                Vector3    rayTarget      = c.transform.position;
                Ray        ray            = new Ray(myEyes.transform.position, rayTarget - myEyes.transform.position);
                Debug.DrawRay(myEyes.transform.position, rayTarget - myEyes.transform.position);
                if (Physics.Raycast(ray, out hit))
                {
                    //Debug.Log("raycast hit in sensor for corpse: " + hit.collider.name);
                    Character hitCharacter = hit.collider.GetComponent <Character>();
                    if (hitCharacter != null && hitCharacter == c)
                    {
                        Debug.Log("Found new corpse! " + _parentCharacter.name);
                        fact                = _workingMemory.AddFact(FactType.NearbyCorpse, c, c.transform.position, 1, 0);
                        fact.ThreatLevel    = 1;
                        fact.ThreatDropRate = 0.1f;


                        if (_parentCharacter.MyAI.BlackBoard.TargetCorpse == null)
                        {
                            _parentCharacter.MyAI.BlackBoard.TargetCorpse = fact;
                        }
                        else
                        {
                            if ((Vector3.Distance(_parentCharacter.MyAI.BlackBoard.TargetCorpse.LastKnownPos, _parentCharacter.transform.position) <
                                 Vector3.Distance(c.transform.position, _parentCharacter.transform.position)) || _parentCharacter.MyAI.BlackBoard.TargetCorpse.ThreatLevel <= 0)
                            {
                                _parentCharacter.MyAI.BlackBoard.TargetCorpse = fact;
                            }
                        }

                        _parentCharacter.MyAI.OnImportantEvent(0.3f);
                    }
                }
            }
        }
    }
示例#23
0
    private void DetectDisturbance()
    {
        //go through all characters and find enemies within hearing range
        foreach (Character c in GameManager.Inst.NPCManager.AllCharacters)
        {
            if (c == _parentCharacter || _parentCharacter.MyAI.IsCharacterEnemy(c) >= 2 || c.MyStatus.Health <= 0)
            {
                continue;
            }

            float distance = Vector3.Distance(c.transform.position, _parentCharacter.transform.position);

            if (c.Stealth.NoiseLevel > distance)
            {
                //first check if the memory fact exists already
                WorkingMemoryFact fact = _workingMemory.FindExistingFact(FactType.Disturbance, c);
                if (fact == null)
                {
                    //confidence drop rate depends on the threat level
                    float dropRate = 0.1f - 0.095f * c.Stealth.NoiseThreat;
                    fact                = _workingMemory.AddFact(FactType.Disturbance, c, c.transform.position, 1, dropRate);
                    fact.ThreatLevel    = c.Stealth.NoiseThreat;
                    fact.ThreatDropRate = dropRate;
                }
                else
                {
                    fact.Confidence   = 1;
                    fact.LastKnownPos = c.transform.position;
                    fact.ThreatLevel  = c.Stealth.NoiseThreat;
                }
            }
        }

        //now look through all disturbance and put the highest in black board
        float   oldThreat  = _parentCharacter.MyAI.BlackBoard.HighestDisturbanceThreat;
        float   tempThreat = 0;
        Vector3 tempLoc    = Vector3.zero;
        object  tempSource = null;
        List <WorkingMemoryFact> disturbances = _workingMemory.FindExistingFactOfType(FactType.Disturbance);

        foreach (WorkingMemoryFact f in disturbances)
        {
            if (f.ThreatLevel > tempThreat)
            {
                tempThreat = f.ThreatLevel;
                tempLoc    = f.LastKnownPos;
                tempSource = f.Target;
            }
        }

        //Debug.Log("updating HighestDisturbance threat to " + tempThreat);
        _parentCharacter.MyAI.BlackBoard.HighestDisturbanceThreat = tempThreat;

        //if higher than old threat then trigger an important event; don't do this when there's active enemy target or personal threat
        if (tempThreat > oldThreat &&
            _parentCharacter.MyAI.BlackBoard.TargetEnemy == null &&
            _parentCharacter.MyAI.BlackBoard.HighestPersonalThreat <= 0)
        {
            _parentCharacter.MyAI.BlackBoard.HighestDisturbanceLoc     = tempLoc;
            _parentCharacter.MyAI.BlackBoard.HightestDisturbanceSource = tempSource;
            //Debug.Log("Found higher disturbance, raising important event " + _parentCharacter.name);
            _parentCharacter.MyAI.OnImportantEvent(tempThreat);
        }
    }
示例#24
0
    private void UpdateWorkingMemoryCharacters()
    {
        //set the field of view and view range to a number for now; these will be part of char attributes
        float      fov    = 170;
        float      range  = 60;
        GameObject myEyes = _parentCharacter.MyReference.Eyes;

        foreach (Character c in GameManager.Inst.NPCManager.AllCharacters)
        {
            if (c == _parentCharacter || _parentCharacter.MyAI.IsCharacterEnemy(c) >= 3)
            {
                continue;
            }

            if (c.MyStatus.Health <= 0)
            {
                //ignore dead
                continue;
            }

            bool isSeen = false;


            //adjust distance according to guardlevel
            if (_parentCharacter.MyAI.BlackBoard.GuardLevel == 2)
            {
                range = Mathf.Clamp(range, 20, range);
                fov   = 200;
            }
            else if (_parentCharacter.MyAI.BlackBoard.GuardLevel == 3)
            {
                range = Mathf.Clamp(range, 30, range);
                fov   = 240;
            }
            else
            {
                range = c.Stealth.Visibility * _parentCharacter.MyStatus.EyeSight;
            }

            float baseRange = range;

            //add 8 to range for player
            if (c.MyAI.ControlType == AIControlType.Player)
            {
                //Debug.Log("Update working memory checking player");
                range += 8;                 //make a buffer zone to notify player with flashing vignette when enemy is too near
            }


            //check if within range and fov
            float distance = Vector3.Distance(c.transform.position, _parentCharacter.transform.position);
            if (distance <= 3 && _parentCharacter.MyAI.BlackBoard.GuardLevel > 2)
            {
                fov = 360;
            }


            if (distance <= range && Vector3.Angle(myEyes.transform.forward, (c.transform.position - _parentCharacter.transform.position)) <= fov / 2)
            {
                //Debug.Log(_parentCharacter.name + " sensor range/fov check passed for " + c.name);
                //now do a raycast check if this character is behind walls.
                RaycastHit      hit;
                float           colliderHeight = 0;
                CapsuleCollider collider       = c.GetComponent <CapsuleCollider>();
                if (collider.direction == 2)
                {
                    colliderHeight = collider.center.y;
                }
                else if (collider.direction == 1)
                {
                    colliderHeight = collider.height;
                }
                Vector3 rayTarget = c.transform.position + Vector3.up * colliderHeight * 0.7f;
                Ray     ray       = new Ray(myEyes.transform.position, rayTarget - myEyes.transform.position);
                //Debug.DrawRay(myEyes.transform.position, rayTarget - myEyes.transform.position, Color.red, 0.9f);
                if (Physics.Raycast(ray, out hit, 200))
                {
                    //Debug.Log(_parentCharacter.name + " raycast hit in sensor: " + hit.collider.name);
                    Character hitCharacter = hit.collider.GetComponent <Character>();
                    if (hitCharacter != null && hitCharacter == c)
                    {
                        //Debug.Log("sensor ray check passed");
                        if (c.MyAI.ControlType != AIControlType.Player)
                        {
                            isSeen = true;
                            c.Stealth.SetDetectedVisibilityBoost(5);
                        }
                        else
                        {
                            if (distance <= baseRange)
                            {
                                isSeen = true;
                                c.Stealth.SetDetectedVisibilityBoost(5);
                                c.Stealth.AlmostDetected = 0;
                            }
                            else
                            {
                                //notify player of imminent detection
                                c.Stealth.AlmostDetected = 1;
                            }
                        }
                    }
                    else
                    {
                    }
                }
            }
            else if (c.MyAI.ControlType == AIControlType.Player)
            {
                c.Stealth.AlmostDetected = 0;
            }

            //process each character found
            //determine confidence based on whether seen or heard
            float confidence = 0;
            if (isSeen)
            {
                confidence = 1;
            }
            else
            {
                //not seen nor heard, continue
                continue;
            }

            int relationship = _parentCharacter.MyAI.IsCharacterEnemy(c);
            if (relationship < 2 || c == _parentCharacter.Killer)
            {
                //add/update enemy fact
                WorkingMemoryFact fact = _workingMemory.FindExistingFact(FactType.KnownEnemy, c);

                Vector3 position = c.transform.position;

                //check if the neutral is within patrol range
                float dist               = Vector3.Distance(_parentCharacter.MyAI.BlackBoard.DefensePoint, c.transform.position);
                float highThreat         = 1;
                int   originalGuardLevel = _parentCharacter.MyAI.BlackBoard.GuardLevel;
                //Debug.Log("AI Sensor update enemy relationship " + relationship);
                if (relationship > 0 && c != _parentCharacter.Killer)
                {
                    if (dist > _parentCharacter.MyAI.BlackBoard.DefenseRadius * 2f)
                    {
                        highThreat = 0f;
                        _parentCharacter.MyAI.BlackBoard.GuardLevel = originalGuardLevel;
                    }
                    else if (dist > _parentCharacter.MyAI.BlackBoard.DefenseRadius)
                    {
                        highThreat = 0.5f;
                        if (originalGuardLevel >= 2)
                        {
                            _parentCharacter.MyAI.BlackBoard.GuardLevel = originalGuardLevel;
                        }
                        else
                        {
                            _parentCharacter.MyAI.BlackBoard.GuardLevel = 2;
                        }
                    }
                    else
                    {
                        highThreat = 1;
                        _parentCharacter.MyAI.BlackBoard.GuardLevel = 3;
                    }
                }

                if (fact == null)
                {
                    //didn't find it in working memory, create a new fact
                    fact = _workingMemory.AddFact(FactType.KnownEnemy, c, c.transform.position, confidence, 0.03f);
                    //Debug.LogError("adding known enemy fact " + c.Faction + " " + _parentCharacter.Faction + " " + c.name + " I am " + _parentCharacter.name);
                    fact.ThreatLevel    = highThreat;
                    fact.ThreatDropRate = 0.03f;
                }
                else
                {
                    //found it in working memory, refresh confidence level
                    fact.Confidence   = confidence;
                    fact.LastKnownPos = c.transform.position;
                    fact.ThreatLevel  = highThreat;
                    //Debug.Log("refreshing enemy fact");
                }

                //if current blackboard has personal threat, mark this target high threat level
                if (_parentCharacter.MyAI.BlackBoard.HighestPersonalThreat > 0)
                {
                    //Debug.Log("Since there's  personal threat " + _parentCharacter.MyAI.BlackBoard.HighestPersonalThreat + ", marking enemy threat as high");
                    fact.ThreatLevel = 1;
                }

                //if we consider this character is posing personal threat then his threat level is maxed
                float personalThreat = CheckPersonalThreat(c);
                if (personalThreat >= PersonalThreatLow)
                {
                    //Debug.Log("enemy is aiming at me, marking enemy threat as high");
                    fact.ThreatLevel = 1;
                }
            }
            else
            {
                //add/update friend fact
            }
        }
    }
示例#25
0
    public void OnReceiveDisturbance(float threat, object source, Vector3 location, Character sourceChar)
    {
        if (_parentCharacter.MyAI.ControlType == AIControlType.Player)
        {
            return;
        }

        if (_parentCharacter.MyAI.IsCharacterInParty(sourceChar) && threat < 1)
        {
            return;
        }

        //first check if the memory fact exists already
        WorkingMemoryFact fact = _workingMemory.FindExistingFact(FactType.Disturbance, source);

        if (fact == null)
        {
            //Debug.Log("adding new disturbance fact");
            //confidence drop rate depends on the threat level
            float dropRate = 0.1f - 0.05f * threat;
            fact                = _workingMemory.AddFact(FactType.Disturbance, source, location, 1, dropRate);
            fact.ThreatLevel    = threat;
            fact.ThreatDropRate = 0.0f;
        }
        else
        {
            //Debug.Log("Found existing disturbance memory " + _parentCharacter.name);
            fact.Confidence   = 1;
            fact.LastKnownPos = location;
            fact.ThreatLevel += threat;
            if (fact.ThreatLevel > 1)
            {
                fact.ThreatLevel = 1;
            }
        }

        //if higher than old threat then trigger an important event; don't do this when there's active enemy target or personal threat
        //Debug.Log("new threat level " + fact.ThreatLevel + _parentCharacter.name);
        if (_parentCharacter.MyAI.BlackBoard.HighestDisturbanceThreat <= fact.ThreatLevel &&
            _parentCharacter.MyAI.BlackBoard.TargetEnemy == null &&
            _parentCharacter.MyAI.BlackBoard.HighestPersonalThreat <= 0)
        {
            //Debug.Log("Received higher disturbance " + fact.ThreatLevel + ", raising important event, I am " + _parentCharacter.name);
            _parentCharacter.MyAI.BlackBoard.HighestDisturbanceThreat = fact.ThreatLevel;
            //if threat greater than 1 then use thrower's location
            if (fact.ThreatLevel < 1)
            {
                _parentCharacter.MyAI.BlackBoard.HighestDisturbanceLoc = location;
            }
            else
            {
                Vector3 destination = Vector3.zero;
                if (AI.RandomPoint(sourceChar.transform.position, new Vector3(3, 1, 3), out destination))
                {
                    _parentCharacter.MyAI.BlackBoard.HighestDisturbanceLoc = destination;
                }
                else
                {
                    _parentCharacter.MyAI.BlackBoard.HighestDisturbanceLoc = location;
                }
            }

            _parentCharacter.MyAI.BlackBoard.HightestDisturbanceSource = source;
            _parentCharacter.MyAI.OnImportantEvent(fact.ThreatLevel);
        }
    }