Ejemplo n.º 1
0
        /// <summary>
        /// Retrieves the DateTime in which the specified cooldownCategoryID will be available for usel
        /// </summary>
        /// <param name="activator">The creature whose cooldown we're checking.</param>
        /// <param name="cooldownCategoryID">The cooldown category we're checking for.</param>
        /// <returns></returns>
        private static DateTime GetAbilityCooldownUnlocked(NWCreature activator, int cooldownCategoryID)
        {
            // Players: Retrieve info from cache/DB, if it doesn't exist create a new record and insert it. Return unlock date.
            if (activator.IsPlayer)
            {
                PCCooldown pcCooldown = DataService.PCCooldown.GetByPlayerAndCooldownCategoryIDOrDefault(activator.GlobalID, cooldownCategoryID);
                if (pcCooldown == null)
                {
                    pcCooldown = new PCCooldown
                    {
                        CooldownCategoryID = Convert.ToInt32(cooldownCategoryID),
                        DateUnlocked       = DateTime.UtcNow.AddSeconds(-1),
                        PlayerID           = activator.GlobalID
                    };

                    DataService.SubmitDataChange(pcCooldown, DatabaseActionType.Insert);
                }

                return(pcCooldown.DateUnlocked);
            }
            // Creatures: Retrieve info from local variable, convert to DateTime if possible. Return parsed unlock date.
            else
            {
                string unlockDate = activator.GetLocalString("ABILITY_COOLDOWN_ID_" + cooldownCategoryID);
                if (string.IsNullOrWhiteSpace(unlockDate))
                {
                    return(DateTime.UtcNow.AddSeconds(-1));
                }
                else
                {
                    return(DateTime.ParseExact(unlockDate, "yyyy-MM-dd hh:mm:ss", CultureInfo.InvariantCulture));
                }
            }
        }
Ejemplo n.º 2
0
        private void ApplyCooldown(NWPlayer pc, CooldownCategory cooldown, IPerk ability)
        {
            float finalCooldown   = ability.CooldownTime(pc, (float)cooldown.BaseCooldownTime);
            int   cooldownSeconds = (int)finalCooldown;
            int   cooldownMillis  = (int)((finalCooldown - cooldownSeconds) * 100);

            PCCooldown pcCooldown = _db.PCCooldowns.Single(x => x.PlayerID == pc.GlobalID && x.CooldownCategoryID == cooldown.CooldownCategoryID);

            pcCooldown.DateUnlocked = DateTime.UtcNow.AddSeconds(cooldownSeconds).AddMilliseconds(cooldownMillis);
            _db.SaveChanges();
        }
Ejemplo n.º 3
0
        public static void ApplyCooldown(NWPlayer pc, CooldownCategory cooldown, IPerkHandler ability, int spellFeatID)
        {
            float finalCooldown   = ability.CooldownTime(pc, (float)cooldown.BaseCooldownTime, spellFeatID);
            int   cooldownSeconds = (int)finalCooldown;
            int   cooldownMillis  = (int)((finalCooldown - cooldownSeconds) * 100);

            PCCooldown pcCooldown = DataService.GetAll <PCCooldown>().Single(x => x.PlayerID == pc.GlobalID && x.CooldownCategoryID == cooldown.ID);

            pcCooldown.DateUnlocked = DateTime.UtcNow.AddSeconds(cooldownSeconds).AddMilliseconds(cooldownMillis);
            DataService.SubmitDataChange(pcCooldown, DatabaseActionType.Update);
        }
Ejemplo n.º 4
0
        public void GetByID_OneItem_ReturnsPCCooldown()
        {
            // Arrange
            var        id     = Guid.NewGuid();
            PCCooldown entity = new PCCooldown {
                ID = id
            };

            // Act
            MessageHub.Instance.Publish(new OnCacheObjectSet <PCCooldown>(entity));

            // Assert
            Assert.AreNotSame(entity, _cache.GetByID(id));
        }
