public bool CanPerkBeUpgraded(Data.Entities.Perk perk, PCPerk pcPerk, PlayerCharacter player) { int rank = pcPerk?.PerkLevel ?? 0; int maxRank = perk.PerkLevels.Count; if (rank + 1 > maxRank) { return(false); } PerkLevel level = FindPerkLevel(perk.PerkLevels, rank + 1); if (level == null) { return(false); } if (player.UnallocatedSP < level.Price) { return(false); } foreach (PerkLevelSkillRequirement req in level.PerkLevelSkillRequirements) { PCSkill pcSkill = _db.PCSkills.Single(x => x.PlayerID == player.PlayerID && x.SkillID == req.SkillID); if (pcSkill.Rank < req.RequiredRank) { return(false); } } return(true); }
private static void OnHitCastSpell() { NWPlayer oPC = Object.OBJECT_SELF; if (!oPC.IsValid) { return; } NWObject oTarget = _.GetSpellTargetObject(); NWItem oItem = _.GetSpellCastItem(); // If this method was triggered by our own armor (from getting hit), return. if (oItem.BaseItemType == BASE_ITEM_ARMOR) { return; } // Flag this attack as physical so that the damage scripts treat it properly. LoggingService.Trace(TraceComponent.LastAttack, "Setting attack type from " + oPC.GlobalID + " against " + _.GetName(oTarget) + " to physical (" + ATTACK_PHYSICAL.ToString() + ")"); oTarget.SetLocalInt(LAST_ATTACK + oPC.GlobalID, ATTACK_PHYSICAL); HandleGrenadeProficiency(oPC, oTarget); HandlePlasmaCellPerk(oPC, oTarget); int activeWeaponSkillID = oPC.GetLocalInt("ACTIVE_WEAPON_SKILL"); if (activeWeaponSkillID <= 0) { return; } int activeWeaponSkillFeatID = oPC.GetLocalInt("ACTIVE_WEAPON_SKILL_FEAT_ID"); if (activeWeaponSkillFeatID < 0) { activeWeaponSkillFeatID = -1; } PCPerk entity = DataService.GetAll <PCPerk>().Single(x => x.PlayerID == oPC.GlobalID && x.PerkID == activeWeaponSkillID); var perk = DataService.Get <Data.Entity.Perk>(entity.PerkID); var handler = PerkService.GetPerkHandler(activeWeaponSkillID); if (handler.CanCastSpell(oPC, oTarget)) { handler.OnImpact(oPC, oTarget, entity.PerkLevel, activeWeaponSkillFeatID); if (oTarget.IsNPC) { ApplyEnmity(oPC, oTarget.Object, perk); } } else { oPC.SendMessage(handler.CannotCastSpellMessage(oPC, oTarget) ?? "That ability cannot be used at this time."); } oPC.DeleteLocalString("ACTIVE_WEAPON_SKILL_UUID"); oPC.DeleteLocalInt("ACTIVE_WEAPON_SKILL"); oPC.DeleteLocalInt("ACTIVE_WEAPON_SKILL_FEAT_ID"); }
public void GetByID_OneItem_ReturnsPCPerk() { // Arrange var id = Guid.NewGuid(); PCPerk entity = new PCPerk { ID = id }; // Act MessageHub.Instance.Publish(new OnCacheObjectSet <PCPerk>(entity)); // Assert Assert.AreNotSame(entity, _cache.GetByID(id)); }
public void GetByID_TwoItems_ReturnsCorrectObject() { // Arrange var id1 = Guid.NewGuid(); var id2 = Guid.NewGuid(); PCPerk entity1 = new PCPerk { ID = id1 }; PCPerk entity2 = new PCPerk { ID = id2 }; // Act MessageHub.Instance.Publish(new OnCacheObjectSet <PCPerk>(entity1)); MessageHub.Instance.Publish(new OnCacheObjectSet <PCPerk>(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(); PCPerk entity1 = new PCPerk { ID = id1 }; PCPerk entity2 = new PCPerk { ID = id2 }; // Act MessageHub.Instance.Publish(new OnCacheObjectSet <PCPerk>(entity1)); MessageHub.Instance.Publish(new OnCacheObjectSet <PCPerk>(entity2)); MessageHub.Instance.Publish(new OnCacheObjectDeleted <PCPerk>(entity1)); // Assert Assert.Throws <KeyNotFoundException>(() => { _cache.GetByID(id1); }); Assert.AreNotSame(entity2, _cache.GetByID(id2)); }
public void OnHitCastSpell(NWPlayer oPC) { NWObject oTarget = _.GetSpellTargetObject(); HandleGrenadeProficiency(oPC, oTarget); HandlePlasmaCellPerk(oPC, oTarget); int activeWeaponSkillID = oPC.GetLocalInt("ACTIVE_WEAPON_SKILL"); if (activeWeaponSkillID <= 0) { return; } PCPerk entity = _data.GetAll <PCPerk>().Single(x => x.PlayerID == oPC.GlobalID && x.PerkID == activeWeaponSkillID); var perk = _data.Get <Data.Entity.Perk>(entity.PerkID); App.ResolveByInterface <IPerk>("Perk." + perk.ScriptName, (script) => { if (script.CanCastSpell(oPC, oTarget)) { script.OnImpact(oPC, oTarget, entity.PerkLevel); if (oTarget.IsNPC) { ApplyEnmity(oPC, oTarget.Object, perk); } } else { oPC.SendMessage(script.CannotCastSpellMessage(oPC, oTarget) ?? "That ability cannot be used at this time."); } oPC.DeleteLocalString("ACTIVE_WEAPON_SKILL_UUID"); oPC.DeleteLocalInt("ACTIVE_WEAPON_SKILL"); }); }
private void BuildPerkDetails() { Model vm = GetDialogCustomData <Model>(); Data.Entity.Perk perk = _perk.GetPerkByID(vm.SelectedPerkID); PCPerk pcPerk = _perk.GetPCPerkByID(GetPC().GlobalID, perk.ID); Player player = _player.GetPlayerEntity(GetPC().GlobalID); var perkLevels = _data.Where <PerkLevel>(x => x.PerkID == perk.ID).ToList(); int rank = pcPerk?.PerkLevel ?? 0; int maxRank = perkLevels.Count(); string currentBonus = "N/A"; string nextBonus = "N/A"; string price = "N/A"; PerkLevel currentPerkLevel = _perk.FindPerkLevel(perkLevels, rank); PerkLevel nextPerkLevel = _perk.FindPerkLevel(perkLevels, rank + 1); SetResponseVisible("PerkDetailsPage", 1, _perk.CanPerkBeUpgraded(GetPC(), vm.SelectedPerkID)); if (rank > 0) { if (currentPerkLevel != null) { currentBonus = currentPerkLevel.Description; } } if (rank + 1 <= maxRank) { if (nextPerkLevel != null) { nextBonus = nextPerkLevel.Description; price = nextPerkLevel.Price + " SP (Available: " + player.UnallocatedSP + " SP)"; } } var perkCategory = _data.Get <PerkCategory>(perk.PerkCategoryID); var cooldownCategory = perk.CooldownCategoryID == null ? null : _data.Get <CooldownCategory>(perk.CooldownCategoryID); string header = _color.Green("Name: ") + perk.Name + "\n" + _color.Green("Category: ") + perkCategory.Name + "\n" + _color.Green("Rank: ") + rank + " / " + maxRank + "\n" + _color.Green("Price: ") + price + "\n" + (perk.BaseFPCost > 0 ? _color.Green("FP: ") + perk.BaseFPCost : "") + "\n" + (cooldownCategory != null && cooldownCategory.BaseCooldownTime > 0 ? _color.Green("Cooldown: ") + cooldownCategory.BaseCooldownTime + "s" : "") + "\n" + _color.Green("Description: ") + perk.Description + "\n" + _color.Green("Current Bonus: ") + currentBonus + "\n" + _color.Green("Next Bonus: ") + nextBonus + "\n"; if (nextPerkLevel != null) { List <PerkLevelSkillRequirement> requirements = _data.Where <PerkLevelSkillRequirement>(x => x.PerkLevelID == nextPerkLevel.ID).ToList(); if (requirements.Count > 0) { header += "\n" + _color.Green("Next Upgrade Skill Requirements:\n\n"); bool hasRequirement = false; foreach (PerkLevelSkillRequirement req in requirements) { if (req.RequiredRank > 0) { PCSkill pcSkill = _skill.GetPCSkill(GetPC(), req.SkillID); Skill skill = _skill.GetSkill(pcSkill.SkillID); string detailLine = skill.Name + " Rank " + req.RequiredRank; if (pcSkill.Rank >= req.RequiredRank) { header += _color.Green(detailLine) + "\n"; } else { header += _color.Red(detailLine) + "\n"; } hasRequirement = true; } } if (requirements.Count <= 0 || !hasRequirement) { header += "None\n"; } } } SetPageHeader("PerkDetailsPage", header); }
private static void OnHitCastSpell() { NWPlayer oPC = _.OBJECT_SELF; if (!oPC.IsValid) { return; } NWObject oTarget = _.GetSpellTargetObject(); NWItem oItem = _.GetSpellCastItem(); // If this method was triggered by our own armor (from getting hit), return. if (oItem.BaseItemType == BaseItem.Armor) { return; } // Flag this attack as physical so that the damage scripts treat it properly. LoggingService.Trace(TraceComponent.LastAttack, "Setting attack type from " + oPC.GlobalID + " against " + _.GetName(oTarget) + " to physical (" + ATTACK_PHYSICAL.ToString() + ")"); oTarget.SetLocalInt(LAST_ATTACK + oPC.GlobalID, ATTACK_PHYSICAL); HandleGrenadeProficiency(oPC, oTarget); HandlePlasmaCellPerk(oPC, oTarget); int activeWeaponSkillID = oPC.GetLocalInt("ACTIVE_WEAPON_SKILL"); if (activeWeaponSkillID <= 0) { return; } int activeWeaponSkillFeatID = oPC.GetLocalInt("ACTIVE_WEAPON_SKILL_FEAT_ID"); if (activeWeaponSkillFeatID < 0) { activeWeaponSkillFeatID = -1; } PCPerk entity = DataService.PCPerk.GetByPlayerAndPerkID(oPC.GlobalID, activeWeaponSkillID); var perk = DataService.Perk.GetByID(entity.PerkID); var perkFeat = DataService.PerkFeat.GetByFeatID(activeWeaponSkillFeatID); var handler = PerkService.GetPerkHandler(activeWeaponSkillID); string canCast = handler.CanCastSpell(oPC, oTarget, perkFeat.PerkLevelUnlocked); if (string.IsNullOrWhiteSpace(canCast)) { handler.OnImpact(oPC, oTarget, entity.PerkLevel, perkFeat.PerkLevelUnlocked); if (oTarget.IsNPC) { ApplyEnmity(oPC, oTarget.Object, perk); } } else { oPC.SendMessage(canCast); } oPC.DeleteLocalString("ACTIVE_WEAPON_SKILL_UUID"); oPC.DeleteLocalInt("ACTIVE_WEAPON_SKILL"); oPC.DeleteLocalInt("ACTIVE_WEAPON_SKILL_FEAT_ID"); }
public void DoPerkUpgrade(NWPlayer oPC, int perkID) { Data.Entities.Perk perk = _db.Perks.Single(x => x.PerkID == perkID); PCPerk pcPerk = _db.PCPerks.SingleOrDefault(x => x.PlayerID == oPC.GlobalID && x.PerkID == perkID); PlayerCharacter player = _db.PlayerCharacters.Single(x => x.PlayerID == oPC.GlobalID); if (CanPerkBeUpgraded(perk, pcPerk, player)) { if (pcPerk == null) { pcPerk = new PCPerk(); DateTime dt = DateTime.UtcNow; pcPerk.AcquiredDate = dt; pcPerk.PerkID = perk.PerkID; pcPerk.PlayerID = oPC.GlobalID; pcPerk.PerkLevel = 0; _db.PCPerks.Add(pcPerk); } PerkLevel nextPerkLevel = FindPerkLevel(perk.PerkLevels, pcPerk.PerkLevel + 1); if (nextPerkLevel == null) { return; } pcPerk.PerkLevel++; player.UnallocatedSP -= nextPerkLevel.Price; _db.SaveChanges(); // If a perk is activatable, create the item on the PC. // Remove any existing cast spell unique power properties and add the correct one based on the DB flag. if (!string.IsNullOrWhiteSpace(perk.ItemResref)) { if (_.GetIsObjectValid(_.GetItemPossessedBy(oPC.Object, perk.ItemResref)) == FALSE) { NWItem spellItem = NWItem.Wrap(_.CreateItemOnObject(perk.ItemResref, oPC.Object)); spellItem.IsCursed = true; spellItem.SetLocalInt("ACTIVATION_PERK_ID", perk.PerkID); foreach (ItemProperty ipCur in spellItem.ItemProperties) { int ipType = _.GetItemPropertyType(ipCur); int ipSubType = _.GetItemPropertySubType(ipCur); if (ipType == ITEM_PROPERTY_CAST_SPELL && (ipSubType == IP_CONST_CASTSPELL_UNIQUE_POWER || ipSubType == IP_CONST_CASTSPELL_UNIQUE_POWER_SELF_ONLY || ipSubType == IP_CONST_CASTSPELL_ACTIVATE_ITEM)) { _.RemoveItemProperty(spellItem.Object, ipCur); } } ItemProperty ip; if (perk.IsTargetSelfOnly) { ip = _.ItemPropertyCastSpell(IP_CONST_CASTSPELL_UNIQUE_POWER_SELF_ONLY, IP_CONST_CASTSPELL_NUMUSES_UNLIMITED_USE); } else { ip = _.ItemPropertyCastSpell(IP_CONST_CASTSPELL_UNIQUE_POWER, IP_CONST_CASTSPELL_NUMUSES_UNLIMITED_USE); } _biowareXP2.IPSafeAddItemProperty(spellItem, ip, 0.0f, AddItemPropertyPolicy.ReplaceExisting, false, false); } _.SetName(_.GetItemPossessedBy(oPC.Object, perk.ItemResref), perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")"); } oPC.SendMessage(_color.Green("Perk Purchased: " + perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")")); IPerk perkScript = App.ResolveByInterface <IPerk>("Perk." + perk.JavaScriptName); if (perkScript == null) { return; } perkScript.OnPurchased(oPC, pcPerk.PerkLevel); } else { oPC.FloatingText(_color.Red("You cannot purchase the perk at this time.")); } }
public static void DoPerkUpgrade(NWPlayer oPC, int perkID, bool freeUpgrade = false) { var perk = DataService.Single <Data.Entity.Perk>(x => x.ID == perkID); var perkLevels = DataService.Where <PerkLevel>(x => x.PerkID == perkID); var pcPerk = DataService.SingleOrDefault <PCPerk>(x => x.PlayerID == oPC.GlobalID && x.PerkID == perkID); var player = DataService.Single <Player>(x => x.ID == oPC.GlobalID); if (freeUpgrade || CanPerkBeUpgraded(oPC, perkID)) { DatabaseActionType action = DatabaseActionType.Update; if (pcPerk == null) { pcPerk = new PCPerk(); DateTime dt = DateTime.UtcNow; pcPerk.AcquiredDate = dt; pcPerk.PerkID = perk.ID; pcPerk.PlayerID = oPC.GlobalID; pcPerk.PerkLevel = 0; action = DatabaseActionType.Insert; } PerkLevel nextPerkLevel = FindPerkLevel(perkLevels, pcPerk.PerkLevel + 1); if (nextPerkLevel == null) { return; } pcPerk.PerkLevel++; DataService.SubmitDataChange(pcPerk, action); if (!freeUpgrade) { player.UnallocatedSP -= nextPerkLevel.Price; DataService.SubmitDataChange(player, DatabaseActionType.Update); } // Look for any perk levels to grant. var perkFeatsToGrant = DataService.Where <PerkFeat>(x => x.PerkID == perkID && x.PerkLevelUnlocked == pcPerk.PerkLevel); // If at least one feat ID is assigned, add the feat(s) to the player if it doesn't exist yet. if (perkFeatsToGrant.Count > 0) { foreach (var perkFeat in perkFeatsToGrant) { if (_.GetHasFeat(perkFeat.FeatID, oPC.Object) == TRUE) { continue; } NWNXCreature.AddFeatByLevel(oPC, perkFeat.FeatID, 1); var qbs = NWNXPlayerQuickBarSlot.UseFeat(perkFeat.FeatID); // Try to add the new feat to the player's hotbar. if (NWNXPlayer.GetQuickBarSlot(oPC, 0).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 0, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 1).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 1, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 2).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 2, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 3).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 3, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 4).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 4, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 5).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 5, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 6).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 6, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 7).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 7, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 8).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 8, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 9).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 9, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 10).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 10, qbs); } } } oPC.SendMessage(ColorTokenService.Green("Perk Purchased: " + perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")")); var handler = GetPerkHandler(perkID); handler.OnPurchased(oPC, pcPerk.PerkLevel); MessageHub.Instance.Publish(new PerkUpgradedMessage(oPC, perkID)); } else { oPC.FloatingText(ColorTokenService.Red("You cannot purchase the perk at this time.")); } }
public void DoPerkUpgrade(NWPlayer oPC, int perkID, bool freeUpgrade = false) { var perk = _data.Single <Data.Entity.Perk>(x => x.ID == perkID); var perkLevels = _data.Where <PerkLevel>(x => x.PerkID == perkID); var pcPerk = _data.SingleOrDefault <PCPerk>(x => x.PlayerID == oPC.GlobalID && x.PerkID == perkID); var player = _data.Single <Player>(x => x.ID == oPC.GlobalID); if (freeUpgrade || CanPerkBeUpgraded(oPC, perkID)) { DatabaseActionType action = DatabaseActionType.Update; if (pcPerk == null) { pcPerk = new PCPerk(); DateTime dt = DateTime.UtcNow; pcPerk.AcquiredDate = dt; pcPerk.PerkID = perk.ID; pcPerk.PlayerID = oPC.GlobalID; pcPerk.PerkLevel = 0; action = DatabaseActionType.Insert; } PerkLevel nextPerkLevel = FindPerkLevel(perkLevels, pcPerk.PerkLevel + 1); if (nextPerkLevel == null) { return; } pcPerk.PerkLevel++; _data.SubmitDataChange(pcPerk, action); if (!freeUpgrade) { player.UnallocatedSP -= nextPerkLevel.Price; _data.SubmitDataChange(player, DatabaseActionType.Update); } // If a perk is activatable, create the item on the PC. // Remove any existing cast spell unique power properties and add the correct one based on the DB flag. if (!string.IsNullOrWhiteSpace(perk.ItemResref)) { if (_.GetIsObjectValid(_.GetItemPossessedBy(oPC.Object, perk.ItemResref)) == FALSE) { NWItem spellItem = (_.CreateItemOnObject(perk.ItemResref, oPC.Object)); spellItem.IsCursed = true; spellItem.SetLocalInt("ACTIVATION_PERK_ID", perk.ID); foreach (ItemProperty ipCur in spellItem.ItemProperties) { int ipType = _.GetItemPropertyType(ipCur); int ipSubType = _.GetItemPropertySubType(ipCur); if (ipType == ITEM_PROPERTY_CAST_SPELL && (ipSubType == IP_CONST_CASTSPELL_UNIQUE_POWER || ipSubType == IP_CONST_CASTSPELL_UNIQUE_POWER_SELF_ONLY || ipSubType == IP_CONST_CASTSPELL_ACTIVATE_ITEM)) { _.RemoveItemProperty(spellItem.Object, ipCur); } } ItemProperty ip; if (perk.IsTargetSelfOnly) { ip = _.ItemPropertyCastSpell(IP_CONST_CASTSPELL_UNIQUE_POWER_SELF_ONLY, IP_CONST_CASTSPELL_NUMUSES_UNLIMITED_USE); } else { ip = _.ItemPropertyCastSpell(IP_CONST_CASTSPELL_UNIQUE_POWER, IP_CONST_CASTSPELL_NUMUSES_UNLIMITED_USE); } _biowareXP2.IPSafeAddItemProperty(spellItem, ip, 0.0f, AddItemPropertyPolicy.ReplaceExisting, false, false); } _.SetName(_.GetItemPossessedBy(oPC.Object, perk.ItemResref), perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")"); } // If a feat ID is assigned, add the feat to the player if it doesn't exist yet. else if (perk.FeatID != null && perk.FeatID > 0 && _.GetHasFeat((int)perk.FeatID, oPC.Object) == FALSE) { _nwnxCreature.AddFeatByLevel(oPC, (int)perk.FeatID, 1); var qbs = _nwnxQBS.UseFeat((int)perk.FeatID); // Try to add the new feat to the player's hotbar. if (_nwnxPlayer.GetQuickBarSlot(oPC, 0).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 0, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 1).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 1, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 2).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 2, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 3).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 3, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 4).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 4, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 5).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 5, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 6).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 6, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 7).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 7, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 8).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 8, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 9).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 9, qbs); } else if (_nwnxPlayer.GetQuickBarSlot(oPC, 10).ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(oPC, 10, qbs); } } oPC.SendMessage(_color.Green("Perk Purchased: " + perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")")); App.ResolveByInterface <IPerk>("Perk." + perk.ScriptName, (perkScript) => { if (perkScript == null) { return; } perkScript.OnPurchased(oPC, pcPerk.PerkLevel); }); } else { oPC.FloatingText(_color.Red("You cannot purchase the perk at this time.")); } }
private void BuildPerkDetails() { Model vm = GetDialogCustomData <Model>(); Data.Entity.Perk perk = PerkService.GetPerkByID(vm.SelectedPerkID); PCPerk pcPerk = PerkService.GetPCPerkByID(GetPC().GlobalID, perk.ID); Player player = PlayerService.GetPlayerEntity(GetPC().GlobalID); var perkLevels = DataService.Where <PerkLevel>(x => x.PerkID == perk.ID).ToList(); int rank = pcPerk?.PerkLevel ?? 0; int maxRank = perkLevels.Count(); string currentBonus = "N/A"; string currentFPCost = string.Empty; string currentConcentrationCost = string.Empty; string currentSpecializationRequired = "None"; string nextBonus = "N/A"; string nextFPCost = "N/A"; string nextConcentrationCost = string.Empty; string price = "N/A"; string nextSpecializationRequired = "None"; PerkLevel currentPerkLevel = PerkService.FindPerkLevel(perkLevels, rank); PerkLevel nextPerkLevel = PerkService.FindPerkLevel(perkLevels, rank + 1); SetResponseVisible("PerkDetailsPage", 1, PerkService.CanPerkBeUpgraded(GetPC(), vm.SelectedPerkID)); // Player has purchased at least one rank in this perk. Show their current bonuses. if (rank > 0 && currentPerkLevel != null) { var currentPerkFeat = DataService.SingleOrDefault <PerkFeat>(x => x.PerkID == vm.SelectedPerkID && x.PerkLevelUnlocked == currentPerkLevel.Level); currentBonus = currentPerkLevel.Description; // Not every perk is going to have a perk feat. Don't display this information if not necessary. if (currentPerkFeat != null) { currentFPCost = currentPerkFeat.BaseFPCost > 0 ? (ColorTokenService.Green("Current FP: ") + currentPerkFeat.BaseFPCost + "\n") : string.Empty; // If this perk level has a concentration cost and interval, display it on the menu. if (currentPerkFeat.ConcentrationFPCost > 0 && currentPerkFeat.ConcentrationTickInterval > 0) { currentConcentrationCost = ColorTokenService.Green("Current Concentration FP: ") + currentPerkFeat.ConcentrationFPCost + " / " + currentPerkFeat.ConcentrationTickInterval + "s\n"; } } // If this perk level has required specialization, change the text to that. if (currentPerkLevel.SpecializationID > 0) { // Convert ID to enum, then get the string of the enum value. If we ever get a specialization with // more than one word, another process will need to be used. currentSpecializationRequired = ((SpecializationType)currentPerkLevel.SpecializationID).ToString(); } } // Player hasn't reached max rank and this perk has another perk level to display. if (rank + 1 <= maxRank && nextPerkLevel != null) { var nextPerkFeat = DataService.SingleOrDefault <PerkFeat>(x => x.PerkID == vm.SelectedPerkID && x.PerkLevelUnlocked == rank + 1); nextBonus = nextPerkLevel.Description; price = nextPerkLevel.Price + " SP (Available: " + player.UnallocatedSP + " SP)"; if (nextPerkFeat != null) { nextFPCost = nextPerkFeat.BaseFPCost > 0 ? (ColorTokenService.Green("Next FP: ") + nextPerkFeat.BaseFPCost + "\n") : string.Empty; // If this perk level has a concentration cost and interval, display it on the menu. if (nextPerkFeat.ConcentrationFPCost > 0 && nextPerkFeat.ConcentrationTickInterval > 0) { nextConcentrationCost = ColorTokenService.Green("Next Concentration FP: ") + nextPerkFeat.ConcentrationFPCost + " / " + nextPerkFeat.ConcentrationTickInterval + "s\n"; } } if (nextPerkLevel.SpecializationID > 0) { nextSpecializationRequired = ((SpecializationType)nextPerkLevel.SpecializationID).ToString(); } } var perkCategory = DataService.Get <PerkCategory>(perk.PerkCategoryID); var cooldownCategory = perk.CooldownCategoryID == null ? null : DataService.Get <CooldownCategory>(perk.CooldownCategoryID); string header = ColorTokenService.Green("Name: ") + perk.Name + "\n" + ColorTokenService.Green("Category: ") + perkCategory.Name + "\n" + ColorTokenService.Green("Rank: ") + rank + " / " + maxRank + "\n" + ColorTokenService.Green("Price: ") + price + "\n" + currentFPCost + currentConcentrationCost + (cooldownCategory != null && cooldownCategory.BaseCooldownTime > 0 ? ColorTokenService.Green("Cooldown: ") + cooldownCategory.BaseCooldownTime + "s" : "") + "\n" + ColorTokenService.Green("Description: ") + perk.Description + "\n" + ColorTokenService.Green("Current Bonus: ") + currentBonus + "\n" + ColorTokenService.Green("Requires Specialization: ") + currentSpecializationRequired + "\n" + nextFPCost + nextConcentrationCost + ColorTokenService.Green("Next Bonus: ") + nextBonus + "\n" + ColorTokenService.Green("Requires Specialization: ") + nextSpecializationRequired + "\n"; if (nextPerkLevel != null) { List <PerkLevelSkillRequirement> requirements = DataService.Where <PerkLevelSkillRequirement>(x => x.PerkLevelID == nextPerkLevel.ID).ToList(); if (requirements.Count > 0) { header += "\n" + ColorTokenService.Green("Next Upgrade Skill Requirements:\n\n"); bool hasRequirement = false; foreach (PerkLevelSkillRequirement req in requirements) { if (req.RequiredRank > 0) { PCSkill pcSkill = SkillService.GetPCSkill(GetPC(), req.SkillID); Skill skill = SkillService.GetSkill(pcSkill.SkillID); string detailLine = skill.Name + " Rank " + req.RequiredRank; if (pcSkill.Rank >= req.RequiredRank) { header += ColorTokenService.Green(detailLine) + "\n"; } else { header += ColorTokenService.Red(detailLine) + "\n"; } hasRequirement = true; } } if (requirements.Count <= 0 || !hasRequirement) { header += "None\n"; } } } SetPageHeader("PerkDetailsPage", header); }
/// <summary> /// Performs a perk purchase for a player. This handles deducting SP, inserting perk records, /// and adjusting hotbar slots as necessary. /// </summary> /// <param name="oPC">The player receiving the perk upgrade.</param> /// <param name="perkID">The ID number of the perk.</param> /// <param name="freeUpgrade">If true, no SP will be deducted. Otherwise, SP will be deducted from player.</param> public static void DoPerkUpgrade(NWPlayer oPC, int perkID, bool freeUpgrade = false) { var perk = DataService.Perk.GetByID(perkID); var perkLevels = DataService.PerkLevel.GetAllByPerkID(perkID); var pcPerk = DataService.PCPerk.GetByPlayerAndPerkIDOrDefault(oPC.GlobalID, perkID); var player = DataService.Player.GetByID(oPC.GlobalID); if (freeUpgrade || CanPerkBeUpgraded(oPC, perkID)) { DatabaseActionType action = DatabaseActionType.Update; if (pcPerk == null) { pcPerk = new PCPerk(); DateTime dt = DateTime.UtcNow; pcPerk.AcquiredDate = dt; pcPerk.PerkID = perk.ID; pcPerk.PlayerID = oPC.GlobalID; pcPerk.PerkLevel = 0; action = DatabaseActionType.Insert; } PerkLevel nextPerkLevel = FindPerkLevel(perkLevels, pcPerk.PerkLevel + 1); if (nextPerkLevel == null) { return; } pcPerk.PerkLevel++; DataService.SubmitDataChange(pcPerk, action); if (!freeUpgrade) { player.UnallocatedSP -= nextPerkLevel.Price; DataService.SubmitDataChange(player, DatabaseActionType.Update); } // Look for a perk feat to grant. var perkFeatToGrant = DataService.PerkFeat.GetByPerkIDAndLevelUnlockedOrDefault(perkID, pcPerk.PerkLevel); // Add the feat(s) to the player if it doesn't exist yet. if (perkFeatToGrant != null && _.GetHasFeat((Feat)perkFeatToGrant.FeatID, oPC.Object) == false) { NWNXCreature.AddFeatByLevel(oPC, (Feat)perkFeatToGrant.FeatID, 1); var qbs = NWNXPlayerQuickBarSlot.UseFeat((Feat)perkFeatToGrant.FeatID); // Try to add the new feat to the player's hotbar. if (NWNXPlayer.GetQuickBarSlot(oPC, 0).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 0, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 1).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 1, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 2).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 2, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 3).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 3, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 4).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 4, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 5).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 5, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 6).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 6, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 7).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 7, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 8).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 8, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 9).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 9, qbs); } else if (NWNXPlayer.GetQuickBarSlot(oPC, 10).ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(oPC, 10, qbs); } } oPC.SendMessage(ColorTokenService.Green("Perk Purchased: " + perk.Name + " (Lvl. " + pcPerk.PerkLevel + ")")); MessageHub.Instance.Publish(new OnPerkUpgraded(oPC, perkID)); var handler = GetPerkHandler(perkID); handler.OnPurchased(oPC, pcPerk.PerkLevel); } else { oPC.FloatingText(ColorTokenService.Red("You cannot purchase the perk at this time.")); } }