Exemple #1
0
        /// <summary>
        /// Add an influencer to this controller. If this controller is not managing the required stat then
        /// do nothing. If we already added an influencer of this type within the cooldown time then
        /// do nothing.
        /// </summary>
        /// <param name="influencer">The influencer to add.</param>
        /// <returns>True if the influencer was added, otherwise false.</returns>
        public virtual bool TryAddInfluencer(StatInfluencerSO influencer)
        {
            bool exists = false;

            // check that if an influencer already exists we are not in a cooldown period for this influencer
            for (int i = StatsInfluencers.Count - 1; i >= 0; i--)
            {
                if (StatsInfluencers[i].InteractionName == influencer.InteractionName)
                {
                    exists = true;
                    if (Time.timeSinceLevelLoad > StatsInfluencers[i].CooldownCompleteTime)
                    {
                        StatsInfluencers.Add(influencer);
                    }
                    else
                    {
                        // it already exists and we are in cooldown, don't add again.
                        return(false);
                    }
                }
            }

            // If the influencer doesn't already exist add it
            if (!exists)
            {
                StatsInfluencers.Add(influencer);
            }
            return(true);
        }
Exemple #2
0
        /// <summary>
        /// Add an influencer to this controller. If this controller is not managing the required stat then
        /// do nothing.
        /// </summary>
        /// <param name="influencer">The influencer to add.</param>
        /// <returns>True if the influencer was added, otherwise false.</returns>
        public override bool TryAddInfluencer(StatInfluencerSO influencer)
        {
            if (Memory != null && influencer.Trigger != null)
            {
                MemorySO[] memories = Memory.GetAllMemoriesAbout(influencer.Generator);
                for (int i = 0; i < memories.Length; i++)
                {
                    if (memories[i].stat == influencer.stat && memories[i].time + memories[i].cooldown > Time.timeSinceLevelLoad)
                    {
                        return(false);
                    }
                }
            }

            if (Memory != null)
            {
                StatSO         stat   = GetOrCreateStat(influencer.stat);
                List <StateSO> states = GetDesiredStatesFor(stat);
                bool           isGood = true;
                for (int i = 0; i < states.Count; i++)
                {
                    switch (states[i].objective)
                    {
                    case StateSO.Objective.LessThan:
                        if (influencer.maxChange > 0)
                        {
                            isGood = false;
                        }
                        break;

                    case StateSO.Objective.Approximately:
                        float currentDelta    = states[i].normalizedTargetValue - stat.NormalizedValue;
                        float influencedDelta = states[i].normalizedTargetValue - (stat.NormalizedValue + influencer.maxChange);
                        if (currentDelta < influencedDelta)
                        {
                            isGood = false;
                        }
                        break;

                    case StateSO.Objective.GreaterThan:
                        if (influencer.maxChange < 0)
                        {
                            isGood = false;
                        }
                        break;
                    }

                    if (influencer.Generator != null)
                    {
                        Memory.AddMemory(influencer, isGood);
                    }
                }
            }

            return(base.TryAddInfluencer(influencer));
        }
        /// <summary>
        /// Add an influencer to this controller. If this controller is not managing the required stat then
        /// do nothing.
        /// </summary>
        /// <param name="influencer">The influencer to add.</param>
        /// <returns>True if the influencer was added, otherwise false.</returns>
        public bool TryAddInfluencer(StatInfluencerSO influencer)
        {
            if (m_Memory != null && influencer.generator != null)
            {
                MemorySO[] memories = m_Memory.GetAllMemoriesAbout(influencer.generator);
                for (int i = 0; i < memories.Length; i++)
                {
                    if (memories[i].stat == influencer.stat && memories[i].time + memories[i].cooldown > Time.timeSinceLevelLoad)
                    {
                        return(false);
                    }
                }
            }

            StatSO stat   = GetOrCreateStat(influencer.stat.name);
            bool   isGood = true;

            switch (stat.desiredState.objective)
            {
            case DesiredState.Objective.LessThan:
                if (influencer.maxChange > 0)
                {
                    isGood = false;
                }
                break;

            case DesiredState.Objective.Approximately:
                float currentDelta    = stat.desiredState.targetValue - stat.value;
                float influencedDelta = stat.desiredState.targetValue - (stat.value + influencer.maxChange);
                if (currentDelta < influencedDelta)
                {
                    isGood = false;
                }
                break;

            case DesiredState.Objective.GreaterThan:
                if (influencer.maxChange < 0)
                {
                    isGood = false;
                }
                break;
            }

            if (m_Memory != null)
            {
                m_Memory.AddMemory(influencer, isGood);
            }

            m_StatsInfluencers.Add(influencer);

            return(true);
        }
        /// <summary>
        /// Apply an immediate change to a given Stats, if this controller is tracking that stat.
        /// </summary>
        ///
        /// <param name="influencer">The influencer imparting the change.</param>
        internal void ChangeStat(StatInfluencerSO influencer)
        {
            StatSO stat = GetOrCreateStat(influencer.stat.name);
            float  change;

            if (influencer.duration > 0)
            {
                change = Mathf.Clamp(influencer.changePerSecond * (Time.timeSinceLevelLoad - m_TimeOfLastUpdate), float.MinValue, influencer.maxChange - influencer.influenceApplied);
            }
            else
            {
                change = Mathf.Clamp(influencer.maxChange, influencer.maxChange - influencer.influenceApplied, influencer.maxChange);
            }

            stat.value += change;
            influencer.influenceApplied += change;
            //Debug.Log(gameObject.name + " changed stat " + influencer.statName + " by " + change);
        }
        public IEnumerator StatInstantInfluencer()
        {
            string          statName   = "Test Immediate Influencer Stat";
            StatsController controller = new GameObject().AddComponent <StatsController>();

            StatInfluencerSO influencer = ScriptableObject.CreateInstance <StatInfluencerSO>();
            StatSO           stat       = controller.GetOrCreateStat(statName);

            influencer.stat      = stat;
            influencer.maxChange = 10;
            influencer.duration  = 0;

            Assert.True(controller.TryAddInfluencer(influencer), "Was not able to add the Stat influencer");

            yield return(null);

            Assert.True(controller.GetOrCreateStat(statName).value > 0, "Seems the influencer has had no effect.");

            yield return(null);
        }
Exemple #6
0
        public IEnumerator StatInstantInfluencer()
        {
            StatSO template = ScriptableObject.CreateInstance <StatSO>();
            string statName = "Test Immediate Influencer Stat";

            template.name = statName;

            Brain controller = new GameObject().AddComponent <Brain>();

            StatInfluencerSO influencer = ScriptableObject.CreateInstance <StatInfluencerSO>();
            StatSO           stat       = controller.GetOrCreateStat(template);

            influencer.stat      = stat;
            influencer.maxChange = 10;
            influencer.duration  = 0;

            Assert.True(controller.TryAddInfluencer(influencer), "Was not able to add the Stat influencer");

            yield return(new WaitForSeconds(0.51f)); // ensure the brain has time to apply the influencer

            Assert.True(stat.NormalizedValue > 0, "Seems the influencer has had no effect.");

            yield return(null);
        }