Ejemplo n.º 5
0
        public static void ApplyCooldown(NWCreature creature, CooldownCategory cooldown, IPerkHandler handler, int spellTier, float armorPenalty)
        {
            if (armorPenalty <= 0.0f)
            {
                armorPenalty = 1.0f;
            }

            // If player has a a cooldown recovery bonus on their equipment, apply that change now.

            if (creature.IsPlayer)
            {
                var effectiveStats = PlayerStatService.GetPlayerItemEffectiveStats(creature.Object);
                if (effectiveStats.CooldownRecovery > 0)
                {
                    armorPenalty -= (effectiveStats.CooldownRecovery * 0.01f);
                }
            }

            // There's a cap of 50% cooldown reduction from equipment.
            if (armorPenalty < 0.5f)
            {
                armorPenalty = 0.5f;
            }

            Console.WriteLine("armorPenalty final = " + armorPenalty);

            float    finalCooldown   = handler.CooldownTime(creature, (float)cooldown.BaseCooldownTime, spellTier) * armorPenalty;
            int      cooldownSeconds = (int)finalCooldown;
            int      cooldownMillis  = (int)((finalCooldown - cooldownSeconds) * 100);
            DateTime unlockDate      = DateTime.UtcNow.AddSeconds(cooldownSeconds).AddMilliseconds(cooldownMillis);

            if (creature.IsPlayer)
            {
                PCCooldown pcCooldown = DataService.Single <PCCooldown>(x => x.PlayerID == creature.GlobalID && x.CooldownCategoryID == cooldown.ID);
                pcCooldown.DateUnlocked = unlockDate;
                DataService.SubmitDataChange(pcCooldown, DatabaseActionType.Update);
            }
            else
            {
                string unlockDateString = unlockDate.ToString("yyyy-MM-dd hh:mm:ss");
                creature.SetLocalString("ABILITY_COOLDOWN_ID_" + (int)handler.PerkType, unlockDateString);
            }
        }
Ejemplo n.º 6
0
        public void GetByID_TwoItems_ReturnsCorrectObject()
        {
            // Arrange
            var        id1     = Guid.NewGuid();
            var        id2     = Guid.NewGuid();
            PCCooldown entity1 = new PCCooldown {
                ID = id1
            };
            PCCooldown entity2 = new PCCooldown {
                ID = id2
            };

            // Act
            MessageHub.Instance.Publish(new OnCacheObjectSet <PCCooldown>(entity1));
            MessageHub.Instance.Publish(new OnCacheObjectSet <PCCooldown>(entity2));

            // Assert
            Assert.AreNotSame(entity1, _cache.GetByID(id1));
            Assert.AreNotSame(entity2, _cache.GetByID(id2));
        }
Ejemplo n.º 7
0
        public void GetByID_RemovedItem_ReturnsCorrectObject()
        {
            // Arrange
            var        id1     = Guid.NewGuid();
            var        id2     = Guid.NewGuid();
            PCCooldown entity1 = new PCCooldown {
                ID = id1
            };
            PCCooldown entity2 = new PCCooldown {
                ID = id2
            };

            // Act
            MessageHub.Instance.Publish(new OnCacheObjectSet <PCCooldown>(entity1));
            MessageHub.Instance.Publish(new OnCacheObjectSet <PCCooldown>(entity2));
            MessageHub.Instance.Publish(new OnCacheObjectDeleted <PCCooldown>(entity1));

            // Assert
            Assert.Throws <KeyNotFoundException>(() => { _cache.GetByID(id1); });
            Assert.AreNotSame(entity2, _cache.GetByID(id2));
        }
