/// <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)); } } }
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(); }
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); }
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)); }
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); } }
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)); }
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)); }
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); } }
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); } }
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); } }); }