public static bool RemoveStance(NWPlayer player, PCCustomEffect stanceEffect = null, bool sendMessage = true) { if (stanceEffect == null) { stanceEffect = DataService.SingleOrDefault <PCCustomEffect>(x => x.PlayerID == player.GlobalID && x.StancePerkID != null); } if (stanceEffect == null) { return(false); } if (sendMessage) { player.SendMessage("You return to your normal stance."); } int effectiveLevel = stanceEffect.EffectiveLevel; string data = stanceEffect.Data; DataService.SubmitDataChange(stanceEffect, DatabaseActionType.Delete); ICustomEffectHandler handler = GetCustomEffectHandler(stanceEffect.CustomEffectID); handler?.WearOff(player, player, effectiveLevel, data); return(true); }
private static PCCustomEffect RunPCCustomEffectProcess(NWPlayer oPC, PCCustomEffect effect) { NWCreature caster = oPC; if (!string.IsNullOrWhiteSpace(effect.CasterNWNObjectID)) { var obj = NWNXObject.StringToObject(effect.CasterNWNObjectID); if (obj.IsValid) { caster = obj.Object; } } if (effect.Ticks > 0) { effect.Ticks = effect.Ticks - 1; } if (effect.Ticks == 0) { return(null); } ICustomEffectHandler handler = CustomEffectService.GetCustomEffectHandler(effect.CustomEffectID); if (!string.IsNullOrWhiteSpace(handler.ContinueMessage) && effect.Ticks % 6 == 0) // Only show the message once every six seconds { oPC.SendMessage(handler.ContinueMessage); } handler?.Tick(caster, oPC, effect.Ticks, effect.EffectiveLevel, effect.Data); return(effect); }
private static void ProcessPCCustomEffects() { foreach (var player in NWModule.Get().Players) { if (!player.IsInitializedAsPlayer) { continue; // Ignored to prevent a timing issue where new characters would be included in this processing. } List <PCCustomEffect> effects = DataService.PCCustomEffect.GetAllByPlayerID(player.GlobalID).Where(x => x.StancePerkID == null).ToList(); foreach (var effect in effects) { if (player.CurrentHP <= -11) { CustomEffectService.RemovePCCustomEffect(player, effect.CustomEffectID); return; } PCCustomEffect result = RunPCCustomEffectProcess(player, effect); if (result == null) { ICustomEffectHandler handler = CustomEffectService.GetCustomEffectHandler(effect.CustomEffectID); string message = handler.WornOffMessage; player.SendMessage(message); player.DeleteLocalInt("CUSTOM_EFFECT_ACTIVE_" + effect.CustomEffectID); DataService.SubmitDataChange(effect, DatabaseActionType.Delete); handler.WearOff(null, player, effect.EffectiveLevel, effect.Data); } else { DataService.SubmitDataChange(effect, DatabaseActionType.Update); } } } }
public static void ApplyStance(NWCreature creature, CustomEffectType customEffect, PerkType perkType, int effectiveLevel, string data) { // Can't process NPC stances at the moment. Need to do some more refactoring before this is possible. // todo: handle NPC stances. if (!creature.IsPlayer) { return; } var pcStanceEffect = DataService.PCCustomEffect.GetByPlayerStanceOrDefault(creature.GlobalID); int customEffectID = (int)customEffect; // Player selected to cancel their stance. Cancel it and end. if (pcStanceEffect != null && pcStanceEffect.CustomEffectID == customEffectID && pcStanceEffect.EffectiveLevel == effectiveLevel) { RemoveStance(creature, pcStanceEffect); return; } // Otherwise remove existing stance else if (pcStanceEffect != null) { RemoveStance(creature, pcStanceEffect, false); } // Player selected to switch stances pcStanceEffect = new PCCustomEffect { PlayerID = creature.GlobalID, Ticks = -1, CustomEffectID = customEffectID, CasterNWNObjectID = _.ObjectToString(creature), EffectiveLevel = effectiveLevel, StancePerkID = (int)perkType }; DataService.SubmitDataChange(pcStanceEffect, DatabaseActionType.Insert); ICustomEffectHandler handler = GetCustomEffectHandler(customEffect); if (string.IsNullOrWhiteSpace(data)) { data = handler.Apply(creature, creature, effectiveLevel); } if (!string.IsNullOrWhiteSpace(handler.StartMessage)) { creature.SendMessage(handler.StartMessage); } if (string.IsNullOrWhiteSpace(data)) { data = string.Empty; } pcStanceEffect.Data = data; DataService.SubmitDataChange(pcStanceEffect, DatabaseActionType.Update); // Was already queued for removal, but got cast again. Take it out of the list to be removed. if (AppCache.PCEffectsForRemoval.Contains(pcStanceEffect.ID)) { AppCache.PCEffectsForRemoval.Remove(pcStanceEffect.ID); } }
public static bool RemoveStance(NWCreature creature, PCCustomEffect stanceEffect = null, bool sendMessage = true) { // Can't process NPC stances at the moment. Need to do some more refactoring before this is possible. // todo: handle NPC stances. if (!creature.IsPlayer) { return(false); } if (stanceEffect == null) { stanceEffect = DataService.PCCustomEffect.GetByPlayerStanceOrDefault(creature.GlobalID); } if (stanceEffect == null) { return(false); } if (sendMessage) { creature.SendMessage("You return to your normal stance."); } int effectiveLevel = stanceEffect.EffectiveLevel; string data = stanceEffect.Data; DataService.SubmitDataChange(stanceEffect, DatabaseActionType.Delete); ICustomEffectHandler handler = GetCustomEffectHandler(stanceEffect.CustomEffectID); handler?.WearOff(creature, creature, effectiveLevel, data); return(true); }
public static void ApplyStance(NWPlayer player, CustomEffectType customEffect, PerkType perkType, int effectiveLevel, string data) { var pcStanceEffect = DataService.SingleOrDefault <PCCustomEffect>(x => x.PlayerID == player.GlobalID && x.StancePerkID != null); int customEffectID = (int)customEffect; // Player selected to cancel their stance. Cancel it and end. if (pcStanceEffect != null && pcStanceEffect.CustomEffectID == customEffectID && pcStanceEffect.EffectiveLevel == effectiveLevel) { RemoveStance(player, pcStanceEffect); return; } // Otherwise remove existing stance else if (pcStanceEffect != null) { RemoveStance(player, pcStanceEffect, false); } // Player selected to switch stances pcStanceEffect = new PCCustomEffect { PlayerID = player.GlobalID, Ticks = -1, CustomEffectID = customEffectID, CasterNWNObjectID = _.ObjectToString(player), EffectiveLevel = effectiveLevel, StancePerkID = (int)perkType }; DataService.SubmitDataChange(pcStanceEffect, DatabaseActionType.Insert); ICustomEffectHandler handler = GetCustomEffectHandler(customEffect); if (string.IsNullOrWhiteSpace(data)) { data = handler.Apply(player, player, effectiveLevel); } if (!string.IsNullOrWhiteSpace(handler.StartMessage)) { player.SendMessage(handler.StartMessage); } if (string.IsNullOrWhiteSpace(data)) { data = string.Empty; } pcStanceEffect.Data = data; DataService.SubmitDataChange(pcStanceEffect, DatabaseActionType.Update); // Was already queued for removal, but got cast again. Take it out of the list to be removed. if (AppCache.PCEffectsForRemoval.Contains(pcStanceEffect.ID)) { AppCache.PCEffectsForRemoval.Remove(pcStanceEffect.ID); } }
private static void RegisterCustomEffectHandlers() { // Use reflection to get all of CustomEffectBehaviour implementations. var classes = Assembly.GetCallingAssembly().GetTypes() .Where(p => typeof(ICustomEffectHandler).IsAssignableFrom(p) && p.IsClass && !p.IsAbstract).ToArray(); foreach (var type in classes) { ICustomEffectHandler instance = Activator.CreateInstance(type) as ICustomEffectHandler; if (instance == null) { throw new NullReferenceException("Unable to activate instance of type: " + type); } _customEffectHandlers.Add(instance.CustomEffectType, instance); } }
private static void OnModuleEnter() { NWPlayer player = _.GetEnteringObject(); if (!player.IsPlayer) { return; } var pcEffect = DataService.PCCustomEffect.GetByPlayerStanceOrDefault(player.GlobalID); if (pcEffect?.StancePerkID == null) { return; } ICustomEffectHandler handler = GetCustomEffectHandler(pcEffect.CustomEffectID); handler?.Apply(player, player, pcEffect.EffectiveLevel); }
private static void ApplyNPCEffect(NWCreature caster, NWCreature target, int customEffectID, int ticks, int effectiveLevel, string data) { Data.Entity.CustomEffect effectEntity = DataService.Single <Data.Entity.CustomEffect>(x => x.ID == customEffectID); // Look for existing effect. var spellModel = AppCache.NPCEffects.SingleOrDefault(x => x.Key.Caster.Equals(caster) && x.Key.CustomEffectID == customEffectID && x.Key.Target.Equals(target)).Key; if (spellModel == null) { spellModel = new CasterSpellVO { Caster = caster, CustomEffectID = customEffectID, EffectName = effectEntity.Name, Target = target, EffectiveLevel = effectiveLevel }; AppCache.NPCEffects.Add(spellModel, 0); } if (spellModel.EffectiveLevel > effectiveLevel) { caster.SendMessage("A more powerful effect already exists on your target."); return; } ICustomEffectHandler handler = GetCustomEffectHandler(customEffectID); if (string.IsNullOrWhiteSpace(data)) { data = handler?.Apply(caster, target, effectiveLevel); } if (string.IsNullOrWhiteSpace(data)) { data = string.Empty; } spellModel.Data = data; AppCache.NPCEffects[spellModel] = ticks; }
private static void ProcessNPCCustomEffects() { for (int index = AppCache.NPCEffects.Count - 1; index >= 0; index--) { var entry = AppCache.NPCEffects.ElementAt(index); CasterSpellVO casterModel = entry.Key; AppCache.NPCEffects[entry.Key] = entry.Value - 1; Data.Entity.CustomEffect entity = DataService.Single <Data.Entity.CustomEffect>(x => x.ID == casterModel.CustomEffectID); ICustomEffectHandler handler = CustomEffectService.GetCustomEffectHandler(casterModel.CustomEffectID); try { handler?.Tick(casterModel.Caster, casterModel.Target, AppCache.NPCEffects[entry.Key], casterModel.EffectiveLevel, casterModel.Data); } catch (Exception ex) { LoggingService.LogError(ex, "CustomEffectService processor was unable to run specific effect script for custom effect ID: " + entity.ID); } // 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) { handler?.WearOff(casterModel.Caster, casterModel.Target, casterModel.EffectiveLevel, casterModel.Data); 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); AppCache.NPCEffects.Remove(entry.Key); } } }
private static void ApplyPCEffect(NWCreature caster, NWCreature target, int customEffectID, int ticks, int effectiveLevel, string data) { Data.Entity.CustomEffect customEffect = DataService.Single <Data.Entity.CustomEffect>(x => x.ID == customEffectID); PCCustomEffect pcEffect = DataService.SingleOrDefault <PCCustomEffect>(x => x.PlayerID == target.GlobalID && x.CustomEffectID == customEffectID); ICustomEffectHandler handler = GetCustomEffectHandler(customEffectID); CustomEffectCategoryType category = handler.CustomEffectCategoryType; if (category == CustomEffectCategoryType.FoodEffect) { var customEffectPC = DataService.Get <Data.Entity.CustomEffect>(pcEffect.CustomEffectID); if (customEffectPC != null) { var foodHandler = GetCustomEffectHandler(customEffectPC.ID); if (foodHandler.CustomEffectCategoryType == category) { caster.SendMessage("You are not hungry."); } return; } } DatabaseActionType action = DatabaseActionType.Update; if (pcEffect == null) { pcEffect = new PCCustomEffect { PlayerID = target.GlobalID }; action = DatabaseActionType.Insert; } if (pcEffect.EffectiveLevel > effectiveLevel) { caster.SendMessage("A more powerful effect already exists on your target."); return; } pcEffect.CustomEffectID = customEffectID; pcEffect.EffectiveLevel = effectiveLevel; pcEffect.Ticks = ticks; pcEffect.CasterNWNObjectID = _.ObjectToString(caster); DataService.SubmitDataChange(pcEffect, action); target.SendMessage(handler.StartMessage); if (string.IsNullOrWhiteSpace(data)) { data = handler?.Apply(caster, target, effectiveLevel); } if (string.IsNullOrWhiteSpace(data)) { data = string.Empty; } pcEffect.Data = data; DataService.SubmitDataChange(pcEffect, DatabaseActionType.Update); // Was already queued for removal, but got cast again. Take it out of the list to be removed. if (AppCache.PCEffectsForRemoval.Contains(pcEffect.ID)) { AppCache.PCEffectsForRemoval.Remove(pcEffect.ID); } }