public override void OnGameTick(float deltaTime) { if ((tickAccum += deltaTime) < 0.33f) { return; } tickAccum = 0; float nowStressLevel = 0f; List <string> codesToRemove = null; foreach (var stateAndcode in ActiveStatesByCode) { string code = stateAndcode.Key; ActiveEmoState state = stateAndcode.Value; float leftDur = state.Duration -= 10 * deltaTime; if (leftDur <= 0) { if (codesToRemove == null) { codesToRemove = new List <string>(); } codesToRemove.Add(code); entityAttr.RemoveAttribute(code); continue; } nowStressLevel += availableStates[state.StateId].StressLevel; } if (codesToRemove != null) { foreach (string s in codesToRemove) { ActiveStatesByCode.Remove(s); } } float curlevel = entity.WatchedAttributes.GetFloat("stressLevel"); if (nowStressLevel > 0) { entity.WatchedAttributes.SetFloat("stressLevel", Math.Max(curlevel, nowStressLevel)); } else { if (curlevel > 0) // no need to keep recalculating and setting it once it reaches 0 { curlevel = Math.Max(0, curlevel - deltaTime * 1.25f); entity.WatchedAttributes.SetFloat("stressLevel", curlevel); } } if (entity.World.EntityDebugMode) { // expensive string operations entity.DebugAttributes.SetString("emotionstates", string.Join(", ", ActiveStatesByCode.Keys.ToList())); } }
public bool TryTriggerState(string statecode, double chance, long sourceEntityId) { bool triggered = false; for (int stateid = 0; stateid < availableStates.Length; stateid++) { EmotionState newstate = availableStates[stateid]; if (newstate.Code != statecode || chance > newstate.Chance) { continue; } if (newstate.whenHealthRelBelow < healthRel) { continue; } ActiveEmoState activeState = null; foreach (var val in ActiveStatesByCode) { if (val.Key == newstate.Code) { activeState = val.Value; continue; } int activestateid = val.Value.StateId; EmotionState activestate = availableStates[activestateid]; if (activestate.Slot == newstate.Slot) { // Active state has priority over this one if (activestate.Priority > newstate.Priority) { return(false); } else { // New state has priority ActiveStatesByCode.Remove(val.Key); entityAttr.RemoveAttribute(newstate.Code); break; } } } float duration = newstate.Duration; if (newstate.BelowTempThreshold > -99 && entity.World.BlockAccessor.GetClimateAt(entity.Pos.AsBlockPos, EnumGetClimateMode.NowValues).Temperature < newstate.BelowTempDuration) { duration = newstate.BelowTempDuration; } float newDuration = 0; if (newstate.AccumType == EnumAccumType.Sum) { newDuration = activeState?.Duration ?? 0 + duration; } if (newstate.AccumType == EnumAccumType.Max) { newDuration = Math.Max(activeState?.Duration ?? 0, duration); } if (newstate.AccumType == EnumAccumType.NoAccum) { newDuration = activeState?.Duration > 0 ? activeState?.Duration ?? 0 : duration; } if (activeState == null) { ActiveStatesByCode[newstate.Code] = new ActiveEmoState() { Duration = newDuration, SourceEntityId = sourceEntityId, StateId = stateid }; } else { activeState.SourceEntityId = sourceEntityId; } entityAttr.SetFloat(newstate.Code, newDuration); triggered = true; } return(triggered); }