Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
                    }
                }
            }
        }
Example #4
0
        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);
            }
        }
Example #5
0
        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);
        }
Example #6
0
        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);
            }
        }
Example #7
0
        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);
            }
        }
Example #8
0
        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);
        }
Example #9
0
        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;
        }
Example #10
0
        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);
                }
            }
        }
Example #11
0
        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);
            }
        }