Ejemplo n.º 8
0
        public void OnModuleItemActivated()
        {
            NWPlayer pc     = NWPlayer.Wrap(_.GetItemActivator());
            NWItem   item   = NWItem.Wrap(_.GetItemActivated());
            NWPlayer target = NWPlayer.Wrap(_.GetItemActivatedTarget());
            int      perkID = item.GetLocalInt("ACTIVATION_PERK_ID");

            if (perkID <= 0)
            {
                return;
            }

            Data.Entities.Perk perk = _db.Perks.SingleOrDefault(x => x.PerkID == perkID);

            if (perk == null)
            {
                return;
            }

            IPerk perkAction = App.ResolveByInterface <IPerk>("Perk." + perk.JavaScriptName);

            if (perkAction == null)
            {
                return;
            }

            PlayerCharacter playerEntity = _db.PlayerCharacters.Single(x => x.PlayerID == pc.GlobalID);

            if (_perk.GetPCPerkLevel(pc, perk.PerkID) <= 0)
            {
                pc.SendMessage("You do not meet the prerequisites to use this ability.");
                return;
            }

            if (perkAction.IsHostile() && target.IsPlayer)
            {
                if (!_pvpSanctuary.IsPVPAttackAllowed(pc, target))
                {
                    return;
                }
            }

            if (pc.Area.Resref != target.Area.Resref ||
                _.LineOfSightObject(pc.Object, target.Object) == 0)
            {
                pc.SendMessage("You cannot see your target.");
                return;
            }

            if (!perkAction.CanCastSpell(pc, target))
            {
                pc.SendMessage(perkAction.CannotCastSpellMessage() ?? "That ability cannot be used at this time.");
                return;
            }

            int manaCost = perkAction.ManaCost(pc, perkAction.ManaCost(pc, perk.BaseManaCost));

            if (playerEntity.CurrentMana < manaCost)
            {
                pc.SendMessage("You do not have enough mana. (Required: " + manaCost + ". You have: " + playerEntity.CurrentMana + ")");
                return;
            }

            if (pc.IsBusy || pc.CurrentHP <= 0)
            {
                pc.SendMessage("You are too busy to activate that ability.");
                return;
            }

            // Check cooldown
            PCCooldown pcCooldown = _db.PCCooldowns.SingleOrDefault(x => x.PlayerID == pc.GlobalID && x.CooldownCategoryID == perk.CooldownCategoryID);

            if (pcCooldown == null)
            {
                pcCooldown = new PCCooldown
                {
                    CooldownCategoryID = Convert.ToInt32(perk.CooldownCategoryID),
                    DateUnlocked       = DateTime.UtcNow.AddSeconds(-1),
                    PlayerID           = pc.GlobalID
                };

                _db.PCCooldowns.Add(pcCooldown);
                _db.SaveChanges();
            }

            DateTime unlockDateTime = pcCooldown.DateUnlocked;
            DateTime now            = DateTime.UtcNow;

            if (unlockDateTime > now)
            {
                string timeToWait = _time.GetTimeToWaitLongIntervals(now, unlockDateTime, false);
                pc.SendMessage("That ability can be used again in " + timeToWait + ".");
                return;
            }

            // Spells w/ casting time
            if (perk.PerkExecutionType.PerkExecutionTypeID == (int)PerkExecutionType.Spell)
            {
                CastSpell(pc, target, perk, perkAction, perk.CooldownCategory);
            }
            // Combat Abilities w/o casting time
            else if (perk.PerkExecutionType.PerkExecutionTypeID == (int)PerkExecutionType.CombatAbility)
            {
                perkAction.OnImpact(pc, target);

                if (manaCost > 0)
                {
                    playerEntity.CurrentMana = playerEntity.CurrentMana - manaCost;
                    _db.SaveChanges();
                }
                ApplyCooldown(pc, perk.CooldownCategory, perkAction);
            }
            // Queued Weapon Skills
            else if (perk.PerkExecutionType.PerkExecutionTypeID == (int)PerkExecutionType.QueuedWeaponSkill)
            {
                HandleQueueWeaponSkill(pc, perk, perkAction);
            }
        }
