public override void Initialize(EntityProperties properties, JsonObject typeAttributes) { base.Initialize(properties, typeAttributes); JsonObject[] availStates = typeAttributes["states"].AsArray(); foreach (JsonObject obj in availStates) { EmotionState state = obj.AsObject <EmotionState>(); availableStates.Add(state); } }
public bool IsInEmotionState(string statecode) { for (int stateid = 0; stateid < availableStates.Count; stateid++) { EmotionState newstate = availableStates[stateid]; if (newstate.Code != statecode) { continue; } return(ActiveStatesById.ContainsKey(stateid)); } return(false); }
public override void Initialize(EntityProperties properties, JsonObject typeAttributes) { base.Initialize(properties, typeAttributes); JsonObject[] availStates = typeAttributes["states"].AsArray(); availableStates = new EmotionState[availStates.Length]; int i = 0; foreach (JsonObject obj in availStates) { EmotionState state = obj.AsObject <EmotionState>(); availableStates[i++] = state; } tickAccum = (float)(entity.World.Rand.NextDouble() * 0.33); //spread out the ticking if a lot of entities load at the same time, such as at server start }
public override void OnEntityReceiveDamage(DamageSource damageSource, ref float damage) { if (damageSource.Source == EnumDamageSource.Fall && entity.World.Config.GetString("creatureHostility") == "passive" && entity.World.Config.GetString("creatureHostility") == "off") { return; } var beh = entity.GetBehavior <EntityBehaviorHealth>(); healthRel = beh.Health / beh.MaxHealth; long sourceEntityId = damageSource.SourceEntity?.EntityId ?? 0; if (TryTriggerState("alarmherdondamage", sourceEntityId) && damageSource.SourceEntity != null && (entity as EntityAgent).HerdId > 0) { EmotionState state = availableStates.First((s) => s.Code == "alarmherdondamage"); entity.World.GetNearestEntity(entity.ServerPos.XYZ, state.NotifyRange, state.NotifyRange, (e) => { EntityAgent agent = e as EntityAgent; if (e.EntityId != entity.EntityId && agent != null && agent.Alive && agent.HerdId == (entity as EntityAgent).HerdId) { agent.GetBehavior <EntityBehaviorEmotionStates>().TryTriggerState("aggressiveondamage", sourceEntityId); } return(false); }); } if (TryTriggerState("aggressiveondamage", sourceEntityId)) { if (TryTriggerState("aggressivealarmondamage", sourceEntityId)) { } } if (TryTriggerState("fleeondamage", sourceEntityId)) { if (TryTriggerState("fleealarmondamage", sourceEntityId)) { } } }
public bool TryTriggerState(string statecode) { bool triggered = false; for (int stateid = 0; stateid < availableStates.Count; stateid++) { EmotionState newstate = availableStates[stateid]; if (newstate.Code != statecode || entity.World.Rand.NextDouble() > newstate.Chance) { continue; } if (newstate.whenHealthRelBelow < healthRel) { continue; } float activedur = 0; foreach (int activestateid in ActiveStatesById.Keys) { if (activestateid == stateid) { activedur = ActiveStatesById[stateid]; continue; } 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 ActiveStatesById.Remove(activestateid); entityAttrById.RemoveAttribute("" + activestateid); entityAttr.RemoveAttribute(newstate.Code); break; } } } float newDuration = 0; if (newstate.AccumType == EnumAccumType.Sum) { newDuration = activedur + newstate.Duration; } if (newstate.AccumType == EnumAccumType.Max) { newDuration = Math.Max(activedur, newstate.Duration); } if (newstate.AccumType == EnumAccumType.NoAccum) { newDuration = activedur > 0 ? activedur : newstate.Duration; } ActiveStatesById[stateid] = newDuration; entityAttrById.SetFloat("" + stateid, newDuration); entityAttr.SetFloat(newstate.Code, newDuration); triggered = true; } return(triggered); }
public bool TryTriggerState(string statecode, double chance) { bool triggered = false; for (int stateid = 0; stateid < availableStates.Count; stateid++) { EmotionState newstate = availableStates[stateid]; if (newstate.Code != statecode || chance > newstate.Chance) { continue; } if (newstate.whenHealthRelBelow < healthRel) { continue; } float activedur = 0; foreach (int activestateid in ActiveStatesById.Keys) { if (activestateid == stateid) { activedur = ActiveStatesById[stateid]; continue; } 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 ActiveStatesById.Remove(activestateid); entityAttrById.RemoveAttribute("" + activestateid); 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 = activedur + duration; } if (newstate.AccumType == EnumAccumType.Max) { newDuration = Math.Max(activedur, duration); } if (newstate.AccumType == EnumAccumType.NoAccum) { newDuration = activedur > 0 ? activedur : duration; } ActiveStatesById[stateid] = newDuration; entityAttrById.SetFloat("" + stateid, newDuration); entityAttr.SetFloat(newstate.Code, newDuration); triggered = true; } return(triggered); }
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); }
public bool TryTriggerState(string statecode) { EmotionState newstate; if (!availableStates.TryGetValue(statecode, out newstate)) { return(false); } if (entity.World.Rand.NextDouble() > newstate.Chance) { return(false); } float activedur = 0; foreach (string activestatecode in activeStates.Keys) { if (activestatecode == statecode) { activedur = activeStates[activestatecode]; continue; } EmotionState activestate = availableStates[activestatecode]; if (activestate.Slot == newstate.Slot) { // Active state has priority over this one if (activestate.Priority > newstate.Priority) { return(false); } else { // New state has priority activeStates.Remove(activestatecode); entityAttr.RemoveAttribute(activestatecode); break; } } } float newDuration = 0; if (newstate.AccumType == EnumAccumType.Sum) { newDuration = activedur + newstate.Duration; } if (newstate.AccumType == EnumAccumType.Max) { newDuration = Math.Max(activedur, newstate.Duration); } if (newstate.AccumType == EnumAccumType.NoAccum) { newDuration = activedur > 0 ? activedur : newstate.Duration; } activeStates[statecode] = newDuration; entityAttr.SetFloat(statecode, newDuration); return(true); }