public void OnModuleHeartbeat() { foreach (var entry in _state.NPCEffects) { CasterSpellVO casterModel = entry.Key; _state.NPCEffects[entry.Key] = entry.Value - 1; Data.Entities.CustomEffect entity = _db.CustomEffects.Single(x => x.CustomEffectID == casterModel.CustomEffectID); ICustomEffect handler = App.ResolveByInterface <ICustomEffect>("CustomEffect." + entity.ScriptHandler); try { handler?.Tick(casterModel.Caster, casterModel.Target); } catch (Exception ex) { _error.LogError(ex, "OnModuleHeartbeat was unable to run specific effect script: " + entity.ScriptHandler); } // Kill the effect if it has expired, target is invalid, or target is dead. if (entry.Value <= 0 || !casterModel.Target.IsValid || casterModel.Target.CurrentHP <= -11) { _state.EffectsToRemove.Add(entry.Key); handler?.WearOff(casterModel.Caster, casterModel.Target); if (casterModel.Caster.IsValid && casterModel.Caster.IsPlayer) { casterModel.Caster.SendMessage("Your effect '" + casterModel.EffectName + "' has worn off of " + casterModel.Target.Name); } casterModel.Target.DeleteLocalInt("CUSTOM_EFFECT_ACTIVE_" + casterModel.CustomEffectID); } } foreach (CasterSpellVO entry in _state.EffectsToRemove) { _state.NPCEffects.Remove(entry); } _state.EffectsToRemove.Clear(); }
public void ApplyCustomEffect(NWCreature oCaster, NWCreature oTarget, int customEffectID, int ticks, int effectLevel) { // Can't apply the effect if the existing one is stronger. int existingEffectLevel = GetActiveEffectLevel(oTarget, customEffectID); if (existingEffectLevel > effectLevel) { oCaster.SendMessage("A more powerful effect already exists on your target."); return; } Data.Entities.CustomEffect effectEntity = _db.CustomEffects.Single(x => x.CustomEffectID == customEffectID); // PC custom effects are tracked in the database. if (oTarget.IsPlayer) { PCCustomEffect entity = _db.PCCustomEffects.SingleOrDefault(x => x.PlayerID == oTarget.GlobalID && x.CustomEffectID == customEffectID); if (entity == null) { entity = new PCCustomEffect { PlayerID = oTarget.GlobalID, CustomEffectID = customEffectID }; _db.PCCustomEffects.Add(entity); } entity.Ticks = ticks; _db.SaveChanges(); oTarget.SendMessage(effectEntity.StartMessage); } // NPCs custom effects are tracked in server memory. else { // Look for existing effect. foreach (var entry in _state.NPCEffects) { CasterSpellVO casterSpellModel = entry.Key; if (casterSpellModel.Caster.Equals(oCaster) && casterSpellModel.CustomEffectID == customEffectID && casterSpellModel.Target.Equals(oTarget)) { _state.NPCEffects[entry.Key] = ticks; return; } } // Didn't find an existing effect. Create a new one. CasterSpellVO spellModel = new CasterSpellVO { Caster = oCaster, CustomEffectID = customEffectID, EffectName = effectEntity.Name, Target = oTarget }; _state.NPCEffects[spellModel] = ticks; } ICustomEffect handler = App.ResolveByInterface <ICustomEffect>("CustomEffect." + effectEntity.ScriptHandler); handler?.Apply(oCaster, oTarget); oTarget.SetLocalInt("CUSTOM_EFFECT_ACTIVE_" + customEffectID, effectLevel); }