Ejemplo n.º 9
0
        private static void OnModuleUseFeat()
        {
            NWPlayer   pc       = Object.OBJECT_SELF;
            NWCreature target   = NWNXEvents.OnFeatUsed_GetTarget().Object;
            int        featID   = NWNXEvents.OnFeatUsed_GetFeatID();
            var        perkFeat = DataService.SingleOrDefault <PerkFeat>(x => x.FeatID == featID);

            if (perkFeat == null)
            {
                return;
            }
            Data.Entity.Perk perk = DataService.GetAll <Data.Entity.Perk>().SingleOrDefault(x => x.ID == perkFeat.PerkID);
            if (perk == null)
            {
                return;
            }

            // Check to see if we are a spaceship.  Spaceships can't use abilities...
            if (pc.GetLocalInt("IS_SHIP") > 0 || pc.GetLocalInt("IS_GUNNER") > 0)
            {
                pc.SendMessage("You cannot use that ability while piloting a ship.");
                return;
            }

            var perkAction = PerkService.GetPerkHandler(perkFeat.PerkID);

            Player playerEntity = DataService.Get <Player>(pc.GlobalID);
            int    pcPerkLevel  = PerkService.GetPCPerkLevel(pc, perk.ID);

            // If player is disabling an existing stance, remove that effect.
            if (perk.ExecutionTypeID == (int)PerkExecutionType.Stance)
            {
                PCCustomEffect stanceEffect = DataService.SingleOrDefault <PCCustomEffect>(x => x.StancePerkID == perk.ID &&
                                                                                           x.PlayerID == pc.GlobalID);

                if (stanceEffect != null)
                {
                    if (CustomEffectService.RemoveStance(pc))
                    {
                        return;
                    }
                }
            }

            if (pcPerkLevel <= 0)
            {
                pc.SendMessage("You do not meet the prerequisites to use this ability.");
                return;
            }

            if (perkAction.IsHostile() && target.IsPlayer)
            {
                if (!PVPSanctuaryService.IsPVPAttackAllowed(pc, target.Object))
                {
                    return;
                }
            }

            if (pc.Area.Resref != target.Area.Resref ||
                _.LineOfSightObject(pc.Object, target.Object) == 0)
            {
                pc.SendMessage("You cannot see your target.");
                return;
            }

            if (!perkAction.CanCastSpell(pc, target))
            {
                pc.SendMessage(perkAction.CannotCastSpellMessage(pc, target) ?? "That ability cannot be used at this time.");
                return;
            }

            int fpCost = perkAction.FPCost(pc, perkAction.FPCost(pc, perk.BaseFPCost, featID), featID);

            if (playerEntity.CurrentFP < fpCost)
            {
                pc.SendMessage("You do not have enough FP. (Required: " + fpCost + ". You have: " + playerEntity.CurrentFP + ")");
                return;
            }

            if (pc.IsBusy || pc.CurrentHP <= 0)
            {
                pc.SendMessage("You are too busy to activate that ability.");
                return;
            }

            // Check cooldown
            int?       cooldownCategoryID = perkAction.CooldownCategoryID(pc, perk.CooldownCategoryID, featID);
            PCCooldown pcCooldown         = DataService.GetAll <PCCooldown>().SingleOrDefault(x => x.PlayerID == pc.GlobalID &&
                                                                                              x.CooldownCategoryID == cooldownCategoryID);

            if (pcCooldown == null)
            {
                pcCooldown = new PCCooldown
                {
                    CooldownCategoryID = Convert.ToInt32(cooldownCategoryID),
                    DateUnlocked       = DateTime.UtcNow.AddSeconds(-1),
                    PlayerID           = pc.GlobalID
                };

                DataService.SubmitDataChange(pcCooldown, DatabaseActionType.Insert);
            }

            DateTime unlockDateTime = pcCooldown.DateUnlocked;
            DateTime now            = DateTime.UtcNow;

            if (unlockDateTime > now)
            {
                string timeToWait = TimeService.GetTimeToWaitLongIntervals(now, unlockDateTime, false);
                pc.SendMessage("That ability can be used in " + timeToWait + ".");
                return;
            }

            // Force Abilities (aka Spells)
            if (perk.ExecutionTypeID == (int)PerkExecutionType.ForceAbility)
            {
                target.SetLocalInt(LAST_ATTACK + pc.GlobalID, ATTACK_FORCE);
                ActivateAbility(pc, target, perk, perkAction, pcPerkLevel, PerkExecutionType.ForceAbility, featID);
            }
            // Combat Abilities
            else if (perk.ExecutionTypeID == (int)PerkExecutionType.CombatAbility)
            {
                target.SetLocalInt(LAST_ATTACK + pc.GlobalID, ATTACK_PHYSICAL);
                ActivateAbility(pc, target, perk, perkAction, pcPerkLevel, PerkExecutionType.CombatAbility, featID);
            }
            // Queued Weapon Skills
            else if (perk.ExecutionTypeID == (int)PerkExecutionType.QueuedWeaponSkill)
            {
                target.SetLocalInt(LAST_ATTACK + pc.GlobalID, ATTACK_PHYSICAL);
                HandleQueueWeaponSkill(pc, perk, perkAction, featID);
            }
            // Stances
            else if (perk.ExecutionTypeID == (int)PerkExecutionType.Stance)
            {
                target.SetLocalInt(LAST_ATTACK + pc.GlobalID, ATTACK_COMBATABILITY);
                ActivateAbility(pc, target, perk, perkAction, pcPerkLevel, PerkExecutionType.Stance, featID);
            }
        }
