Ejemplo n.º 1
0
        public void CreateDialogueBehavior(MentalType mentalType)
        {
            if (mentalType == MentalType.Normal)
            {
                return;
            }
            string textIdentifier = $"dialogmentalstate{mentalType.ToString().ToLowerInvariant()}";

            character.Speak(TextManager.Get(textIdentifier), delay: Rand.Range(0.5f, 1.0f), identifier: textIdentifier, minDurationBetweenSimilar: 35f);
        }
Ejemplo n.º 2
0
        public bool CreateCombatBehavior(MentalType mentalType)
        {
            Character mentalAttackTarget = Character.CharacterList.Where(
                possibleTarget => HumanAIController.IsActive(possibleTarget) &&
                (possibleTarget.TeamID != character.TeamID || mentalType == MentalType.Berserk) &&
                humanAIController.VisibleHulls.Contains(possibleTarget.CurrentHull) &&
                possibleTarget != character).GetRandom();

            if (mentalAttackTarget == null)
            {
                return(false);
            }

            var  combatMode = AIObjectiveCombat.CombatMode.None;
            bool holdFire   = mentalType == MentalType.Afraid && character.IsSecurity;

            switch (mentalType)
            {
            case MentalType.Afraid:
                combatMode = character.IsSecurity ? AIObjectiveCombat.CombatMode.Arrest : AIObjectiveCombat.CombatMode.Retreat;
                break;

            case MentalType.Desperate:
                // might be unnecessary to explicitly declare as arrest against non-humans
                combatMode = character.IsSecurity && mentalAttackTarget.IsHuman ? AIObjectiveCombat.CombatMode.Arrest : AIObjectiveCombat.CombatMode.Defensive;
                break;

            case MentalType.Berserk:
                combatMode = AIObjectiveCombat.CombatMode.Offensive;
                break;
            }

            // using this as an explicit time-out for the behavior. it's possible it will never run out because of the manager being disabled, but combat objective has failsafes for that
            mentalBehaviorTimer = MentalBehaviorInterval;
            humanAIController.AddCombatObjective(combatMode, mentalAttackTarget, allowHoldFire: holdFire, abortCondition: obj => mentalBehaviorTimer <= 0f);
            string textIdentifier = $"dialogmentalstatereaction{combatMode.ToString().ToLowerInvariant()}";

            character.Speak(TextManager.Get(textIdentifier), delay: Rand.Range(0.5f, 1.0f), identifier: textIdentifier, minDurationBetweenSimilar: 25f);

            if (mentalType == MentalType.Berserk && !character.HasTeamChange(MentalTeamChange))
            {
                // TODO: could this be handled in the switch block above?
                character.TryAddNewTeamChange(MentalTeamChange, new ActiveTeamChange(CharacterTeamType.None, ActiveTeamChange.TeamChangePriorities.Absolute, aggressiveBehavior: true));
            }

            return(true);
        }
Ejemplo n.º 3
0
        private void UpdateMentalState()
        {
            MentalType newMentalType = GetMentalType(character.CharacterHealth.GetAffliction("psychosis"));
            bool       createdCombat = false;

            switch (newMentalType)
            {
            case MentalType.Normal:
            case MentalType.Confused:
                // remove combat if we became normal again
                mentalBehaviorTimer = 0f;
                break;

            case MentalType.Afraid:
            case MentalType.Desperate:
            case MentalType.Berserk:
                // berserk is not removed unless we drop to normal behavior again
                if (CurrentMentalType == MentalType.Berserk)
                {
                    newMentalType = MentalType.Berserk;
                }
                // give players a full interval to react to mental changes
                if (newMentalType == CurrentMentalType)
                {
                    createdCombat = CreateCombatBehavior(CurrentMentalType);
                }
                break;
            }

            if (!createdCombat)
            {
                CreateDialogueBehavior(newMentalType);
            }

            if (newMentalType != MentalType.Berserk)
            {
                character.TryRemoveTeamChange(MentalTeamChange);
            }

            CurrentMentalType = newMentalType;
        }
Ejemplo n.º 4
0
        private MentalType GetMentalType(Affliction affliction)
        {
            if (affliction == null)
            {
                return(MentalType.Normal);
            }
            // test this later
            int psychosisIndex = (int)(affliction.Strength / (affliction.Prefab.MaxStrength / MentalTypeCount) * Rand.Range(1f, 1.2f));

            psychosisIndex = Math.Clamp(psychosisIndex, 0, 4);
            MentalType mentalType = psychosisIndex switch
            {
                0 => MentalType.Normal,
                1 => MentalType.Confused,
                2 => MentalType.Afraid,
                3 => MentalType.Desperate,
                4 => MentalType.Berserk,
                _ => throw new ArgumentOutOfRangeException(psychosisIndex.ToString()),
            };

            return(mentalType);
        }