public static void OpenHomePurchaseMenu() { var player = GetLastUsedBy(); Creature.AddFeatByLevel(player, Feat.PropertyTool, 1); Dialog.StartConversation(player, OBJECT_SELF, nameof(PlayerHouseDialog)); }
private static void GrantBasicFeats(uint player) { Creature.AddFeatByLevel(player, Feat.ArmorProficiencyLight, 1); Creature.AddFeatByLevel(player, Feat.ArmorProficiencyMedium, 1); Creature.AddFeatByLevel(player, Feat.ArmorProficiencyHeavy, 1); Creature.AddFeatByLevel(player, Feat.ShieldProficiency, 1); Creature.AddFeatByLevel(player, Feat.WeaponProficiencyExotic, 1); Creature.AddFeatByLevel(player, Feat.WeaponProficiencyMartial, 1); Creature.AddFeatByLevel(player, Feat.WeaponProficiencySimple, 1); Creature.AddFeatByLevel(player, Feat.UncannyDodge1, 1); Creature.AddFeatByLevel(player, Feat.OpenRestMenu, 1); Creature.AddFeatByLevel(player, Feat.ChatCommandTargeter, 1); }
public static void HandleChatMessage() { uint sender = OBJECT_SELF; string originalMessage = Chat.GetMessage().Trim(); if (!CanHandleChat(sender, originalMessage)) { return; } var split = originalMessage.Split(' ').ToList(); // Commands with no arguments won't be split, so if we didn't split anything then add the command to the split list manually. if (split.Count <= 0) { split.Add(originalMessage); } split[0] = split[0].ToLower(); string command = split[0].Substring(1, split[0].Length - 1); split.RemoveAt(0); Chat.SkipMessage(); if (!ChatCommands.ContainsKey(command)) { SendMessageToPC(sender, ColorToken.Red("Invalid chat command. Use '/help' to get a list of available commands.")); return; } var chatCommand = ChatCommands[command]; string args = string.Join(" ", split); if (!chatCommand.RequiresTarget) { ProcessChatCommand(command, sender, OBJECT_INVALID, null, args); } else { string error = chatCommand.ValidateArguments(sender, split.ToArray()); if (!string.IsNullOrWhiteSpace(error)) { SendMessageToPC(sender, error); return; } SetLocalString(sender, "CHAT_COMMAND", command); SetLocalString(sender, "CHAT_COMMAND_ARGS", command); SendMessageToPC(sender, "Please use your 'Chat Command Targeter' feat to select the target of this chat command."); if (!GetHasFeat(Feat.ChatCommandTargeter, sender) || GetIsDM(sender) || GetIsDMPossessed(sender)) { Creature.AddFeatByLevel(sender, Feat.ChatCommandTargeter, 1); if (GetIsDM(sender) || GetIsDMPossessed(sender)) { var qbs = Player.GetQuickBarSlot(sender, 11); if (qbs.ObjectType == QuickBarSlotType.Empty) { Player.SetQuickBarSlot(sender, 11, PlayerQuickBarSlot.UseFeat(Feat.ChatCommandTargeter)); } } } } }
private void PerkDetailsPageInit(DialogPage page) { var player = GetPC(); var model = GetDataModel <Model>(); var perkDetail = Perk.GetPerkDetails(model.SelectedPerk); var playerId = GetObjectUUID(player); var dbPlayer = DB.Get <Player>(playerId); var categoryDetail = Perk.GetPerkCategoryDetails(model.SelectedCategory); var rank = dbPlayer.Perks.ContainsKey(model.SelectedPerk) ? dbPlayer.Perks[model.SelectedPerk] : 0; var maxRank = perkDetail.PerkLevels.Count; var currentLevel = perkDetail.PerkLevels.ContainsKey(rank) ? perkDetail.PerkLevels[rank] : null; var nextLevel = perkDetail.PerkLevels.ContainsKey(rank + 1) ? perkDetail.PerkLevels[rank + 1] : null; var price = nextLevel == null ? "N/A" : $"{nextLevel.Price} SP (Available: {dbPlayer.UnallocatedSP} SP)"; var meetsRequirements = true; string BuildPerkSection(bool isCurrent, PerkLevel perkLevel) { var currentOrNext = isCurrent ? "Current" : "Next"; var bonus = perkLevel == null ? "N/A" : perkLevel.Description; return(ColorToken.Green($"{currentOrNext} Bonus: ") + bonus + "\n"); } string BuildRequirements(List <IPerkRequirement> requirements) { if (requirements == null) { return(string.Empty); } string text = ColorToken.Green("Requirements:\n\n"); if (requirements.Count <= 0) { text += "N/A"; } foreach (var req in requirements) { var requirementMet = string.IsNullOrWhiteSpace(req.CheckRequirements(player)); var reqText = requirementMet ? ColorToken.Green(req.RequirementText) : ColorToken.Red(req.RequirementText); text += reqText + "\n"; if (!requirementMet) { meetsRequirements = false; } } return(text); } void PurchaseUpgrade() { if (model.IsConfirmingPurchase) { model.IsConfirmingPurchase = false; DoPerkUpgrade(); } else { model.IsConfirmingPurchase = true; } } bool CanUpgrade() { if (!meetsRequirements) { return(false); } if (rank + 1 > maxRank) { return(false); } if (nextLevel == null) { return(false); } if (dbPlayer.UnallocatedSP < nextLevel.Price) { return(false); } return(true); } void DoPerkUpgrade() { if (!CanUpgrade() || nextLevel == null) { FloatingTextStringOnCreature("You do not meet the requirements to purchase this perk upgrade.", player, false); return; } int perkRank = dbPlayer.Perks.ContainsKey(model.SelectedPerk) ? dbPlayer.Perks[model.SelectedPerk] : 0; dbPlayer.Perks[model.SelectedPerk] = perkRank + 1; dbPlayer.UnallocatedSP -= nextLevel.Price; DB.Set(playerId, dbPlayer); GrantFeats(); ApplyPurchasePerkTriggers(dbPlayer.Perks[model.SelectedPerk]); Events.SignalEvent("FFO_BUY_PERK", player); } void GrantFeats() { foreach (var feat in nextLevel.GrantedFeats) { if (GetHasFeat(feat, player)) { continue; } Creature.AddFeatByLevel(player, feat, 1); AddFeatToHotBar(feat); } } void AddFeatToHotBar(Feat feat) { var qbs = PlayerQuickBarSlot.UseFeat(feat); // Try to add the new feat to the player's hotbar. if (Core.NWNX.Player.GetQuickBarSlot(player, 0).ObjectType == QuickBarSlotType.Empty) { Core.NWNX.Player.SetQuickBarSlot(player, 0, qbs); } else if (Core.NWNX.Player.GetQuickBarSlot(player, 1).ObjectType == QuickBarSlotType.Empty) { Core.NWNX.Player.SetQuickBarSlot(player, 1, qbs); } else if (Core.NWNX.Player.GetQuickBarSlot(player, 2).ObjectType == QuickBarSlotType.Empty) { Core.NWNX.Player.SetQuickBarSlot(player, 2, qbs); } else if (Core.NWNX.Player.GetQuickBarSlot(player, 3).ObjectType == QuickBarSlotType.Empty) { Core.NWNX.Player.SetQuickBarSlot(player, 3, qbs); } else if (Core.NWNX.Player.GetQuickBarSlot(player, 4).ObjectType == QuickBarSlotType.Empty) { Core.NWNX.Player.SetQuickBarSlot(player, 4, qbs); } else if (Core.NWNX.Player.GetQuickBarSlot(player, 5).ObjectType == QuickBarSlotType.Empty) { Core.NWNX.Player.SetQuickBarSlot(player, 5, qbs); } else if (Core.NWNX.Player.GetQuickBarSlot(player, 6).ObjectType == QuickBarSlotType.Empty) { Core.NWNX.Player.SetQuickBarSlot(player, 6, qbs); } else if (Core.NWNX.Player.GetQuickBarSlot(player, 7).ObjectType == QuickBarSlotType.Empty) { Core.NWNX.Player.SetQuickBarSlot(player, 7, qbs); } else if (Core.NWNX.Player.GetQuickBarSlot(player, 8).ObjectType == QuickBarSlotType.Empty) { Core.NWNX.Player.SetQuickBarSlot(player, 8, qbs); } else if (Core.NWNX.Player.GetQuickBarSlot(player, 9).ObjectType == QuickBarSlotType.Empty) { Core.NWNX.Player.SetQuickBarSlot(player, 9, qbs); } else if (Core.NWNX.Player.GetQuickBarSlot(player, 10).ObjectType == QuickBarSlotType.Empty) { Core.NWNX.Player.SetQuickBarSlot(player, 10, qbs); } } // Applies any Purchase triggers associated with this perk. void ApplyPurchasePerkTriggers(int perkLevel) { if (perkDetail.PurchasedTriggers.Count > 0) { foreach (var action in perkDetail.PurchasedTriggers) { action(player, model.SelectedPerk, perkLevel); } } } var currentPerkLevelDetails = BuildPerkSection(true, currentLevel); var nextPerkLevelDetails = BuildPerkSection(false, nextLevel); var requirementsSection = BuildRequirements(nextLevel?.Requirements); page.Header = ColorToken.Green("Name: ") + perkDetail.Name + "\n" + ColorToken.Green("Description: ") + perkDetail.Description + "\n" + ColorToken.Green("Category: ") + categoryDetail.Name + "\n" + ColorToken.Green("Rank: ") + rank + " / " + maxRank + "\n" + ColorToken.Green("Price: ") + price + "\n" + currentPerkLevelDetails + "\n" + nextPerkLevelDetails + "\n" + requirementsSection; if (CanUpgrade()) { page.AddResponse(model.IsConfirmingPurchase ? "CONFIRM PURCHASE" : "Purchase Upgrade", PurchaseUpgrade); } }