Ejemplo n.º 10
0
        public void OnModuleUseFeat()
        {
            NWPlayer   pc     = Object.OBJECT_SELF;
            NWCreature target = _nwnxEvents.OnFeatUsed_GetTarget().Object;
            int        featID = _nwnxEvents.OnFeatUsed_GetFeatID();

            Data.Entity.Perk perk = _data.GetAll <Data.Entity.Perk>().SingleOrDefault(x => x.FeatID == featID);
            if (perk == null)
            {
                return;
            }

            App.ResolveByInterface <IPerk>("Perk." + perk.ScriptName, (perkAction) =>
            {
                if (perkAction == null)
                {
                    return;
                }

                Player playerEntity = _data.Get <Player>(pc.GlobalID);
                int pcPerkLevel     = _perk.GetPCPerkLevel(pc, perk.ID);

                // If player is disabling an existing stance, remove that effect.
                if (perk.ExecutionTypeID == (int)PerkExecutionType.Stance)
                {
                    PCCustomEffect stanceEffect = _data.GetAll <PCCustomEffect>().SingleOrDefault(x =>
                    {
                        var customEffect = _data.Get <Data.Entity.CustomEffect>(x.CustomEffectID);

                        return(x.PlayerID == pc.GlobalID &&
                               customEffect.CustomEffectCategoryID == (int)CustomEffectCategoryType.Stance);
                    });

                    if (stanceEffect != null && perk.ID == stanceEffect.StancePerkID)
                    {
                        if (_customEffect.RemoveStance(pc))
                        {
                            return;
                        }
                    }
                }

                if (pcPerkLevel <= 0)
                {
                    pc.SendMessage("You do not meet the prerequisites to use this ability.");
                    return;
                }

                if (perkAction.IsHostile() && target.IsPlayer)
                {
                    if (!_pvpSanctuary.IsPVPAttackAllowed(pc, target.Object))
                    {
                        return;
                    }
                }

                if (pc.Area.Resref != target.Area.Resref ||
                    _.LineOfSightObject(pc.Object, target.Object) == 0)
                {
                    pc.SendMessage("You cannot see your target.");
                    return;
                }

                if (!perkAction.CanCastSpell(pc, target))
                {
                    pc.SendMessage(perkAction.CannotCastSpellMessage(pc, target) ?? "That ability cannot be used at this time.");
                    return;
                }

                int fpCost = perkAction.FPCost(pc, perkAction.FPCost(pc, perk.BaseFPCost));
                if (playerEntity.CurrentFP < fpCost)
                {
                    pc.SendMessage("You do not have enough FP. (Required: " + fpCost + ". You have: " + playerEntity.CurrentFP + ")");
                    return;
                }

                if (pc.IsBusy || pc.CurrentHP <= 0)
                {
                    pc.SendMessage("You are too busy to activate that ability.");
                    return;
                }

                // Check cooldown
                PCCooldown pcCooldown = _data.GetAll <PCCooldown>().SingleOrDefault(x => x.PlayerID == pc.GlobalID && x.CooldownCategoryID == perk.CooldownCategoryID);
                if (pcCooldown == null)
                {
                    pcCooldown = new PCCooldown
                    {
                        CooldownCategoryID = Convert.ToInt32(perk.CooldownCategoryID),
                        DateUnlocked       = DateTime.UtcNow.AddSeconds(-1),
                        PlayerID           = pc.GlobalID
                    };

                    _data.SubmitDataChange(pcCooldown, DatabaseActionType.Insert);
                }

                DateTime unlockDateTime = pcCooldown.DateUnlocked;
                DateTime now            = DateTime.UtcNow;

                if (unlockDateTime > now)
                {
                    string timeToWait = _time.GetTimeToWaitLongIntervals(now, unlockDateTime, false);
                    pc.SendMessage("That ability can be used in " + timeToWait + ".");
                    return;
                }

                // Force Abilities (aka Spells)
                if (perk.ExecutionTypeID == (int)PerkExecutionType.ForceAbility)
                {
                    ActivateAbility(pc, target, perk, perkAction, pcPerkLevel, PerkExecutionType.ForceAbility);
                }
                // Combat Abilities
                else if (perk.ExecutionTypeID == (int)PerkExecutionType.CombatAbility)
                {
                    ActivateAbility(pc, target, perk, perkAction, pcPerkLevel, PerkExecutionType.CombatAbility);
                }
                // Queued Weapon Skills
                else if (perk.ExecutionTypeID == (int)PerkExecutionType.QueuedWeaponSkill)
                {
                    HandleQueueWeaponSkill(pc, perk, perkAction);
                }
                // Stances
                else if (perk.ExecutionTypeID == (int)PerkExecutionType.Stance)
                {
                    ActivateAbility(pc, target, perk, perkAction, pcPerkLevel, PerkExecutionType.Stance);
                }
            });
        }