public static void SetMapPin(NWPlayer oPC, string text, float positionX, float positionY, NWArea area, string tag) { int numberOfMapPins = GetNumberOfMapPins(oPC); int storeAtIndex = -1; for (int index = 0; index < numberOfMapPins; index++) { MapPin mapPin = GetMapPin(oPC, index); if (string.IsNullOrWhiteSpace(mapPin.Text)) { storeAtIndex = index; break; } } if (storeAtIndex == -1) { numberOfMapPins++; storeAtIndex = numberOfMapPins - 1; } storeAtIndex++; oPC.SetLocalString("NW_MAP_PIN_NTRY_" + storeAtIndex, text); oPC.SetLocalFloat("NW_MAP_PIN_XPOS_" + storeAtIndex, positionX); oPC.SetLocalFloat("NW_MAP_PIN_YPOS_" + storeAtIndex, positionY); oPC.SetLocalObject("NW_MAP_PIN_AREA_" + storeAtIndex, area.Object); oPC.SetLocalInt("NW_TOTAL_MAP_PINS", numberOfMapPins); if (tag != null) { oPC.SetLocalString("CUSTOM_NW_MAP_PIN_TAG_" + storeAtIndex, tag); } }
public void OnModuleClientEnter() { NWPlayer oPC = NWPlayer.Wrap(_.GetEnteringObject()); string name = oPC.Name; string cdKey = _.GetPCPublicCDKey(oPC.Object); string account = _.GetPCPlayerName(oPC.Object); DateTime now = DateTime.UtcNow; string nowString = now.ToString("yyyy-MM-dd hh:mm:ss"); // CD Key and accounts are stored as local strings on the PC // because they cannot be retrieved using NWScript functions // on the module OnClientLeave event. oPC.SetLocalString("PC_CD_KEY", cdKey); oPC.SetLocalString("PC_ACCOUNT", account); Console.WriteLine(nowString + ": " + name + " (" + account + "/" + cdKey + ") connected to the server."); ClientLogEvent entity = new ClientLogEvent { AccountName = account, CDKey = cdKey, ClientLogEventTypeID = 1, PlayerID = oPC.IsDM ? null : oPC.GlobalID, DateOfEvent = now }; _db.ClientLogEvents.Add(entity); _db.SaveChanges(); }
private static void OnModuleEnter() { NWPlayer oPC = (GetEnteringObject()); string name = oPC.Name; string cdKey = GetPCPublicCDKey(oPC.Object); string account = GetPCPlayerName(oPC.Object); DateTime now = DateTime.UtcNow; string nowString = now.ToString("yyyy-MM-dd hh:mm:ss"); // CD Key and accounts are stored as local strings on the PC // because they cannot be retrieved using NWScript functions // on the module OnClientLeave event. oPC.SetLocalString("PC_CD_KEY", cdKey); oPC.SetLocalString("PC_ACCOUNT", account); Console.WriteLine(nowString + ": " + name + " (" + account + "/" + cdKey + ") connected to the server."); ModuleEvent entity = new ModuleEvent { AccountName = account, CDKey = cdKey, ModuleEventTypeID = 1, PlayerID = oPC.IsDM ? null : (Guid?)oPC.GlobalID, DateOfEvent = now }; // Bypass the caching logic. DataService.DataQueue.Enqueue(new DatabaseAction(entity, DatabaseActionType.Insert)); }
/// <summary> /// Deletes a player's character. Player must submit the command twice within 30 seconds. /// </summary> /// <param name="user"></param> /// <param name="target"></param> /// <param name="targetLocation"></param> /// <param name="args"></param> public void DoAction(NWPlayer user, NWObject target, NWLocation targetLocation, params string[] args) { string lastSubmission = user.GetLocalString("DELETE_CHARACTER_LAST_SUBMISSION"); bool isFirstSubmission = true; // Check for the last submission, if any. if (!string.IsNullOrWhiteSpace(lastSubmission)) { // Found one, parse it. DateTime dateTime = DateTime.Parse(lastSubmission); if (DateTime.UtcNow <= dateTime.AddSeconds(30)) { // Player submitted a second request within 30 seconds of the last one. // This is a confirmation they want to delete. isFirstSubmission = false; } } // Player hasn't submitted or time has elapsed if (isFirstSubmission) { user.SetLocalString("DELETE_CHARACTER_LAST_SUBMISSION", DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)); user.FloatingText("Please confirm your deletion by entering another \"/delete <CD Key>\" command within 30 seconds."); } else { Player dbPlayer = DataService.Player.GetByID(user.GlobalID); dbPlayer.IsDeleted = true; DataService.SubmitDataChange(dbPlayer, DatabaseActionType.Update); NWNXAdmin.DeletePlayerCharacter(user, true, "Your character has been deleted."); } }
public static void HandleQueueWeaponSkill(NWPlayer pc, Data.Entity.Perk entity, IPerkHandler ability, int spellFeatID) { int? cooldownCategoryID = ability.CooldownCategoryID(pc, entity.CooldownCategoryID, spellFeatID); var cooldownCategory = DataService.Get <CooldownCategory>(cooldownCategoryID); string queueUUID = Guid.NewGuid().ToString(); pc.SetLocalInt("ACTIVE_WEAPON_SKILL", entity.ID); pc.SetLocalString("ACTIVE_WEAPON_SKILL_UUID", queueUUID); pc.SetLocalInt("ACTIVE_WEAPON_SKILL_FEAT_ID", spellFeatID); pc.SendMessage("Weapon skill '" + entity.Name + "' queued for next attack."); ApplyCooldown(pc, cooldownCategory, ability, spellFeatID); // Player must attack within 30 seconds after queueing or else it wears off. _.DelayCommand(30f, () => { if (pc.GetLocalString("ACTIVE_WEAPON_SKILL_UUID") == queueUUID) { pc.DeleteLocalInt("ACTIVE_WEAPON_SKILL"); pc.DeleteLocalString("ACTIVE_WEAPON_SKILL_UUID"); pc.DeleteLocalInt("ACTIVE_WEAPON_SKILL_FEAT_ID"); pc.SendMessage("Your weapon skill '" + entity.Name + "' is no longer queued."); } }); }
public void DoAction(NWPlayer user, NWObject target, NWLocation targetLocation, params string[] args) { var lastSubmission = user.GetLocalString("RESTART_SERVER_LAST_SUBMISSION"); var isFirstSubmission = true; // Check for the last submission, if any. if (!string.IsNullOrWhiteSpace(lastSubmission)) { // Found one, parse it. var dateTime = DateTime.Parse(lastSubmission); if (DateTime.UtcNow <= dateTime.AddSeconds(15)) { // Player submitted a second request within 15 seconds of the last one. // This is a confirmation they want to restart. isFirstSubmission = false; } } // Player hasn't submitted or time has elapsed if (isFirstSubmission) { user.SetLocalString("RESTART_SERVER_LAST_SUBMISSION", DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)); user.FloatingText("Please confirm server reset by entering another \"/restartserver <CD Key>\" command within 15 seconds."); } else { foreach (var player in NWModule.Get().Players) { _.BootPC(player, $"A DM has restarted the server. Please reconnect shortly."); } NWNXAdmin.ShutdownServer(); } }
public static void DeleteMapPin(NWPlayer oPC, int index) { int numberOfPins = GetNumberOfMapPins(oPC); if (index > numberOfPins - 1) { return; } MapPin mapPin = GetMapPin(oPC, index); if (mapPin != null) { oPC.SetLocalString("NW_MAP_PIN_NTRY_" + index, string.Empty); } }
private static void OnModuleNWNXChat() { NWPlayer player = NWNXChat.GetSender().Object; if (!CanHandleChat(player)) { return; } string message = NWNXChat.GetMessage(); NWNXChat.SkipMessage(); player.SetLocalString("MESSAGE_BOARD_TEXT", message); player.SendMessage("Please click the 'Set Title' or 'Set Message' option in the menu."); }
private static void OnModuleNWNXChat() { NWPlayer player = NWNXChat.GetSender().Object; if (!CanHandleChat(player)) { return; } string message = NWNXChat.GetMessage(); NWNXChat.SkipMessage(); message = message.Truncate(50); player.SetLocalString("RENAMED_ITEM_NEW_NAME", message); player.SendMessage("Please click 'Refresh' to see changes, then select 'Change Name' to confirm the changes."); }
public void OnModuleNWNXChat(NWPlayer sender) { string text = _nwnxChat.GetMessage().Trim(); if (!CanHandleChat(sender, text)) { return; } _nwnxChat.SkipMessage(); if (text.Length > 32) { sender.FloatingText("Container names must be 32 characters or less."); return; } sender.SetLocalString("NEW_CONTAINER_NAME", text); sender.SendMessage("New container name received. Please press the 'Next' button in the conversation window."); }
public void OnModuleChat() { NWPlayer sender = (_.GetPCChatSpeaker()); if (sender.GetLocalInt("LISTENING_FOR_DESCRIPTION") != 1) { return; } if (!sender.IsPlayer) { return; } string text = _.GetPCChatMessage().Trim(); sender.SetLocalString("NEW_DESCRIPTION_TO_SET", text); _.SetPCChatMessage(string.Empty); // Skip the message _.SendMessageToPC(sender.Object, "New description received. Please press the 'Next' button in the conversation window."); }
private void HandleQueueWeaponSkill(NWPlayer pc, Data.Entities.Perk entity, IPerk ability) { string queueUUID = Guid.NewGuid().ToString(); pc.SetLocalInt("ACTIVE_WEAPON_SKILL", entity.PerkID); pc.SetLocalString("ACTIVE_WEAPON_SKILL_UUID", queueUUID); pc.SendMessage("Weapon skill '" + entity.Name + "' queued for next attack."); ApplyCooldown(pc, entity.CooldownCategory, ability); // Player must attack within 30 seconds after queueing or else it wears off. pc.DelayCommand(() => { if (pc.GetLocalString("ACTIVE_WEAPON_SKILL_UUID") == queueUUID) { pc.DeleteLocalInt("ACTIVE_WEAPON_SKILL"); pc.DeleteLocalString("ACTIVE_WEAPON_SKILL_UUID"); pc.SendMessage("Your weapon skill '" + entity.Name + "' is no longer queued."); } }, 30.0f); }
public void Main() { NWPlayer oPC = GetLastUsedBy(); if (GetIsInCombat(oPC) == true) { SendMessageToPC(oPC, "You are in combat."); return; } NWPlaceable self = OBJECT_SELF; string destination = self.GetLocalString("DESTINATION"); var visualEffectID = self.GetLocalInt("VISUAL_EFFECT") > 0 ? (VisualEffect)self.GetLocalInt("VISUAL_EFFECT") : VisualEffect.Invalid; int keyItemID = self.GetLocalInt("KEY_ITEM_ID"); string missingKeyItemMessage = self.GetLocalString("MISSING_KEY_ITEM_MESSAGE"); bool isInstance = GetLocalBool(self, "INSTANCE") == true; bool personalInstanceOnly = GetLocalBool(self, "PERSONAL_INSTANCE_ONLY"); if (keyItemID > 0) { if (!KeyItemService.PlayerHasKeyItem(oPC, keyItemID)) { if (!string.IsNullOrWhiteSpace(missingKeyItemMessage)) { oPC.SendMessage(missingKeyItemMessage); } else { oPC.SendMessage("You don't have the necessary key item to access that object."); } return; } } if (visualEffectID > 0) { ApplyEffectToObject(DurationType.Instant, EffectVisualEffect(visualEffectID), oPC.Object); } NWObject entranceWP = GetWaypointByTag(destination); NWLocation location = GetLocation(entranceWP); if (!entranceWP.IsValid) { oPC.SendMessage("Cannot locate entrance waypoint. Inform an admin."); return; } if (isInstance) { var members = oPC.PartyMembers.Where(x => x.Area.GetLocalString("ORIGINAL_RESREF") == entranceWP.Area.Resref).ToList(); // A party member is in an instance of this type already. // Prompt player to select which instance to enter. if (members.Count >= 1 && !personalInstanceOnly) { oPC.SetLocalString("INSTANCE_RESREF", entranceWP.Area.Resref); oPC.SetLocalString("INSTANCE_DESTINATION_TAG", destination); DialogService.StartConversation(oPC, self, "InstanceSelection"); return; } // Otherwise no instance exists yet or this instance only allows one player. Make a new one for this player. NWArea instance = AreaService.CreateAreaInstance(oPC, entranceWP.Area.Resref, entranceWP.Area.Name, destination); location = instance.GetLocalLocation("INSTANCE_ENTRANCE"); PlayerService.SaveLocation(oPC); } oPC.AssignCommand(() => { ActionJumpToLocation(location); }); }
public bool Run(params object[] args) { NWPlayer oPC = _.GetLastUsedBy(); if (_.GetIsInCombat(oPC) == TRUE) { _.SendMessageToPC(oPC, "You are in combat."); return(false); } NWPlaceable self = Object.OBJECT_SELF; string destination = self.GetLocalString("DESTINATION"); int visualEffectID = self.GetLocalInt("VISUAL_EFFECT"); int keyItemID = self.GetLocalInt("KEY_ITEM_ID"); string missingKeyItemMessage = self.GetLocalString("MISSING_KEY_ITEM_MESSAGE"); bool isInstance = self.GetLocalInt("INSTANCE") == TRUE; if (keyItemID > 0) { if (!_keyItem.PlayerHasKeyItem(oPC, keyItemID)) { if (!string.IsNullOrWhiteSpace(missingKeyItemMessage)) { oPC.SendMessage(missingKeyItemMessage); } else { oPC.SendMessage("You don't have the necessary key item to access that object."); } return(false); } } if (visualEffectID > 0) { _.ApplyEffectToObject(DURATION_TYPE_INSTANT, _.EffectVisualEffect(visualEffectID), oPC.Object); } NWObject entranceWP = _.GetWaypointByTag(destination); NWLocation location = _.GetLocation(entranceWP); if (!entranceWP.IsValid) { oPC.SendMessage("Cannot locate entrance waypoint. Inform an admin."); return(false); } if (isInstance) { var members = oPC.PartyMembers.Where(x => x.GetLocalString("ORIGINAL_RESREF") == entranceWP.Area.Resref).ToList(); // A party member is in an instance of this type already. // Prompt player to select which instance to enter. if (members.Count >= 1) { oPC.SetLocalString("INSTANCE_RESREF", entranceWP.Resref); oPC.SetLocalString("INSTANCE_DESTINATION_TAG", destination); _dialog.StartConversation(oPC, self, "InstanceSelection"); return(false); } // Otherwise no instance exists yet. Make a new one for this player. NWArea instance = _area.CreateAreaInstance(oPC, entranceWP.Area.Resref, entranceWP.Area.Name, destination); location = instance.GetLocalLocation("INSTANCE_ENTRANCE"); _player.SaveLocation(oPC); } oPC.AssignCommand(() => { _.ActionJumpToLocation(location); }); return(true); }
public override void DoAction(NWPlayer player, string pageName, int responseID) { switch (pageName) { case "MainPage": switch (responseID) { // Open Overflow Inventory case 1: NWObject storage = NWObject.Wrap(_.CreateObject(NWScript.OBJECT_TYPE_PLACEABLE, "overflow_storage", player.Location)); player.AssignCommand(() => _.ActionInteractObject(storage.Object)); break; // View Skills case 2: SwitchConversation("ViewSkills"); break; // View Perks case 3: SwitchConversation("ViewPerks"); break; // View Blueprints case 4: SwitchConversation("ViewBlueprints"); break; // Dice Bag case 5: player.SetLocalObject("dmfi_univ_target", player.Object); player.SetLocalLocation("dmfi_univ_location", player.Location); player.SetLocalString("dmfi_univ_conv", "pc_dicebag"); player.AssignCommand(() => { _.ClearAllActions(); _.ActionStartConversation(player.Object, "dmfi_universal", 1, 0); }); break; // Emote Menu case 6: player.SetLocalObject("dmfi_univ_target", player.Object); player.SetLocalLocation("dmfi_univ_location", player.Location); player.SetLocalString("dmfi_univ_conv", "pc_emote"); player.AssignCommand(() => { _.ClearAllActions(); _.ActionStartConversation(player.Object, "dmfi_universal", 1, 0); }); break; // Key Item Categories Page case 7: SwitchConversation("KeyItems"); break; // Modify Clothes case 8: player.AssignCommand(() => _.ActionStartConversation(player.Object, "x0_skill_ctrap", 1, 0)); break; // Character Management case 9: SwitchConversation("CharacterManagement"); break; // Open Trash Can (Destroy Items) case 10: EndConversation(); NWPlaceable trashCan = NWPlaceable.Wrap(_.CreateObject(NWScript.OBJECT_TYPE_PLACEABLE, "reo_trash_can", player.Location)); player.AssignCommand(() => _.ActionInteractObject(trashCan.Object)); _.DelayCommand(0.2f, () => trashCan.IsUseable = false); break; } break; } }
private static void OnModuleNWNXChat() { NWPlayer sender = Object.OBJECT_SELF; string originalMessage = NWNXChat.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); NWNXChat.SkipMessage(); if (!IsChatCommandRegistered(command)) { sender.SendMessage(ColorTokenService.Red("Invalid chat command. Use '/help' to get a list of available commands.")); return; } IChatCommand chatCommand = GetChatCommandHandler(command); string args = string.Join(" ", split); if (!chatCommand.RequiresTarget) { ProcessChatCommand(chatCommand, sender, null, null, args); } else { string error = chatCommand.ValidateArguments(sender, split.ToArray()); if (!string.IsNullOrWhiteSpace(error)) { sender.SendMessage(error); return; } sender.SetLocalString("CHAT_COMMAND", command); sender.SetLocalString("CHAT_COMMAND_ARGS", args); sender.SendMessage("Please use your 'Chat Command Targeter' feat to select the target of this chat command."); if (_.GetHasFeat((int)CustomFeatType.ChatCommandTargeter, sender) == FALSE || sender.IsDM) { NWNXCreature.AddFeatByLevel(sender, (int)CustomFeatType.ChatCommandTargeter, 1); if (sender.IsDM) { var qbs = NWNXPlayer.GetQuickBarSlot(sender, 11); if (qbs.ObjectType == QuickBarSlotType.Empty) { NWNXPlayer.SetQuickBarSlot(sender, 11, NWNXPlayerQuickBarSlot.UseFeat((int)CustomFeatType.ChatCommandTargeter)); } } } } }
public void OnModuleNWNXChat(NWPlayer sender) { string originalMessage = _nwnxChat.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); _nwnxChat.SkipMessage(); if (!App.IsKeyRegistered <IChatCommand>("ChatCommand." + command)) { sender.SendMessage(_color.Red("Invalid chat command. Use '/help' to get a list of available commands.")); return; } App.ResolveByInterface <IChatCommand>("ChatCommand." + command, chatCommand => { string args = string.Join(" ", split); if (!chatCommand.RequiresTarget) { ProcessChatCommand(chatCommand, sender, null, null, args); } else { string error = chatCommand.ValidateArguments(sender, args); if (!string.IsNullOrWhiteSpace(error)) { sender.SendMessage(error); return; } sender.SetLocalString("CHAT_COMMAND", command); sender.SetLocalString("CHAT_COMMAND_ARGS", args); sender.SendMessage("Please use your 'Chat Command Targeter' feat to select the target of this chat command."); if (_.GetHasFeat((int)CustomFeatType.ChatCommandTargeter, sender) == FALSE || sender.IsDM) { _nwnxCreature.AddFeatByLevel(sender, (int)CustomFeatType.ChatCommandTargeter, 1); if (sender.IsDM) { var qbs = _nwnxPlayer.GetQuickBarSlot(sender, 11); if (qbs.ObjectType == QuickBarSlotType.Empty) { _nwnxPlayer.SetQuickBarSlot(sender, 11, _nwnxQBS.UseFeat((int)CustomFeatType.ChatCommandTargeter)); } } } } }); }