/// <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); }
/// <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); }
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); }