├── .gitattributes ├── AI Behaviors ├── README.md ├── ai_b_sitonchair.nss └── ai_b_wander.nss ├── Components ├── Core │ ├── README.md │ ├── es_cc_concom.nss │ ├── es_cc_events.nss │ ├── es_cc_pos.nss │ └── es_cc_profiler.nss ├── Services │ ├── README.md │ ├── es_srv_chatcom.nss │ ├── es_srv_elc.nss │ ├── es_srv_gui.nss │ ├── es_srv_instance.nss │ ├── es_srv_mediator.nss │ ├── es_srv_randarmor.nss │ ├── es_srv_randomnpc.nss │ ├── es_srv_simai.nss │ ├── es_srv_simdialog.nss │ ├── es_srv_spellhook.nss │ ├── es_srv_tiles.nss │ ├── es_srv_toolbox.nss │ ├── es_srv_webhook.nss │ └── es_srv_wtimer.nss └── Subsystems │ ├── README.md │ ├── es_s_ambientnpcs.nss │ ├── es_s_areacreator.nss │ ├── es_s_areagen.nss │ ├── es_s_autoiditem.nss │ ├── es_s_charsave.nss │ ├── es_s_closedoor.nss │ ├── es_s_dumplocals.nss │ ├── es_s_emote.nss │ ├── es_s_hpbar.nss │ ├── es_s_iditem.nss │ ├── es_s_intchair.nss │ ├── es_s_kobinv.nss │ ├── es_s_musicplayer.nss │ ├── es_s_objsit.nss │ ├── es_s_persisthp.nss │ ├── es_s_persistloc.nss │ ├── es_s_portrait.nss │ ├── es_s_quickbar.nss │ ├── es_s_sailing.nss │ ├── es_s_spellbook.nss │ ├── es_s_spiders.nss │ ├── es_s_subsysman.nss │ ├── es_s_testing.nss │ └── es_s_travel.nss ├── Core ├── es_inc_array.nss ├── es_inc_core.nss ├── es_inc_effects.nss ├── es_inc_nss.nss ├── es_inc_sqlite.nss ├── es_inc_sqlocals.nss ├── es_inc_test.nss └── es_inc_util.nss ├── LICENSE ├── README.md └── Resources ├── 2DA └── visualeffects.2da ├── Fonts ├── fnt_book.tga ├── fnt_book.txi ├── fnt_es_gui.tga ├── fnt_es_gui.txi ├── fnt_es_hbport.tga ├── fnt_es_hbport.txi ├── fnt_es_icon32.tga ├── fnt_es_icon32.txi ├── fnt_es_portrait.tga ├── fnt_es_portrait.txi ├── fnt_es_text.tga └── fnt_es_text.txi └── cv_simdialog.dlg /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | *.dlg binary 3 | -------------------------------------------------------------------------------- /AI Behaviors/README.md: -------------------------------------------------------------------------------- 1 | # Sample AI Behaviors for the es_srv_simai service 2 | -------------------------------------------------------------------------------- /AI Behaviors/ai_b_sitonchair.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: ai_b_sitonchair.nss 3 | Created by: Daz 4 | 5 | Description: A SimpleAI Behavior that lets NPCs sit on a chair. 6 | */ 7 | 8 | #include "es_srv_simai" 9 | 10 | //void main(){} 11 | 12 | const string AIBEHAVIOR_SITONCHAIR_WAYPOINT_TAG = "WP_AIB_SITONCHAIR"; 13 | 14 | const string AIBEHAVIOR_SITONCHAIR_SEAT_AMOUNT = "AIBSitOnChairSeatAmount"; 15 | const string AIBEHAVIOR_SITONCHAIR_SEAT = "AIBSitOnChairSeat_"; 16 | 17 | const string AIBEHAVIOR_SITONCHAIR_NEXT_MOVE_TICK = "AIBSitOnChairNextMoveTick"; 18 | 19 | object SitOnChair_FindSeat(); 20 | 21 | // @SimAIBehavior_Init 22 | void SitOnChair_Init() 23 | { 24 | int nNth = 0; 25 | object oWaypoint = GetObjectByTag(AIBEHAVIOR_SITONCHAIR_WAYPOINT_TAG, nNth); 26 | 27 | while (GetIsObjectValid(oWaypoint)) 28 | { 29 | object oArea = GetArea(oWaypoint); 30 | 31 | if (!GetLocalInt(oArea, AIBEHAVIOR_SITONCHAIR_SEAT_AMOUNT)) 32 | { 33 | int nNthSeat = 1; 34 | object oSeat = GetNearestObjectByTag("OBJSIT_SINGLE", oWaypoint, nNthSeat); 35 | 36 | while (GetIsObjectValid(oSeat)) 37 | { 38 | int nAmount = GetLocalInt(oArea, AIBEHAVIOR_SITONCHAIR_SEAT_AMOUNT); 39 | 40 | SetLocalInt(oArea, AIBEHAVIOR_SITONCHAIR_SEAT_AMOUNT, ++nAmount); 41 | SetLocalObject(oArea, AIBEHAVIOR_SITONCHAIR_SEAT + IntToString(nAmount), oSeat); 42 | 43 | oSeat = GetNearestObjectByTag("OBJSIT_SINGLE", oWaypoint, ++nNthSeat); 44 | } 45 | } 46 | 47 | oWaypoint = GetObjectByTag(AIBEHAVIOR_SITONCHAIR_WAYPOINT_TAG, ++nNth); 48 | } 49 | } 50 | 51 | // @SimAIBehavior_OnSpawn 52 | void SitOnChair_Spawn() 53 | { 54 | object oSelf = OBJECT_SELF; 55 | 56 | object oClothes = GetLocalObject(oSelf, "AMBIENT_NPC_CLOTHES"); 57 | if (GetIsObjectValid(oClothes)) 58 | ActionEquipItem(oClothes, INVENTORY_SLOT_CHEST); 59 | 60 | SetLocalInt(oSelf, AIBEHAVIOR_SITONCHAIR_NEXT_MOVE_TICK, Random(25) + 10); 61 | 62 | object oSeat = SitOnChair_FindSeat(); 63 | 64 | if (oSeat != OBJECT_INVALID) 65 | { 66 | ActionForceMoveToObject(oSeat, FALSE, 5.0f, 15.0f); 67 | ActionSit(oSeat); 68 | } 69 | else 70 | { 71 | ActionRandomWalk(); 72 | } 73 | } 74 | 75 | void SitOnChair_PlayVoiceChat(int nVoiceChatID, float fNearbyCreatureDistance = 3.0f) 76 | { 77 | object oNearby = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE); 78 | 79 | if (GetIsObjectValid(oNearby)) 80 | { 81 | if (GetDistanceBetween(OBJECT_SELF, oNearby) <= fNearbyCreatureDistance) 82 | SimpleAI_PlayVoiceChat(nVoiceChatID); 83 | } 84 | } 85 | 86 | void SitOnChair_Sit(object oSeat) 87 | { 88 | if (!GetIsObjectValid(GetSittingCreature(oSeat))) 89 | { 90 | ActionSit(oSeat); 91 | SitOnChair_PlayVoiceChat(VOICE_CHAT_HELLO); 92 | } 93 | else 94 | SitOnChair_PlayVoiceChat(VOICE_CHAT_MOVEOVER); 95 | } 96 | 97 | // @SimAIBehavior_OnHeartbeat 98 | void SitOnChair_Heartbeat() 99 | { 100 | if (SimpleAI_GetIsAreaEmpty()) return; 101 | 102 | object oSelf = OBJECT_SELF; 103 | int nAction = GetCurrentAction(); 104 | 105 | if (nAction == ACTION_RANDOMWALK) 106 | { 107 | if (!Random(5)) 108 | { 109 | object oSeat = SitOnChair_FindSeat(); 110 | 111 | if (oSeat != OBJECT_INVALID) 112 | { 113 | ClearAllActions(); 114 | ActionForceMoveToObject(oSeat, FALSE, 5.0f, 30.0f); 115 | ActionDoCommand(SitOnChair_Sit(oSeat)); 116 | } 117 | } 118 | } 119 | else if (nAction == ACTION_SIT) 120 | { 121 | int nRandom = Random(100); 122 | 123 | if (nRandom < 5) 124 | SitOnChair_PlayVoiceChat(VOICE_CHAT_LAUGH); 125 | else 126 | if(nRandom > 97) 127 | SitOnChair_PlayVoiceChat(VOICE_CHAT_CHEER); 128 | 129 | int nTick = SimpleAI_GetTick(); 130 | int nNextMoveTick = GetLocalInt(oSelf, AIBEHAVIOR_SITONCHAIR_NEXT_MOVE_TICK); 131 | 132 | if (nTick > nNextMoveTick) 133 | { 134 | SetLocalInt(oSelf, AIBEHAVIOR_SITONCHAIR_NEXT_MOVE_TICK, Random(25) + 10); 135 | ClearAllActions(); 136 | SitOnChair_PlayVoiceChat(VOICE_CHAT_GOODBYE); 137 | ActionRandomWalk(); 138 | SimpleAI_SetTick(0); 139 | } 140 | else 141 | SimpleAI_SetTick(++nTick); 142 | } 143 | else 144 | if (nAction != ACTION_SIT && nAction != ACTION_MOVETOPOINT && nAction != ACTION_WAIT) 145 | { 146 | ActionRandomWalk(); 147 | } 148 | } 149 | 150 | // @SimAIBehavior_OnConversation 151 | void SitOnChair_Conversation() 152 | { 153 | if (GetCurrentAction() == ACTION_SIT) 154 | ClearAllActions(); 155 | 156 | // Debug 157 | SpeakString("Behavior: " + SimpleAI_GetAIBehavior()); 158 | PrintString("Pelvis: " + IntToString(GetItemAppearance(GetItemInSlot(INVENTORY_SLOT_CHEST), ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_PELVIS)) + 159 | ", Head: " + IntToString(GetCreatureBodyPart(CREATURE_PART_HEAD))); 160 | } 161 | 162 | /* *** */ 163 | 164 | object SitOnChair_FindSeat() 165 | { 166 | object oArea = GetArea(OBJECT_SELF); 167 | int nSeats = GetLocalInt(oArea, AIBEHAVIOR_SITONCHAIR_SEAT_AMOUNT); 168 | int nNumTries = 0, nMaxTries = nSeats / 2; 169 | 170 | object oSeat = GetLocalObject(GetLocalObject(oArea, AIBEHAVIOR_SITONCHAIR_SEAT + IntToString(Random(nSeats))), "OBJSIT_SINGLE_CHAIR"); 171 | 172 | while (GetIsObjectValid(oSeat) && nNumTries < nMaxTries) 173 | { 174 | nNumTries++; 175 | 176 | if (!GetIsObjectValid(GetSittingCreature(oSeat))) 177 | return oSeat; 178 | else 179 | oSeat = GetLocalObject(GetLocalObject(oArea, AIBEHAVIOR_SITONCHAIR_SEAT + IntToString(Random(nSeats))), "OBJSIT_SINGLE_CHAIR"); 180 | } 181 | 182 | return OBJECT_INVALID; 183 | } 184 | 185 | -------------------------------------------------------------------------------- /AI Behaviors/ai_b_wander.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: ai_b_wander.nss 3 | Created by: Daz 4 | 5 | Description: A SimpleAI Behavior that lets NPCs wander. 6 | */ 7 | 8 | #include "es_srv_simai" 9 | 10 | //void main(){} 11 | 12 | const string AIBEHAVIOR_WANDER_WAYPOINT_TAG = "WP_AIB_WANDER"; 13 | 14 | const string AIBEHAVIOR_WANDER_AREA_WAYPOINTS = "AIBWanderWaypoints"; 15 | const string AIBEHAVIOR_WANDER_NEXT_MOVE_TICK = "AIBWanderNextMoveTick"; 16 | 17 | object Wander_GetRandomWaypointInArea(); 18 | 19 | // @SimAIBehavior_Init 20 | void Wander_Init() 21 | { 22 | int nNth = 0; 23 | object oWaypoint = GetObjectByTag(AIBEHAVIOR_WANDER_WAYPOINT_TAG, nNth); 24 | 25 | while (GetIsObjectValid(oWaypoint)) 26 | { 27 | object oArea = GetArea(oWaypoint); 28 | int nWaypoints = GetLocalInt(oArea, AIBEHAVIOR_WANDER_AREA_WAYPOINTS) + 1; 29 | 30 | SetLocalInt(oArea, AIBEHAVIOR_WANDER_AREA_WAYPOINTS, nWaypoints); 31 | SetLocalObject(oArea, AIBEHAVIOR_WANDER_AREA_WAYPOINTS + IntToString(nWaypoints), oWaypoint); 32 | 33 | oWaypoint = GetObjectByTag(AIBEHAVIOR_WANDER_WAYPOINT_TAG, ++nNth); 34 | } 35 | } 36 | 37 | // @SimAIBehavior_OnSpawn 38 | void Wander_Spawn() 39 | { 40 | object oClothes = GetLocalObject(OBJECT_SELF, "AMBIENT_NPC_CLOTHES"); 41 | if (GetIsObjectValid(oClothes)) 42 | ActionEquipItem(oClothes, INVENTORY_SLOT_CHEST); 43 | 44 | SetLocalInt(OBJECT_SELF, AIBEHAVIOR_WANDER_NEXT_MOVE_TICK, Random(20) + 10); 45 | 46 | ActionForceMoveToObject(Wander_GetRandomWaypointInArea(), FALSE, 2.5f, 30.0f); 47 | ActionRandomWalk(); 48 | } 49 | 50 | // @SimAIBehavior_OnHeartbeat 51 | void Wander_Heartbeat() 52 | { 53 | int nAction = GetCurrentAction(); 54 | 55 | if (SimpleAI_GetIsAreaEmpty()) 56 | { 57 | if (nAction != ACTION_INVALID) 58 | ClearAllActions(); 59 | return; 60 | } 61 | 62 | int nTick = SimpleAI_GetTick(); 63 | 64 | if (nAction == ACTION_RANDOMWALK) 65 | { 66 | int nNextMoveTick = GetLocalInt(OBJECT_SELF, AIBEHAVIOR_WANDER_NEXT_MOVE_TICK); 67 | 68 | if (nTick > nNextMoveTick) 69 | { 70 | SetLocalInt(OBJECT_SELF, AIBEHAVIOR_WANDER_NEXT_MOVE_TICK, Random(20) + 10); 71 | SimpleAI_SetTick(0); 72 | 73 | ClearAllActions(); 74 | ActionForceMoveToObject(Wander_GetRandomWaypointInArea(), FALSE, 2.5f, 30.0f); 75 | } 76 | } 77 | else 78 | if (nAction != ACTION_MOVETOPOINT && nAction != ACTION_WAIT) 79 | { 80 | ClearAllActions(); 81 | ActionRandomWalk(); 82 | } 83 | 84 | SimpleAI_SetTick(++nTick); 85 | } 86 | 87 | // @SimAIBehavior_OnConversation 88 | void Wander_Conversation() 89 | { 90 | // Debug 91 | SpeakString("Behavior: " + SimpleAI_GetAIBehavior()); 92 | PrintString("Pelvis: " + IntToString(GetItemAppearance(GetItemInSlot(INVENTORY_SLOT_CHEST), ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_PELVIS)) + 93 | ", Head: " + IntToString(GetCreatureBodyPart(CREATURE_PART_HEAD))); 94 | } 95 | 96 | object Wander_GetRandomWaypointInArea() 97 | { 98 | object oArea = GetArea(OBJECT_SELF); 99 | int nNumWaypoints = GetLocalInt(oArea, AIBEHAVIOR_WANDER_AREA_WAYPOINTS); 100 | object oWaypoint = GetLocalObject(oArea, AIBEHAVIOR_WANDER_AREA_WAYPOINTS + IntToString(Random(nNumWaypoints) + 1)); 101 | 102 | return GetIsObjectValid(oWaypoint) ? oWaypoint : OBJECT_SELF; 103 | } 104 | 105 | -------------------------------------------------------------------------------- /Components/Core/README.md: -------------------------------------------------------------------------------- 1 | # Various EventSystem Core Components that provide core functionality 2 | -------------------------------------------------------------------------------- /Components/Core/es_cc_concom.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_cc_concom.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[Util] 7 | 8 | Description: An EventSystem Core Component that allows Services 9 | and Subsystems to register server console commands 10 | */ 11 | 12 | //void main() {} 13 | 14 | #include "es_inc_core" 15 | 16 | const string CONSOLECOMMAND_LOG_TAG = "ConsoleCommand"; 17 | const string CONSOLECOMMAND_SCRIPT_NAME = "es_cc_concom"; 18 | 19 | const string CONSOLECOMMAND_BASE_COMMAND = "BaseCommand"; 20 | 21 | const string CONSOLECOMMAND_NUM_COMMANDS = "NumCommands"; 22 | const string CONSOLECOMMAND_REGISTERED_COMMAND = "RegisteredCommand_"; 23 | 24 | const string CONSOLECOMMAND_COMMAND = "Command_"; 25 | const string CONSOLECOMMAND_PARAMS = "Params_"; 26 | const string CONSOLECOMMAND_DESCRIPTION = "Description_"; 27 | const string CONSOLECOMMAND_SUBSYSTEM = "Subsystem_"; 28 | const string CONSOLECOMMAND_FUNCTION = "Function_"; 29 | 30 | // Register a console command 31 | // 32 | // sComponentScript: The component the command is from, for example: es_s_example 33 | // sFunction: The function name to execute when the administrator uses the console command. 34 | // The implementation must have the following signature: void (string sArgs) 35 | // Note: DelayCommand/AssignCommand will not work in the function. 36 | // sCommand: The command the administrator must type 37 | // sHelpParams: Optional parameter description for the 'help' console command 38 | // sHelpDescription: A description of what the command does for the 'help' console command 39 | // 40 | // Returns: TRUE on success 41 | void ConsoleCommand_Register(string sComponentScript, string sFunction, string sCommand, string sHelpParams, string sHelpDescription); 42 | 43 | void ConsoleCommand_RegisterBaseCommand(string sCommand, string sHelpParams, string sHelpDescription) 44 | { 45 | ConsoleCommand_Register(CONSOLECOMMAND_BASE_COMMAND, CONSOLECOMMAND_BASE_COMMAND, sCommand, sHelpParams, sHelpDescription); 46 | } 47 | 48 | // @Load 49 | void ConsoleCommand_Load(string sCoreComponentScript) 50 | { 51 | // Register Base Game Commands 52 | ConsoleCommand_RegisterBaseCommand("status", "", "Show information about the server."); 53 | ConsoleCommand_RegisterBaseCommand("clientinfo", "[Player]", "Displays details on the client identified by ID, CDKey or PlayerName."); 54 | ConsoleCommand_RegisterBaseCommand("kick", "[Player]", "Remove a player from the game identified by ID, CDKey or PlayerName."); 55 | ConsoleCommand_RegisterBaseCommand("listbans", "", "List all the current bans for IPs, CDKeys and PlayerNames."); 56 | ConsoleCommand_RegisterBaseCommand("banip", "[IP Address]", "Ban connections from an IP Address (may include *s)."); 57 | ConsoleCommand_RegisterBaseCommand("bankey", "[CDKey]", "Ban connections using a CDKey."); 58 | ConsoleCommand_RegisterBaseCommand("banname", "[PlayerName]", "Ban connections from a PlayerName (may start and/or end with *s)."); 59 | ConsoleCommand_RegisterBaseCommand("unbanip", "[IP Address]", "Remove an IP Address from the list of banned IP Addresses."); 60 | ConsoleCommand_RegisterBaseCommand("unbankey", "[CDKey]", "Remove a CDKey the list of banned CDKeys."); 61 | ConsoleCommand_RegisterBaseCommand("unbanname", "[PlayerName]", "Remove a PlayerName from the list of banned PlayerNames."); 62 | ConsoleCommand_RegisterBaseCommand("save", "[Slot#] [Name]", "Save the current running game as [Name] to [Slot#]."); 63 | ConsoleCommand_RegisterBaseCommand("forcesave", "[Slot#] [Name]", "Save the current running game as [Name], overwriting [Slot#]."); 64 | ConsoleCommand_RegisterBaseCommand("exit", "", "Shut down the server."); 65 | ConsoleCommand_RegisterBaseCommand("quit", "", "Shut down the server."); 66 | ConsoleCommand_RegisterBaseCommand("saveandexit", "[Slot#] [Name]", "Save the current running game as [Name] to [Slot#] and shut down the server."); 67 | ConsoleCommand_RegisterBaseCommand("module", "[ModuleName]", "Load the specified module."); 68 | ConsoleCommand_RegisterBaseCommand("load", "[Slot#]", "Load the specified saved game."); 69 | ConsoleCommand_RegisterBaseCommand("say", "[Message]", "Broadcast a message to all clients."); 70 | ConsoleCommand_RegisterBaseCommand("export", "", "Causes all player characters in the game to be saved."); 71 | ConsoleCommand_RegisterBaseCommand("maxclients", "[NumClients]", "Set the maximum number of connections to the game server."); 72 | ConsoleCommand_RegisterBaseCommand("minlevel", "[MinLevel]", "Set the minimum character level required by the server."); 73 | ConsoleCommand_RegisterBaseCommand("maxlevel", "[MaxLevel]", "Set the maximum character level allowed by the server."); 74 | ConsoleCommand_RegisterBaseCommand("pauseandplay", "[1|0]", "0 = game can only be paused by DMs, 1 = game can by paused by players."); 75 | ConsoleCommand_RegisterBaseCommand("elc", "[1|0]", "0 = don't enforce legal characters, 1 = do enforce legal characters."); 76 | ConsoleCommand_RegisterBaseCommand("ilr", "[1|0]", "0 = don't enforce item level restrictions, 1 = do enforce item level restrictions."); 77 | ConsoleCommand_RegisterBaseCommand("oneparty", "[1|0]", "0 = allow only one party, 1 = allow multiple parties."); 78 | ConsoleCommand_RegisterBaseCommand("difficulty", "[Level]", "1 = easy, 2 = normal, 3 = D&D hardcore, 4 = very difficult."); 79 | ConsoleCommand_RegisterBaseCommand("autosaveinterval", "[Minutes]", "Set how frequently (in minutes) to autosave, 0 disables autosave."); 80 | ConsoleCommand_RegisterBaseCommand("playerpassword", "[Password]", "Change the player password, leave empty to remove."); 81 | ConsoleCommand_RegisterBaseCommand("dmpassword", "[Password]", "Change the DM password, leave empty to remove."); 82 | ConsoleCommand_RegisterBaseCommand("servername", "[Name]", "Set the server name."); 83 | ConsoleCommand_RegisterBaseCommand("help", "", "Display all commands."); 84 | 85 | // Override the help command with our own 86 | ConsoleCommand_Register(sCoreComponentScript, "ConsoleCommand_ShowHelp", "help", "", "Display all commands."); 87 | } 88 | 89 | int ConsoleCommand_Register(string sComponentScript, string sFunction, string sCommand, string sHelpParams, string sHelpDescription) 90 | { 91 | if (sComponentScript == "" || sFunction == "" || sCommand == "" || sHelpDescription == "") 92 | return FALSE; 93 | 94 | object oDataObject = ES_Util_GetDataObject(CONSOLECOMMAND_SCRIPT_NAME); 95 | int bReturn, nCommandID = GetLocalInt(oDataObject, CONSOLECOMMAND_NUM_COMMANDS) + 1; 96 | string sCommandID = IntToString(nCommandID); 97 | 98 | sCommand = GetStringLowerCase(sCommand); 99 | 100 | if (sComponentScript == CONSOLECOMMAND_BASE_COMMAND && sFunction == CONSOLECOMMAND_BASE_COMMAND) 101 | { 102 | SetLocalInt(oDataObject, CONSOLECOMMAND_REGISTERED_COMMAND + sCommand, nCommandID); 103 | SetLocalInt(oDataObject, CONSOLECOMMAND_NUM_COMMANDS, nCommandID); 104 | 105 | SetLocalString(oDataObject, CONSOLECOMMAND_COMMAND + sCommandID, sCommand); 106 | SetLocalString(oDataObject, CONSOLECOMMAND_PARAMS + sCommandID, sHelpParams); 107 | SetLocalString(oDataObject, CONSOLECOMMAND_DESCRIPTION + sCommandID, sHelpDescription); 108 | 109 | bReturn = TRUE; 110 | } 111 | else 112 | { 113 | int nCommandRegistered = GetLocalInt(oDataObject, CONSOLECOMMAND_REGISTERED_COMMAND + sCommand); 114 | string sRegisteredCommandID = IntToString(nCommandRegistered); 115 | 116 | if (nCommandRegistered) 117 | { 118 | if (GetLocalString(oDataObject, CONSOLECOMMAND_SUBSYSTEM + sRegisteredCommandID) == "" && 119 | GetLocalString(oDataObject, CONSOLECOMMAND_FUNCTION + sRegisteredCommandID) == "") 120 | { 121 | SetLocalString(oDataObject, CONSOLECOMMAND_COMMAND + sRegisteredCommandID, sCommand); 122 | SetLocalString(oDataObject, CONSOLECOMMAND_PARAMS + sRegisteredCommandID, sHelpParams); 123 | SetLocalString(oDataObject, CONSOLECOMMAND_DESCRIPTION + sRegisteredCommandID, sHelpDescription); 124 | SetLocalString(oDataObject, CONSOLECOMMAND_SUBSYSTEM + sRegisteredCommandID, sComponentScript); 125 | SetLocalString(oDataObject, CONSOLECOMMAND_FUNCTION + sRegisteredCommandID, sFunction); 126 | 127 | bReturn = ES_Util_RegisterServerConsoleCommand(sCommand, sComponentScript, nssFunction(sFunction, "sArgs"), TRUE); 128 | 129 | if (bReturn) 130 | ES_Util_Log(CONSOLECOMMAND_LOG_TAG, "* Overriding Base Game Console Command -> '" + sCommand + "' by '" + 131 | sComponentScript + "' with Function: " + sFunction + "()"); 132 | else 133 | ES_Util_Log(CONSOLECOMMAND_LOG_TAG, "* ERROR: Failed to override Console Command -> '" + sCommand + "' by '" + 134 | sComponentScript + "' with Function: " + sFunction + "()"); 135 | } 136 | else 137 | { 138 | string sSubsystem = GetLocalString(oDataObject, CONSOLECOMMAND_SUBSYSTEM + sRegisteredCommandID); 139 | ES_Util_Log(CONSOLECOMMAND_LOG_TAG, "* ERROR: Console Command -> '" + sCommand + "' has already been registered by: " + sSubsystem); 140 | } 141 | } 142 | else 143 | { 144 | SetLocalInt(oDataObject, CONSOLECOMMAND_REGISTERED_COMMAND + sCommand, nCommandID); 145 | SetLocalInt(oDataObject, CONSOLECOMMAND_NUM_COMMANDS, nCommandID); 146 | 147 | SetLocalString(oDataObject, CONSOLECOMMAND_COMMAND + sCommandID, sCommand); 148 | SetLocalString(oDataObject, CONSOLECOMMAND_PARAMS + sCommandID, sHelpParams); 149 | SetLocalString(oDataObject, CONSOLECOMMAND_DESCRIPTION + sCommandID, sHelpDescription); 150 | SetLocalString(oDataObject, CONSOLECOMMAND_SUBSYSTEM + sCommandID, sComponentScript); 151 | SetLocalString(oDataObject, CONSOLECOMMAND_FUNCTION + sCommandID, sFunction); 152 | 153 | bReturn = ES_Util_RegisterServerConsoleCommand(sCommand, sComponentScript, nssFunction(sFunction, "sArgs"), TRUE); 154 | 155 | if (bReturn) 156 | ES_Util_Log(CONSOLECOMMAND_LOG_TAG, "* Registering Console Command -> '" + sCommand + "' for '" + 157 | sComponentScript + "' with Function: " + sFunction + "()"); 158 | else 159 | ES_Util_Log(CONSOLECOMMAND_LOG_TAG, "* ERROR: Failed to register Console Command -> '" + sCommand + "' for '" + 160 | sComponentScript + "' with Function: " + sFunction + "()"); 161 | } 162 | } 163 | 164 | return bReturn; 165 | } 166 | 167 | void ConsoleCommand_ShowHelp(string sArgs) 168 | { 169 | object oDataObject = ES_Util_GetDataObject(CONSOLECOMMAND_SCRIPT_NAME); 170 | string sHelp = GetLocalString(oDataObject, "HelpString"); 171 | 172 | if (sHelp == "" || sArgs != "") 173 | { 174 | int nNumCommands = GetLocalInt(oDataObject, CONSOLECOMMAND_NUM_COMMANDS); 175 | sHelp = "Available Console Commands: \n"; 176 | 177 | int nCommandID; 178 | for (nCommandID = 1; nCommandID <= nNumCommands; nCommandID++) 179 | { 180 | string sCommandID = IntToString(nCommandID); 181 | string sCommand = GetLocalString(oDataObject, CONSOLECOMMAND_COMMAND + sCommandID); 182 | string sParams = GetLocalString(oDataObject, CONSOLECOMMAND_PARAMS + sCommandID); 183 | string sDescription = GetLocalString(oDataObject, CONSOLECOMMAND_DESCRIPTION + sCommandID); 184 | 185 | sHelp += "\n" + sCommand + (sParams != "" ? " " + sParams : "") + " - " + sDescription; 186 | 187 | SetLocalString(oDataObject, "HelpString", sHelp); 188 | } 189 | } 190 | 191 | PrintString(sHelp); 192 | } 193 | 194 | -------------------------------------------------------------------------------- /Components/Core/es_cc_pos.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_cc_pos.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[Object] 7 | 8 | Description: An EventSystem Core Component that allows Services 9 | and Subsystems to store data in the POS of objects 10 | */ 11 | 12 | #include "es_inc_core" 13 | #include "nwnx_object" 14 | 15 | const string POS_LOG_TAG = "POS"; 16 | const string POS_SCRIPT_NAME = "es_cc_pos"; 17 | 18 | // Delete oObject's POS float variable sVarName 19 | void POS_DeleteFloat(object oObject, string sVarName); 20 | // Delete any of oObject's POS float variables that match sRegex 21 | void POS_DeleteFloatRegex(object oObject, string sRegex); 22 | // Get oObject's POS float variable sVarName 23 | // * Return value on error: 0.0f 24 | float POS_GetFloat(object oObject, string sVarName); 25 | // Set oObject's POS float variable sVarName to fValue 26 | void POS_SetFloat(object oObject, string sVarName, float fValue, int bPersist = FALSE); 27 | 28 | // Delete oObject's POS integer variable sVarName 29 | void POS_DeleteInt(object oObject, string sVarName); 30 | // Delete any of oObject's POS int variables that match sRegex 31 | void POS_DeleteIntRegex(object oObject, string sRegex); 32 | // Get oObject's POS integer variable sVarName 33 | // * Return value on error: 0 34 | int POS_GetInt(object oObject, string sVarName); 35 | // Set oObject's POS integer variable sVarName to nValue 36 | void POS_SetInt(object oObject, string sVarName, int nValue, int bPersist = FALSE); 37 | 38 | // Delete oObject's POS location variable sVarName 39 | void POS_DeleteLocation(object oObject, string sVarName); 40 | // Delete any of oObject's POS location variables that match sRegex 41 | void POS_DeleteLocationRegex(object oObject, string sRegex); 42 | // Get oObject's POS location variable sVarname 43 | location POS_GetLocation(object oObject, string sVarName); 44 | // Set oObject's POS location variable sVarname to locValue 45 | void POS_SetLocation(object oObject, string sVarName, location locValue, int bPersist = FALSE); 46 | 47 | // Delete oObject's POS vector variable sVarName 48 | void POS_DeleteVector(object oObject, string sVarName); 49 | // Delete any of oObject's POS vector variables that match sRegex 50 | void POS_DeleteVectorRegex(object oObject, string sRegex); 51 | // Get oObject's POS vector variable sVarname 52 | vector POS_GetVector(object oObject, string sVarName); 53 | // Set oObject's POS vector variable sVarname to vValue 54 | void POS_SetVector(object oObject, string sVarName, vector vValue, int bPersist = FALSE); 55 | 56 | // Delete oObject's POS object variable sVarName 57 | void POS_DeleteObject(object oObject, string sVarName); 58 | // Delete any of oObject's POS object variables that match sRegex 59 | void POS_DeleteObjectRegex(object oObject, string sRegex); 60 | // Get oObject's POS object variable sVarName 61 | // * Return value on error: OBJECT_INVALID 62 | object POS_GetObject(object oObject, string sVarName); 63 | // Set oObject's POS object variable sVarName to oValue 64 | void POS_SetObject(object oObject, string sVarName, object oValue); 65 | 66 | // Delete oObject's POS string variable sVarName 67 | void POS_DeleteString(object oObject, string sVarName); 68 | // Delete any of oObject's POS string variables that match sRegex 69 | void POS_DeleteStringRegex(object oObject, string sRegex); 70 | // Get oObject's POS string variable sVarName 71 | // * Return value on error: "" 72 | string POS_GetString(object oObject, string sVarName); 73 | // Set oObject's POS string variable sVarName to sValue 74 | void POS_SetString(object oObject, string sVarName, string sValue, int bPersist = FALSE); 75 | 76 | // Delete any POS variables from oObject that match sRegex 77 | void POS_DeleteVarRegex(object oObject, string sRegex); 78 | 79 | // @Test 80 | void POS_Test(string sComponentScript) 81 | { 82 | object oModule = GetModule(); 83 | int nTestValue = 5; 84 | 85 | POS_SetInt(oModule, "POS_TEST", nTestValue); 86 | Test_Assert("POS_{Set|Get}Int()", POS_GetInt(oModule, "POS_TEST") == nTestValue); 87 | 88 | POS_DeleteInt(oModule, "POS_TEST"); 89 | Test_Assert("POS_DeleteInt()", !POS_GetInt(oModule, "POS_TEST")); 90 | } 91 | 92 | void POS_DeleteFloat(object oObject, string sVarName) 93 | { 94 | NWNX_Object_DeleteFloat(oObject, "ES!FLT!" + sVarName); 95 | } 96 | 97 | void POS_DeleteFloatRegex(object oObject, string sRegex) 98 | { 99 | NWNX_Object_DeleteVarRegex(oObject, "(?:ES!FLT!)" + sRegex); 100 | } 101 | 102 | float POS_GetFloat(object oObject, string sVarName) 103 | { 104 | return NWNX_Object_GetFloat(oObject, "ES!FLT!" + sVarName); 105 | } 106 | 107 | void POS_SetFloat(object oObject, string sVarName, float fValue, int bPersist = FALSE) 108 | { 109 | NWNX_Object_SetFloat(oObject, "ES!FLT!" + sVarName, fValue, bPersist); 110 | } 111 | 112 | void POS_DeleteInt(object oObject, string sVarName) 113 | { 114 | NWNX_Object_DeleteInt(oObject, "ES!INT!" + sVarName); 115 | } 116 | 117 | void POS_DeleteIntRegex(object oObject, string sRegex) 118 | { 119 | NWNX_Object_DeleteVarRegex(oObject, "(?:ES!INT!)" + sRegex); 120 | } 121 | 122 | int POS_GetInt(object oObject, string sVarName) 123 | { 124 | return NWNX_Object_GetInt(oObject, "ES!INT!" + sVarName); 125 | } 126 | 127 | void POS_SetInt(object oObject, string sVarName, int nValue, int bPersist = FALSE) 128 | { 129 | NWNX_Object_SetInt(oObject, "ES!INT!" + sVarName, nValue, bPersist); 130 | } 131 | 132 | void POS_DeleteLocation(object oObject, string sVarName) 133 | { 134 | NWNX_Object_DeleteString(oObject, "ES!LOC!" + sVarName); 135 | } 136 | 137 | void POS_DeleteLocationRegex(object oObject, string sRegex) 138 | { 139 | NWNX_Object_DeleteVarRegex(oObject, "(?:ES!LOC!)" + sRegex); 140 | } 141 | 142 | location POS_GetLocation(object oObject, string sVarName) 143 | { 144 | return ES_Util_StringToLocation(NWNX_Object_GetString(oObject, "ES!LOC!" + sVarName)); 145 | } 146 | 147 | void POS_SetLocation(object oObject, string sVarName, location locValue, int bPersist = FALSE) 148 | { 149 | NWNX_Object_SetString(oObject, "ES!LOC!" + sVarName, ES_Util_LocationToString(locValue), bPersist); 150 | } 151 | 152 | void POS_DeleteVector(object oObject, string sVarName) 153 | { 154 | NWNX_Object_DeleteString(oObject, "ES!VEC!" + sVarName); 155 | } 156 | 157 | void POS_DeleteVectorRegex(object oObject, string sRegex) 158 | { 159 | NWNX_Object_DeleteVarRegex(oObject, "(?:ES!VEC!)" + sRegex); 160 | } 161 | 162 | vector POS_GetVector(object oObject, string sVarName) 163 | { 164 | return ES_Util_StringToVector(NWNX_Object_GetString(oObject, "ES!VEC!" + sVarName)); 165 | } 166 | 167 | void POS_SetVector(object oObject, string sVarName, vector vValue, int bPersist = FALSE) 168 | { 169 | NWNX_Object_SetString(oObject, "ES!VEC!" + sVarName, ES_Util_VectorToString(vValue), bPersist); 170 | } 171 | 172 | void POS_DeleteObject(object oObject, string sVarName) 173 | { 174 | NWNX_Object_DeleteString(oObject, "ES!OBJ!" + sVarName); 175 | } 176 | 177 | void POS_DeleteObjectRegex(object oObject, string sRegex) 178 | { 179 | NWNX_Object_DeleteVarRegex(oObject, "(?:ES!OBJ!)" + sRegex); 180 | } 181 | 182 | object POS_GetObject(object oObject, string sVarName) 183 | { 184 | return StringToObject(NWNX_Object_GetString(oObject, "ES!OBJ!" + sVarName)); 185 | } 186 | 187 | void POS_SetObject(object oObject, string sVarName, object oValue) 188 | { 189 | NWNX_Object_SetString(oObject, "ES!OBJ!" + sVarName, ObjectToString(oValue), FALSE); 190 | } 191 | 192 | void POS_DeleteString(object oObject, string sVarName) 193 | { 194 | NWNX_Object_DeleteString(oObject, "ES!STR!" + sVarName); 195 | } 196 | 197 | void POS_DeleteStringRegex(object oObject, string sRegex) 198 | { 199 | NWNX_Object_DeleteVarRegex(oObject, "(?:ES!STR!)" + sRegex); 200 | } 201 | 202 | string POS_GetString(object oObject, string sVarName) 203 | { 204 | return NWNX_Object_GetString(oObject, "ES!STR!" + sVarName); 205 | } 206 | 207 | void POS_SetString(object oObject, string sVarName, string sValue, int bPersist = FALSE) 208 | { 209 | NWNX_Object_SetString(oObject, "ES!STR!" + sVarName, sValue, bPersist); 210 | } 211 | 212 | void POS_DeleteVarRegex(object oObject, string sRegex) 213 | { 214 | NWNX_Object_DeleteVarRegex(oObject, "(?:ES!)((?:FLT!)|(?:INT!)|(?:LOC!)|(?:OBJ!)|(?:STR!))" + sRegex); 215 | } 216 | 217 | -------------------------------------------------------------------------------- /Components/Core/es_cc_profiler.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_cc_profiler.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: An EventSystem Core Component that adds a Script Profiler 9 | */ 10 | 11 | //void main() {} 12 | 13 | #include "es_inc_core" 14 | 15 | const string PROFILER_LOG_TAG = "Profiler"; 16 | const string PROFILER_SCRIPT_NAME = "es_cc_profiler"; 17 | 18 | const int PROFILER_OVERHEAD_COMPENSATION_ITERATIONS = 250; 19 | 20 | struct ProfilerData 21 | { 22 | string sName; 23 | int bEnableStats; 24 | int bSkipLog; 25 | int nSeconds; 26 | int nMicroseconds; 27 | }; 28 | 29 | struct ProfilerStats 30 | { 31 | string sName; 32 | int nSum; 33 | int nCount; 34 | int nMin; 35 | int nMax; 36 | int nAvg; 37 | }; 38 | 39 | struct ProfilerData Profiler_Start(string sName, int bSkipLog = FALSE, int bEnableStats = TRUE); 40 | int Profiler_Stop(struct ProfilerData startData); 41 | int Profiler_GetOverheadCompensation(); 42 | void Profiler_SetOverheadCompensation(int nOverhead); 43 | int Profiler_Calibrate(int nIterations); 44 | struct ProfilerStats Profiler_GetStats(string sName); 45 | void Profiler_DeleteStats(string sName); 46 | string nssProfiler(string sName, string sContents, int bSkipLog = FALSE, int bEnableStats = TRUE); 47 | 48 | // @Load 49 | void Profiler_Load(string sCoreComponentScript) 50 | { 51 | int nOverhead = Profiler_Calibrate(PROFILER_OVERHEAD_COMPENSATION_ITERATIONS); 52 | 53 | ES_Util_Log(PROFILER_LOG_TAG, "* Overhead Compensation: " + IntToString(nOverhead) + "us"); 54 | Profiler_SetOverheadCompensation(nOverhead); 55 | } 56 | 57 | struct ProfilerData Profiler_Start(string sName, int bSkipLog = FALSE, int bEnableStats = TRUE) 58 | { 59 | struct ProfilerData pd; 60 | pd.sName = sName; 61 | pd.bEnableStats = bEnableStats; 62 | pd.bSkipLog = bSkipLog; 63 | 64 | struct NWNX_Util_HighResTimestamp ts = NWNX_Util_GetHighResTimeStamp(); 65 | pd.nSeconds = ts.seconds; 66 | pd.nMicroseconds = ts.microseconds; 67 | 68 | return pd; 69 | } 70 | 71 | int Profiler_Stop(struct ProfilerData startData) 72 | { 73 | struct NWNX_Util_HighResTimestamp endTimestamp = NWNX_Util_GetHighResTimeStamp(); 74 | int nTotalSeconds = endTimestamp.seconds - startData.nSeconds; 75 | int nTotalMicroSeconds = endTimestamp.microseconds - startData.nMicroseconds - Profiler_GetOverheadCompensation(); 76 | 77 | if (nTotalMicroSeconds < 0) 78 | { 79 | if (nTotalSeconds > 0) 80 | { 81 | nTotalMicroSeconds = 1000000 + nTotalMicroSeconds; 82 | nTotalSeconds--; 83 | } 84 | else 85 | nTotalMicroSeconds = 0; 86 | } 87 | 88 | string sStats; 89 | if (startData.bEnableStats) 90 | { 91 | object oDataObject = ES_Util_GetDataObject(PROFILER_SCRIPT_NAME + "_" + startData.sName); 92 | int nMin, nMax, nCount = GetLocalInt(oDataObject, "PROFILER_COUNT") + 1; 93 | SetLocalInt(oDataObject, "PROFILER_COUNT", nCount); 94 | 95 | if (nCount == 1) 96 | { 97 | nMin = nTotalMicroSeconds; 98 | nMax = nTotalMicroSeconds; 99 | 100 | SetLocalInt(oDataObject, "PROFILER_MIN", nTotalMicroSeconds); 101 | SetLocalInt(oDataObject, "PROFILER_MAX", nTotalMicroSeconds); 102 | } 103 | else 104 | { 105 | nMin = GetLocalInt(oDataObject, "PROFILER_MIN"); 106 | if (nTotalMicroSeconds < nMin) 107 | { 108 | nMin = nTotalMicroSeconds; 109 | SetLocalInt(oDataObject, "PROFILER_MIN", nTotalMicroSeconds); 110 | } 111 | 112 | nMax = GetLocalInt(oDataObject, "PROFILER_MAX"); 113 | if (nTotalMicroSeconds > nMax) 114 | { 115 | nMax = nTotalMicroSeconds; 116 | SetLocalInt(oDataObject, "PROFILER_MAX", nTotalMicroSeconds); 117 | } 118 | } 119 | 120 | int nSum = GetLocalInt(oDataObject, "PROFILER_SUM") + nTotalMicroSeconds; 121 | SetLocalInt(oDataObject, "PROFILER_SUM", nSum); 122 | 123 | sStats = " (MIN: " + IntToString(nMin) + "us, MAX: " + IntToString(nMax) + "us, AVG: " + IntToString((nSum / nCount)) + "us)"; 124 | } 125 | 126 | if (!startData.bSkipLog) 127 | { 128 | int nLength = GetStringLength(IntToString(nTotalMicroSeconds)); 129 | 130 | string sZeroPadding; 131 | while (nLength < 6) 132 | { 133 | sZeroPadding += "0"; 134 | nLength++; 135 | } 136 | 137 | ES_Util_Log(PROFILER_LOG_TAG, "[" + startData.sName + "] " + IntToString(nTotalSeconds) + "." + sZeroPadding + IntToString(nTotalMicroSeconds) + " seconds" + sStats); 138 | } 139 | 140 | return nTotalMicroSeconds; 141 | } 142 | 143 | int Profiler_GetOverheadCompensation() 144 | { 145 | return GetLocalInt(ES_Util_GetDataObject(PROFILER_SCRIPT_NAME), "OVERHEAD_COMPENSATION"); 146 | } 147 | 148 | void Profiler_SetOverheadCompensation(int nOverhead) 149 | { 150 | SetLocalInt(ES_Util_GetDataObject(PROFILER_SCRIPT_NAME), "OVERHEAD_COMPENSATION", nOverhead); 151 | } 152 | 153 | int Profiler_Calibrate(int nIterations) 154 | { 155 | int i, nSum; 156 | 157 | for (i = 0; i < nIterations; i++) 158 | { 159 | nSum += Profiler_Stop(Profiler_Start("Calibration", TRUE, FALSE)); 160 | } 161 | 162 | return nIterations == 0 ? 0 : nSum / nIterations; 163 | } 164 | 165 | struct ProfilerStats Profiler_GetStats(string sName) 166 | { 167 | struct ProfilerStats ps; 168 | object oDataObject = ES_Util_GetDataObject(PROFILER_SCRIPT_NAME + "!" + sName, FALSE); 169 | 170 | ps.sName = sName; 171 | 172 | if (GetIsObjectValid(oDataObject)) 173 | { 174 | ps.nSum = GetLocalInt(oDataObject, "PROFILER_SUM"); 175 | ps.nCount = GetLocalInt(oDataObject, "PROFILER_COUNT"); 176 | ps.nMin = GetLocalInt(oDataObject, "PROFILER_MIN"); 177 | ps.nMax = GetLocalInt(oDataObject, "PROFILER_MAX"); 178 | ps.nAvg = ps.nCount == 0 ? 0 : ps.nSum / ps.nCount; 179 | } 180 | 181 | return ps; 182 | } 183 | 184 | void Profiler_DeleteStats(string sName) 185 | { 186 | ES_Util_DestroyDataObject(PROFILER_SCRIPT_NAME + "_" + sName); 187 | 188 | ES_Util_Log(PROFILER_LOG_TAG, "Deleted stats for: '" + sName + "'"); 189 | } 190 | 191 | string nssProfiler(string sName, string sContents, int bSkipLog = FALSE, int bEnableStats = TRUE) 192 | { 193 | return "struct ProfilerData pd = " + nssFunction("Profiler_Start", 194 | nssEscapeDoubleQuotes(sName) + ", " + IntToString(bSkipLog) + ", " + 195 | IntToString(bEnableStats)) + sContents + " Profiler_Stop(pd);"; 196 | } 197 | 198 | -------------------------------------------------------------------------------- /Components/Services/README.md: -------------------------------------------------------------------------------- 1 | # Various EventSystem Services that provide additional functionality 2 | -------------------------------------------------------------------------------- /Components/Services/es_srv_elc.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_srv_elc.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[ELC] 7 | 8 | Description: An EventSystem Service that allows subscribing to ELC events 9 | */ 10 | 11 | //void main() {} 12 | 13 | #include "es_inc_core" 14 | #include "es_cc_events" 15 | #include "nwnx_elc" 16 | 17 | const string ELC_LOG_TAG = "ELC"; 18 | const string ELC_SCRIPT_NAME = "es_srv_elc"; 19 | 20 | const string ELC_EVENT = "ELC_EVENT"; 21 | 22 | // Subscribe sSubsystemScript to the ELC event 23 | void ELC_SubscribeEvent(string sSubsystemScript); 24 | 25 | // @Load 26 | void ELC_Load(string sServiceScript) 27 | { 28 | ES_Util_AddScript(sServiceScript, ELC_SCRIPT_NAME, nssFunction("Events_SignalEvent", nssEscapeDoubleQuotes(ELC_EVENT) + ", OBJECT_SELF")); 29 | } 30 | 31 | void ELC_SubscribeEvent(string sSubsystemScript) 32 | { 33 | NWNX_ELC_SetELCScript(ELC_SCRIPT_NAME); 34 | 35 | Events_SubscribeEvent(sSubsystemScript, ELC_EVENT, FALSE); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Components/Services/es_srv_randarmor.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_srv_randarmor.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[Item Object] 7 | 8 | Description: An EventSystem Service that allows the creation of random chest armor 9 | */ 10 | 11 | //void main() {} 12 | 13 | #include "es_inc_core" 14 | #include "nwnx_item" 15 | #include "nwnx_object" 16 | 17 | const string RANDOM_ARMOR_LOG_TAG = "RandomArmor"; 18 | const string RANDOM_ARMOR_SCRIPT_NAME = "es_srv_randarmor"; 19 | 20 | const string RANDOM_ARMOR_TEMPLATE_TAG = "RandomArmorTemplate"; 21 | 22 | void RandomArmor_CacheArmorParts(string sSubsystemScript); 23 | void RandomArmor_PrepareTemplateArmor(); 24 | 25 | string RandomArmor_GetTableFromArmorModelType(int nArmorModelPart); 26 | int RandomArmor_GetRandomPartByType(int nArmorModelPart, int nMinPartNum = 0, float fMinAC = 0.0f, float fMaxAC = 10.0f); 27 | 28 | object RandomArmor_GetClothes(object oTarget = OBJECT_INVALID); 29 | 30 | // @Load 31 | void RandomArmor_Load(string sServiceScript) 32 | { 33 | RandomArmor_CacheArmorParts(sServiceScript); 34 | 35 | RandomArmor_PrepareTemplateArmor(); 36 | } 37 | 38 | void RandomArmor_CacheArmorParts(string sServiceScript) 39 | { 40 | object oDataObject = ES_Util_GetDataObject(RANDOM_ARMOR_SCRIPT_NAME); 41 | string sParts2DAArray = ES_Util_GetResRefArray(oDataObject, 2017/* 2DA */, "parts_.+", FALSE); 42 | 43 | ES_Util_Log(RANDOM_ARMOR_LOG_TAG, "* Caching armor parts in database"); 44 | ES_Util_ExecuteScriptChunkForArrayElements(oDataObject, sParts2DAArray, sServiceScript, nssFunction("RandomArmor_InsertArmorParts2DA", "sArrayElement"), GetModule()); 45 | StringArray_Clear(oDataObject, sParts2DAArray); 46 | } 47 | 48 | void RandomArmor_InsertArmorParts2DA(string sParts2DA) 49 | { 50 | if (SqlGetTableExistsCampaign(RANDOM_ARMOR_SCRIPT_NAME, sParts2DA)) 51 | { 52 | ES_Util_Log(RANDOM_ARMOR_LOG_TAG, " > Table for '" + sParts2DA + "' already exists, skipping!"); 53 | return; 54 | } 55 | 56 | ES_Util_Log(RANDOM_ARMOR_LOG_TAG, " > Creating table for '" + sParts2DA + "'"); 57 | 58 | string sQuery = "CREATE TABLE IF NOT EXISTS " + sParts2DA + " ( PartNum INTEGER UNIQUE, ACBonus REAL NOT NULL );"; 59 | sqlquery sql = SqlPrepareQueryCampaign(RANDOM_ARMOR_SCRIPT_NAME, sQuery); 60 | SqlStep(sql); 61 | 62 | int nIndex; 63 | int nNumRows = NWNX_Util_Get2DARowCount(sParts2DA); 64 | 65 | sQuery = "INSERT INTO " + sParts2DA + " (PartNum, ACBonus) VALUES (@PartNum, @ACBonus);"; 66 | 67 | for (nIndex = 0; nIndex < nNumRows; nIndex++) 68 | { 69 | string sACBonus = Get2DAString(sParts2DA, "ACBONUS", nIndex); 70 | 71 | if (sACBonus != "") 72 | { 73 | if (sParts2DA == "parts_shin" && (nIndex >= 18 && nIndex <= 21)) continue; // Pirate Shins 74 | if (sParts2DA == "parts_foot" && (nIndex >= 13 && nIndex <= 16)) continue; // Pirate Feet 75 | if (sParts2DA == "parts_hand" && (nIndex == 9)) continue; // Pirate Hands 76 | if (sParts2DA == "parts_pelvis" && (nIndex == 36)) continue; // Underwear 77 | 78 | ES_Util_Log(RANDOM_ARMOR_LOG_TAG, " > Inserting Armor Part: Index: '" + IntToString(nIndex) + "', ACBonus: '" + sACBonus + "'"); 79 | 80 | sql = SqlPrepareQueryCampaign(RANDOM_ARMOR_SCRIPT_NAME, sQuery); 81 | SqlBindInt(sql, "@PartNum", nIndex); 82 | SqlBindFloat(sql, "@ACBonus", StringToFloat(sACBonus)); 83 | SqlStep(sql); 84 | } 85 | } 86 | } 87 | 88 | void RandomArmor_PrepareTemplateArmor() 89 | { 90 | object oItem = CreateObject(OBJECT_TYPE_ITEM, "nw_cloth027", GetStartingLocation(), FALSE, RANDOM_ARMOR_TEMPLATE_TAG); 91 | 92 | SetName(oItem, "Random Armor Template"); 93 | SetDescription(oItem, "Random Armor Template"); 94 | SetDroppableFlag(oItem, FALSE); 95 | 96 | string sItem = NWNX_Object_Serialize(oItem); 97 | 98 | SetLocalString(ES_Util_GetDataObject(RANDOM_ARMOR_SCRIPT_NAME), RANDOM_ARMOR_TEMPLATE_TAG, sItem); 99 | 100 | DestroyObject(oItem); 101 | } 102 | 103 | string RandomArmor_GetTableFromArmorModelType(int nArmorModelPart) 104 | { 105 | string sTable = "parts_"; 106 | switch (nArmorModelPart) 107 | { 108 | case ITEM_APPR_ARMOR_MODEL_RFOOT: 109 | case ITEM_APPR_ARMOR_MODEL_LFOOT: return sTable + "foot"; 110 | case ITEM_APPR_ARMOR_MODEL_RSHIN: 111 | case ITEM_APPR_ARMOR_MODEL_LSHIN: return sTable + "shin"; 112 | case ITEM_APPR_ARMOR_MODEL_LTHIGH: 113 | case ITEM_APPR_ARMOR_MODEL_RTHIGH: return sTable + "legs"; 114 | case ITEM_APPR_ARMOR_MODEL_PELVIS: return sTable + "pelvis"; 115 | case ITEM_APPR_ARMOR_MODEL_TORSO: return sTable + "chest"; 116 | case ITEM_APPR_ARMOR_MODEL_BELT: return sTable + "belt"; 117 | case ITEM_APPR_ARMOR_MODEL_NECK: return sTable + "neck"; 118 | case ITEM_APPR_ARMOR_MODEL_RFOREARM: 119 | case ITEM_APPR_ARMOR_MODEL_LFOREARM: return sTable + "forearm"; 120 | case ITEM_APPR_ARMOR_MODEL_RBICEP: 121 | case ITEM_APPR_ARMOR_MODEL_LBICEP: return sTable + "bicep"; 122 | case ITEM_APPR_ARMOR_MODEL_RSHOULDER: 123 | case ITEM_APPR_ARMOR_MODEL_LSHOULDER: return sTable + "shoulder"; 124 | case ITEM_APPR_ARMOR_MODEL_RHAND: 125 | case ITEM_APPR_ARMOR_MODEL_LHAND: return sTable + "hand"; 126 | case ITEM_APPR_ARMOR_MODEL_ROBE : return sTable + "robe"; 127 | } 128 | 129 | return ""; 130 | } 131 | 132 | int RandomArmor_GetRandomPartByType(int nArmorModelPart, int nMinPartNum = 0, float fMinAC = 0.0f, float fMaxAC = 10.0f) 133 | { 134 | int bReturn = 0; 135 | string sTable = RandomArmor_GetTableFromArmorModelType(nArmorModelPart); 136 | string sQuery = "SELECT PartNum FROM " + sTable + " WHERE ACBonus >= @MinAC AND ACBonus <= @MaxAC AND PartNum >= @MinPartNum ORDER BY RANDOM() LIMIT 1;"; 137 | sqlquery sql = SqlPrepareQueryCampaign(RANDOM_ARMOR_SCRIPT_NAME, sQuery); 138 | 139 | SqlBindFloat(sql, "@MinAC", fMinAC); 140 | SqlBindFloat(sql, "@MaxAC", fMaxAC); 141 | SqlBindInt(sql, "@MinPartNum", nMinPartNum); 142 | 143 | if (SqlStep(sql)) 144 | { 145 | bReturn = SqlGetInt(sql, 0); 146 | } 147 | 148 | return bReturn; 149 | } 150 | 151 | object RandomArmor_GetClothes(object oTarget = OBJECT_INVALID) 152 | { 153 | object oItem = NWNX_Object_Deserialize(GetLocalString(ES_Util_GetDataObject(RANDOM_ARMOR_SCRIPT_NAME), RANDOM_ARMOR_TEMPLATE_TAG)); 154 | 155 | float fMinPartAC = 0.0f; 156 | float fMaxPartAC = 0.08f; 157 | 158 | float fMinChestAC = 0.0f; 159 | float fMaxChestAC = 2.0f; 160 | 161 | float fMinRobeAC = 0.0f; 162 | float fMaxRobeAC = 2.0f; 163 | 164 | int nValue; 165 | 166 | if (Random(10) > 7) 167 | { 168 | nValue = RandomArmor_GetRandomPartByType(ITEM_APPR_ARMOR_MODEL_BELT, 0, fMinPartAC, fMaxPartAC); 169 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_BELT, nValue); 170 | } 171 | 172 | nValue = RandomArmor_GetRandomPartByType(ITEM_APPR_ARMOR_MODEL_LBICEP, 0, fMinPartAC, fMaxPartAC); 173 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_LBICEP, nValue); 174 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_RBICEP, nValue); 175 | 176 | nValue = RandomArmor_GetRandomPartByType(ITEM_APPR_ARMOR_MODEL_TORSO, 2, fMinChestAC, fMaxChestAC); 177 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_TORSO, nValue); 178 | 179 | nValue = RandomArmor_GetRandomPartByType(ITEM_APPR_ARMOR_MODEL_LFOOT, 2, fMinPartAC, fMaxPartAC); 180 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_LFOOT, nValue); 181 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_RFOOT, nValue); 182 | 183 | if (Random(10) > 7) 184 | { 185 | nValue = RandomArmor_GetRandomPartByType(ITEM_APPR_ARMOR_MODEL_LFOREARM, 0, fMinPartAC, fMaxPartAC); 186 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_LFOREARM, nValue); 187 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_RFOREARM, nValue); 188 | } 189 | 190 | if (Random(10) > 6) 191 | { 192 | nValue = RandomArmor_GetRandomPartByType(ITEM_APPR_ARMOR_MODEL_LHAND, 0, fMinPartAC, fMaxPartAC); 193 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_LHAND, nValue); 194 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_RHAND, nValue); 195 | } 196 | 197 | nValue = RandomArmor_GetRandomPartByType(ITEM_APPR_ARMOR_MODEL_LTHIGH, 2, fMinPartAC, fMaxPartAC); 198 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_LTHIGH, nValue); 199 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_RTHIGH, nValue); 200 | 201 | nValue = RandomArmor_GetRandomPartByType(ITEM_APPR_ARMOR_MODEL_NECK, 1, fMinPartAC, fMaxPartAC); 202 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_NECK, nValue); 203 | 204 | nValue = RandomArmor_GetRandomPartByType(ITEM_APPR_ARMOR_MODEL_PELVIS, 1, fMinPartAC, fMaxPartAC); 205 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_PELVIS, nValue); 206 | 207 | nValue = RandomArmor_GetRandomPartByType(ITEM_APPR_ARMOR_MODEL_LSHIN, 2, fMinPartAC, fMaxPartAC); 208 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_LSHIN, nValue); 209 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_RSHIN, nValue); 210 | 211 | if (!Random(10)) 212 | { 213 | nValue = RandomArmor_GetRandomPartByType(ITEM_APPR_ARMOR_MODEL_LSHOULDER, 0, fMinPartAC, fMaxPartAC); 214 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_LSHOULDER, nValue); 215 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_RSHOULDER, nValue); 216 | } 217 | 218 | if (Random(10) < 2) 219 | { 220 | nValue = RandomArmor_GetRandomPartByType(ITEM_APPR_ARMOR_MODEL_ROBE, 0, fMinRobeAC, fMaxRobeAC); 221 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_MODEL, ITEM_APPR_ARMOR_MODEL_ROBE, nValue); 222 | } 223 | 224 | // Colors 225 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_CLOTH1, Random(25)); 226 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_CLOTH2, Random(25)); 227 | 228 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_LEATHER1, Random(25)); 229 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_LEATHER2, Random(25)); 230 | 231 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_METAL1, Random(16)); 232 | NWNX_Item_SetItemAppearance(oItem, ITEM_APPR_TYPE_ARMOR_COLOR, ITEM_APPR_ARMOR_COLOR_METAL2, Random(16)); 233 | 234 | if (GetIsObjectValid(oTarget)) 235 | { 236 | SetDroppableFlag(oItem, FALSE); 237 | NWNX_Object_AcquireItem(oTarget, oItem); 238 | } 239 | 240 | return oItem; 241 | } 242 | 243 | -------------------------------------------------------------------------------- /Components/Services/es_srv_spellhook.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_srv_spellhook.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: An EventSystem Service that allows subsystems to subscribe to 9 | module override spell script events 10 | */ 11 | 12 | //void main() {} 13 | 14 | #include "es_inc_core" 15 | #include "es_cc_events" 16 | #include "x2_inc_switches" 17 | 18 | const string SPELLHOOK_LOG_TAG = "Spellhook"; 19 | const string SPELLHOOK_SCRIPT_NAME = "es_srv_spellhook"; 20 | 21 | const string SPELLHOOK_EVENT_PREFIX = "SPELL_EVENT_"; 22 | 23 | // Subscribe sEventHandlerScript to a spellcast event 24 | void Spellhook_SubscribeEvent(string sSubsystemScript, int nSpellID, int bDispatchListMode = FALSE); 25 | // Skip a spellhook event 26 | void Spellhook_SkipEvent(); 27 | // Get the spell event name for nSpellID 28 | string Spellhook_GetEventName(int nSpellID); 29 | 30 | // @Load 31 | void Spellhook_Load(string sServiceScript) 32 | { 33 | ES_Util_AddScript(sServiceScript, sServiceScript, nssFunction("Spellhook_SignalEvent")); 34 | } 35 | 36 | void Spellhook_SignalEvent() 37 | { 38 | string sSpellEvent = SPELLHOOK_EVENT_PREFIX + IntToString(GetSpellId()); 39 | 40 | if (GetLocalInt(ES_Util_GetDataObject(SPELLHOOK_SCRIPT_NAME), sSpellEvent)) 41 | Events_SignalEvent(sSpellEvent, OBJECT_SELF); 42 | } 43 | 44 | void Spellhook_SubscribeEvent(string sSubsystemScript, int nSpellID, int bDispatchListMode = FALSE) 45 | { 46 | SetModuleOverrideSpellscript(SPELLHOOK_SCRIPT_NAME); 47 | 48 | SetLocalInt(ES_Util_GetDataObject(SPELLHOOK_SCRIPT_NAME), SPELLHOOK_EVENT_PREFIX + IntToString(nSpellID), TRUE); 49 | 50 | Events_SubscribeEvent(sSubsystemScript, SPELLHOOK_EVENT_PREFIX + IntToString(nSpellID), bDispatchListMode); 51 | } 52 | 53 | void Spellhook_SkipEvent() 54 | { 55 | SetModuleOverrideSpellScriptFinished(); 56 | } 57 | 58 | string Spellhook_GetEventName(int nSpellID) 59 | { 60 | return SPELLHOOK_EVENT_PREFIX + IntToString(nSpellID); 61 | } 62 | 63 | -------------------------------------------------------------------------------- /Components/Services/es_srv_toolbox.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_srv_toolbox.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[Area Object] 7 | 8 | Description: An EventSystem Service that allows you to create small items 9 | and placeables on the fly. 10 | */ 11 | 12 | //void main() {} 13 | 14 | #include "es_inc_core" 15 | #include "es_cc_events" 16 | #include "nwnx_area" 17 | #include "nwnx_object" 18 | 19 | const string TOOLBOX_LOG_TAG = "Toolbox"; 20 | const string TOOLBOX_SCRIPT_NAME = "es_srv_toolbox"; 21 | 22 | const string TOOLBOX_TEMPLATE_SMALL_ITEM_TAG = "ToolboxSmallItem"; 23 | const string TOOLBOX_TEMPLATE_PLACEABLE_TAG = "ToolboxPlaceable"; 24 | 25 | const int TOOLBOX_INVISIBLE_PLACEABLE_MODEL_ID = 157; 26 | 27 | // Creates and returns a small Item with a single itemproperty 28 | object Toolbox_CreateSmallItem(struct Toolbox_SmallItemData sid); 29 | // Generates a serialized placeable template 30 | string Toolbox_GeneratePlaceable(struct Toolbox_PlaceableData pd); 31 | // Create a new placeable from template string 32 | object Toolbox_CreatePlaceable(string sPlaceable, location locLocation, string sNewTag = ""); 33 | // Create a new trigger in the shape of a circle 34 | object Toolbox_CreateCircleTrigger(struct Toolbox_CircleTriggerData ctd, location locLocation); 35 | 36 | struct Toolbox_SmallItemData 37 | { 38 | int nIcon; 39 | string sName; 40 | string sTag; 41 | string sDescription; 42 | 43 | int bPlot; 44 | int bCursed; 45 | int bDroppable; 46 | int bPickpocketable; 47 | int bStolen; 48 | 49 | itemproperty ipProperty; 50 | }; 51 | 52 | struct Toolbox_PlaceableData 53 | { 54 | int nModel; 55 | string sTag; 56 | string sName; 57 | string sDescription; 58 | 59 | int bHasInventory; 60 | int bPlot; 61 | int bUseable; 62 | 63 | float fFacingAdjustment; 64 | 65 | int scriptOnClick; 66 | int scriptOnClose; 67 | int scriptOnDamaged; 68 | int scriptOnDeath; 69 | int scriptOnHeartbeat; 70 | int scriptOnDisturbed; 71 | int scriptOnLock; 72 | int scriptOnPhysicalAttacked; 73 | int scriptOnOpen; 74 | int scriptOnSpellCastAt; 75 | int scriptOnUnlock; 76 | int scriptOnUsed; 77 | int scriptOnUserDefined; 78 | int scriptOnDialog; 79 | int scriptOnDisarm; 80 | int scriptOnTrapTriggered; 81 | }; 82 | 83 | struct Toolbox_CircleTriggerData 84 | { 85 | string sTag; 86 | string sName; 87 | 88 | float fRadius; 89 | int nPoints; 90 | 91 | int bUseSpawnZ; 92 | 93 | int scriptOnClick; 94 | int scriptOnEnter; 95 | int scriptOnExit; 96 | int scriptOnHearbeat; 97 | int scriptOnUserDefined; 98 | }; 99 | 100 | // @Load 101 | void Toolbox_Load(string sServiceScript) 102 | { 103 | object oDataObject = ES_Util_GetDataObject(sServiceScript); 104 | 105 | ES_Util_Log(TOOLBOX_LOG_TAG, "* Generating Small Item Template"); 106 | 107 | object oSmallItem = CreateObject(OBJECT_TYPE_ITEM, "nw_it_msmlmisc22", GetStartingLocation(), FALSE, TOOLBOX_TEMPLATE_SMALL_ITEM_TAG); 108 | SetName(oSmallItem, "Item Template, Small"); 109 | SetDescription(oSmallItem, "Item Template, Small"); 110 | string sSmallItem = NWNX_Object_Serialize(oSmallItem); 111 | SetLocalString(oDataObject, TOOLBOX_TEMPLATE_SMALL_ITEM_TAG, sSmallItem); 112 | object oTemplateSmallItem = NWNX_Object_Deserialize(sSmallItem); 113 | SetLocalObject(oDataObject, TOOLBOX_TEMPLATE_SMALL_ITEM_TAG, oTemplateSmallItem); 114 | DestroyObject(oSmallItem); 115 | 116 | ES_Util_Log(TOOLBOX_LOG_TAG, "* Generating Placeable Template"); 117 | 118 | object oPlaceable = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_invisobj", GetStartingLocation(), FALSE, TOOLBOX_TEMPLATE_PLACEABLE_TAG); 119 | SetName(oPlaceable, "Placeable Template"); 120 | NWNX_Object_SetPlaceableIsStatic(oPlaceable, FALSE); 121 | string sPlaceable = NWNX_Object_Serialize(oPlaceable); 122 | SetLocalString(oDataObject, TOOLBOX_TEMPLATE_PLACEABLE_TAG, sPlaceable); 123 | DestroyObject(oPlaceable); 124 | } 125 | 126 | object Toolbox_CreateSmallItem(struct Toolbox_SmallItemData sid) 127 | { 128 | object oDataObject = ES_Util_GetDataObject(TOOLBOX_SCRIPT_NAME); 129 | object oTemplateItem = GetLocalObject(oDataObject, TOOLBOX_TEMPLATE_SMALL_ITEM_TAG); 130 | object oSmallItem = CopyItemAndModify(oTemplateItem, ITEM_APPR_TYPE_SIMPLE_MODEL, 0, sid.nIcon, TRUE); 131 | 132 | SetName(oSmallItem, sid.sName); 133 | SetDescription(oSmallItem, sid.sDescription); 134 | SetTag(oSmallItem, sid.sTag); 135 | 136 | if (sid.bPlot) SetPlotFlag(oSmallItem, sid.bPlot); 137 | if (sid.bDroppable) SetDroppableFlag(oSmallItem, sid.bDroppable); 138 | if (sid.bCursed) SetItemCursedFlag(oSmallItem, sid.bCursed); 139 | if (sid.bPickpocketable) SetPickpocketableFlag(oSmallItem, sid.bPickpocketable); 140 | if (sid.bStolen) SetStolenFlag(oSmallItem, sid.bStolen); 141 | 142 | if (GetIsItemPropertyValid(sid.ipProperty)) 143 | AddItemProperty(DURATION_TYPE_PERMANENT, sid.ipProperty, oSmallItem); 144 | 145 | return oSmallItem; 146 | } 147 | 148 | string Toolbox_GeneratePlaceable(struct Toolbox_PlaceableData pd) 149 | { 150 | object oDataObject = ES_Util_GetDataObject(TOOLBOX_SCRIPT_NAME); 151 | object oPlaceable = NWNX_Object_Deserialize(GetLocalString(oDataObject, TOOLBOX_TEMPLATE_PLACEABLE_TAG)); 152 | 153 | NWNX_Object_SetAppearance(oPlaceable, pd.nModel); 154 | 155 | string sModelName = Get2DAString("placeables", "ModelName", pd.nModel); 156 | if (sModelName != "") 157 | SetPortraitResRef(oPlaceable, "po_" + GetStringLowerCase(sModelName) + "_"); 158 | 159 | SetName(oPlaceable, pd.sName); 160 | SetDescription(oPlaceable, pd.sDescription); 161 | if (pd.sTag != "") 162 | SetTag(oPlaceable, pd.sTag); 163 | 164 | SetLocalFloat(oPlaceable, "ToolboxFacingAdjustment", pd.fFacingAdjustment); 165 | 166 | if (pd.bHasInventory) NWNX_Object_SetHasInventory(oPlaceable, pd.bHasInventory); 167 | if (pd.bPlot) SetPlotFlag(oPlaceable, pd.bPlot); 168 | if (pd.bUseable) SetUseableFlag(oPlaceable, pd.bUseable); 169 | 170 | if (pd.scriptOnClick) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_LEFT_CLICK, FALSE); 171 | if (pd.scriptOnClose) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_CLOSED, FALSE); 172 | if (pd.scriptOnDamaged) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_DAMAGED, FALSE); 173 | if (pd.scriptOnDeath) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_DEATH, FALSE); 174 | if (pd.scriptOnHeartbeat) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_HEARTBEAT, FALSE); 175 | if (pd.scriptOnDisturbed) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_INVENTORYDISTURBED, FALSE); 176 | if (pd.scriptOnLock) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_LOCK, FALSE); 177 | if (pd.scriptOnPhysicalAttacked) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_MELEEATTACKED, FALSE); 178 | if (pd.scriptOnOpen) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_OPEN, FALSE); 179 | if (pd.scriptOnSpellCastAt) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_SPELLCASTAT, FALSE); 180 | if (pd.scriptOnUnlock) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_UNLOCK, FALSE); 181 | if (pd.scriptOnUsed) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_USED, FALSE); 182 | if (pd.scriptOnUserDefined) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_USER_DEFINED_EVENT, FALSE); 183 | if (pd.scriptOnDialog) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_DIALOGUE, FALSE); 184 | if (pd.scriptOnDisarm) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_DISARM, FALSE); 185 | if (pd.scriptOnTrapTriggered) Events_SetObjectEventScript(oPlaceable, EVENT_SCRIPT_PLACEABLE_ON_TRAPTRIGGERED, FALSE); 186 | 187 | DestroyObject(oPlaceable); 188 | 189 | return NWNX_Object_Serialize(oPlaceable); 190 | } 191 | 192 | object Toolbox_CreatePlaceable(string sPlaceable, location locLocation, string sNewTag = "") 193 | { 194 | object oPlaceable = NWNX_Object_Deserialize(sPlaceable); 195 | 196 | if (sNewTag != "") 197 | SetTag(oPlaceable, sNewTag); 198 | 199 | NWNX_Object_AddToArea(oPlaceable, GetAreaFromLocation(locLocation), GetPositionFromLocation(locLocation)); 200 | 201 | float fFacingAdjustment = GetLocalFloat(oPlaceable, "ToolboxFacingAdjustment"); 202 | float fFacing = GetFacingFromLocation(locLocation) + fFacingAdjustment; 203 | 204 | AssignCommand(oPlaceable, SetFacing(fFacing)); 205 | //NWNX_Object_SetFacing(oPlaceable, fFacing); 206 | DeleteLocalFloat(oPlaceable, "ToolboxFacingAdjustment"); 207 | 208 | 209 | return oPlaceable; 210 | } 211 | 212 | object Toolbox_CreateCircleTrigger(struct Toolbox_CircleTriggerData ctd, location locLocation) 213 | { 214 | object oArea = GetAreaFromLocation(locLocation); 215 | vector vPosition = GetPositionFromLocation(locLocation); 216 | 217 | object oTrigger = NWNX_Area_CreateGenericTrigger(oArea, vPosition.x, vPosition.y, vPosition.z, ctd.sTag); 218 | 219 | if (ctd.sName != "") SetName(oTrigger, ctd.sName); 220 | 221 | ctd.nPoints = abs(ctd.nPoints); 222 | ctd.fRadius = fabs(ctd.fRadius); 223 | if (ctd.nPoints < 3) ctd.nPoints = 3; 224 | if (ctd.fRadius == 0.0f) ctd.fRadius = 1.0f; 225 | 226 | float fAngleIncrement = 360.0f / ctd.nPoints; 227 | string sGeometry; 228 | 229 | int i; 230 | for (i = 0; i < ctd.nPoints; i++) 231 | { 232 | float fAngle = fAngleIncrement * i; 233 | float x = (ctd.fRadius * cos(fAngle)) + vPosition.x; 234 | float y = (ctd.fRadius * sin(fAngle)) + vPosition.y; 235 | 236 | sGeometry += "{" + FloatToString(x) + ", " + FloatToString(y) + (ctd.bUseSpawnZ ? ", " + FloatToString(vPosition.z) + "}" : "}"); 237 | } 238 | 239 | NWNX_Object_SetTriggerGeometry(oTrigger, sGeometry); 240 | 241 | if (ctd.scriptOnClick) Events_SetObjectEventScript(oTrigger, EVENT_SCRIPT_TRIGGER_ON_CLICKED, FALSE); 242 | if (ctd.scriptOnEnter) Events_SetObjectEventScript(oTrigger, EVENT_SCRIPT_TRIGGER_ON_OBJECT_ENTER, FALSE); 243 | if (ctd.scriptOnExit) Events_SetObjectEventScript(oTrigger, EVENT_SCRIPT_TRIGGER_ON_OBJECT_EXIT, FALSE); 244 | if (ctd.scriptOnHearbeat) Events_SetObjectEventScript(oTrigger, EVENT_SCRIPT_TRIGGER_ON_HEARTBEAT, FALSE); 245 | if (ctd.scriptOnUserDefined) Events_SetObjectEventScript(oTrigger, EVENT_SCRIPT_TRIGGER_ON_USER_DEFINED_EVENT, FALSE); 246 | 247 | return oTrigger; 248 | } 249 | 250 | -------------------------------------------------------------------------------- /Components/Services/es_srv_webhook.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_srv_webhook.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[WebHook] 7 | 8 | Description: An EventSystem Service that allows sending of webhook messages 9 | */ 10 | 11 | //void main() {} 12 | 13 | #include "es_inc_core" 14 | #include "es_cc_events" 15 | #include "nwnx_webhook" 16 | 17 | const string WEBHOOK_LOG_TAG = "Webhook"; 18 | const string WEBHOOK_SCRIPT_NAME = "es_srv_webhook"; 19 | 20 | const string WEBHOOK_CHANNEL_PLAYER = "ES_WEBHOOK_API_URL_PLAYER"; 21 | const string WEBHOOK_CHANNEL_ADMIN = "ES_WEBHOOK_API_URL_ADMIN"; 22 | 23 | // Send a webhook message to a channel 24 | // sChannel: WEBHOOK_CHANNEL_* 25 | void Webhook_SendMessage(string sChannel, string sMessage, string sUserName = ""); 26 | 27 | // @Load 28 | void Webhook_Load(string sServiceScript) 29 | { 30 | object oModule = GetModule(); 31 | int bPlayerWebhook = ES_Util_ExecuteScriptChunkAndReturnInt(sServiceScript, 32 | nssFunction("Webhook_CheckAPIUrl", nssEscapeDoubleQuotes(WEBHOOK_CHANNEL_PLAYER)), oModule); 33 | int bAdminWebhook = ES_Util_ExecuteScriptChunkAndReturnInt(sServiceScript, 34 | nssFunction("Webhook_CheckAPIUrl", nssEscapeDoubleQuotes(WEBHOOK_CHANNEL_ADMIN)), oModule); 35 | 36 | if (bPlayerWebhook || bAdminWebhook) 37 | Events_SubscribeEvent_NWNX(sServiceScript, "NWNX_ON_WEBHOOK_FAILURE"); 38 | } 39 | 40 | // @EventHandler 41 | void Webhook_EventHandler(string sServiceScript, string sEvent) 42 | { 43 | if (sEvent == "NWNX_ON_WEBHOOK_FAILURE") 44 | { 45 | int nStatus = Events_GetEventData_NWNX_Int("STATUS"); 46 | 47 | if (nStatus == 429) 48 | {// Rate limited 49 | float fResendDelay = Events_GetEventData_NWNX_Float("RETRY_AFTER") / 1000.0f; 50 | string sMessage = Events_GetEventData_NWNX_String("MESSAGE"); 51 | string sHost = Events_GetEventData_NWNX_String("HOST"); 52 | string sPath = Events_GetEventData_NWNX_String("PATH"); 53 | 54 | ES_Util_Log(WEBHOOK_LOG_TAG, "WARNING: Webhook rate limited, resending in " + FloatToString(fResendDelay) + " seconds."); 55 | 56 | NWNX_WebHook_ResendWebHookHTTPS(sHost, sPath, sMessage, fResendDelay); 57 | } 58 | } 59 | } 60 | 61 | int Webhook_CheckAPIUrl(string sChannel) 62 | { 63 | object oDataObject = ES_Util_GetDataObject(WEBHOOK_SCRIPT_NAME); 64 | 65 | string sWebhookUrl = NWNX_Util_GetEnvironmentVariable(sChannel); 66 | 67 | if (sWebhookUrl != "") 68 | SetLocalString(oDataObject, sChannel, sWebhookUrl); 69 | else 70 | ES_Util_Log(WEBHOOK_LOG_TAG, "WARNING: API URL for '" + sChannel + "' is not set"); 71 | 72 | return sWebhookUrl != ""; 73 | } 74 | 75 | void Webhook_SendMessage(string sChannel, string sMessage, string sUserName = "") 76 | { 77 | string sWebhookUrl = GetLocalString(ES_Util_GetDataObject(WEBHOOK_SCRIPT_NAME), sChannel); 78 | 79 | if (sWebhookUrl != "") 80 | NWNX_WebHook_SendWebHookHTTPS("discordapp.com", sWebhookUrl, sMessage, sUserName); 81 | else 82 | ES_Util_Log(WEBHOOK_LOG_TAG, "WARNING: Tried to send '" + sChannel + "' webhook message but no webhook API url is set"); 83 | } 84 | 85 | -------------------------------------------------------------------------------- /Components/Services/es_srv_wtimer.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_srv_wtimer.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: An EventSystem Service that exposes various world timer related events. 9 | */ 10 | 11 | //void main() {} 12 | 13 | #include "es_inc_core" 14 | #include "es_cc_events" 15 | 16 | const string WORLD_TIMER_LOG_TAG = "WorldTimer"; 17 | const string WORLD_TIMER_SCRIPT_NAME = "es_srv_wtimer"; 18 | 19 | const string WORLD_TIMER_EVENT_1_MINUTE = "WORLD_TIMER_EVENT_1_MINUTE"; 20 | const string WORLD_TIMER_EVENT_5_MINUTES = "WORLD_TIMER_EVENT_5_MINUTES"; 21 | const string WORLD_TIMER_EVENT_10_MINUTES = "WORLD_TIMER_EVENT_10_MINUTES"; 22 | const string WORLD_TIMER_EVENT_15_MINUTES = "WORLD_TIMER_EVENT_15_MINUTES"; 23 | const string WORLD_TIMER_EVENT_30_MINUTES = "WORLD_TIMER_EVENT_30_MINUTES"; 24 | const string WORLD_TIMER_EVENT_60_MINUTES = "WORLD_TIMER_EVENT_60_MINUTES"; 25 | 26 | // Subscribe sEventHandlerScript to a WORLD_TIMER_EVENT_* 27 | void WorldTimer_SubscribeEvent(string sSubsystemScript, string sWorldTimerEvent, int bDispatchListMode = FALSE); 28 | // Unsubscribe sEventHandlerScript from a WORLD_TIMER_EVENT_* 29 | void WorldTimer_UnsubscribeEvent(string sSubsystemScript, string sWorldTimerEvent, int bClearDispatchList = TRUE); 30 | // Get the current heartbeat count tick 31 | int WorldTimer_GetHeartbeatCount(); 32 | 33 | // @Load 34 | void WorldTimer_Load(string sServiceScript) 35 | { 36 | Events_SubscribeEvent_Object(sServiceScript, EVENT_SCRIPT_MODULE_ON_HEARTBEAT); 37 | } 38 | 39 | // @EventHandler 40 | void WorldTimer_EventHandler(string sServiceScript, string sEvent) 41 | { 42 | object oModule = OBJECT_SELF; 43 | object oDataObject = ES_Util_GetDataObject(sServiceScript); 44 | int nHeartbeatCount = GetLocalInt(oDataObject, "WORLD_TIMER_HEARTBEAT_COUNT"); 45 | 46 | // Every 1 minute 47 | if (!(nHeartbeatCount % 10) && GetLocalInt(oDataObject, WORLD_TIMER_EVENT_1_MINUTE)) 48 | Events_SignalEvent(WORLD_TIMER_EVENT_1_MINUTE, oModule); 49 | // Every 5 minutes 50 | if (!(nHeartbeatCount % (10 * 5)) && GetLocalInt(oDataObject, WORLD_TIMER_EVENT_5_MINUTES)) 51 | Events_SignalEvent(WORLD_TIMER_EVENT_5_MINUTES, oModule); 52 | // Every 10 minutes 53 | if (!(nHeartbeatCount % (10 * 10)) && GetLocalInt(oDataObject, WORLD_TIMER_EVENT_10_MINUTES)) 54 | Events_SignalEvent(WORLD_TIMER_EVENT_10_MINUTES, oModule); 55 | // Every 15 minutes 56 | if (!(nHeartbeatCount % (10 * 15)) && GetLocalInt(oDataObject, WORLD_TIMER_EVENT_15_MINUTES)) 57 | Events_SignalEvent(WORLD_TIMER_EVENT_15_MINUTES, oModule); 58 | // Every 30 minutes 59 | if (!(nHeartbeatCount % (10 * 30)) && GetLocalInt(oDataObject, WORLD_TIMER_EVENT_30_MINUTES)) 60 | Events_SignalEvent(WORLD_TIMER_EVENT_30_MINUTES, oModule); 61 | // Every 60 minutes 62 | if (!(nHeartbeatCount % (10 * 60)) && GetLocalInt(oDataObject, WORLD_TIMER_EVENT_60_MINUTES)) 63 | Events_SignalEvent(WORLD_TIMER_EVENT_60_MINUTES, oModule); 64 | 65 | SetLocalInt(oDataObject, "WORLD_TIMER_HEARTBEAT_COUNT", ++nHeartbeatCount); 66 | } 67 | 68 | void WorldTimer_SubscribeEvent(string sSubsystemScript, string sWorldTimerEvent, int bDispatchListMode = FALSE) 69 | { 70 | object oDataObject = ES_Util_GetDataObject(WORLD_TIMER_SCRIPT_NAME); 71 | int nCurrentSubscribed = GetLocalInt(oDataObject, sWorldTimerEvent); 72 | 73 | SetLocalInt(oDataObject, sWorldTimerEvent, ++nCurrentSubscribed); 74 | 75 | Events_SubscribeEvent(sSubsystemScript, sWorldTimerEvent, bDispatchListMode); 76 | } 77 | 78 | void WorldTimer_UnsubscribeEvent(string sSubsystemScript, string sWorldTimerEvent, int bClearDispatchList = TRUE) 79 | { 80 | object oDataObject = ES_Util_GetDataObject(WORLD_TIMER_SCRIPT_NAME); 81 | int nCurrentSubscribed = GetLocalInt(oDataObject, sWorldTimerEvent); 82 | 83 | SetLocalInt(oDataObject, sWorldTimerEvent, --nCurrentSubscribed); 84 | 85 | Events_UnsubscribeEvent(sSubsystemScript, sWorldTimerEvent, bClearDispatchList); 86 | } 87 | 88 | int WorldTimer_GetHeartbeatCount() 89 | { 90 | return GetLocalInt(ES_Util_GetDataObject(WORLD_TIMER_SCRIPT_NAME), "WORLD_TIMER_HEARTBEAT_COUNT"); 91 | } 92 | 93 | -------------------------------------------------------------------------------- /Components/Subsystems/README.md: -------------------------------------------------------------------------------- 1 | # Subsystem Overview 2 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_ambientnpcs.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_ambientnpcs.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: An EventSystem Subsystem that spawns randomly generated ambient NPCs 9 | */ 10 | 11 | //void main() {} 12 | 13 | #include "es_inc_core" 14 | #include "es_cc_events" 15 | #include "es_srv_randarmor" 16 | #include "es_srv_randomnpc" 17 | #include "es_srv_simai" 18 | 19 | const string AMBIENT_NPCS_LOG_TAG = "AmbientNPCs"; 20 | const string AMBIENT_NPCS_SCRIPT_NAME = "es_s_ambientnpcs"; 21 | 22 | const string AMBIENT_NPCS_NPC_TAG = "AMBIENT_NPC"; 23 | const string AMBIENT_NPCS_SPAWN_TAG = "AMBIENT_NPCS_SPAWN"; 24 | 25 | void AmbientNPCs_SpawnNPCs(int nAmount, string sBehavior, location locSpawn); 26 | void AmbientNPCs_ReactMove(object oNPC); 27 | void AmbientNPCs_ReactLookHere(object oPlayer, object oNPC); 28 | 29 | // @Load 30 | void AmbientNPCs_Load(string sSubsystemScript) 31 | { 32 | object oWaypoint; 33 | int nNth; 34 | 35 | while ((oWaypoint = GetObjectByTag(AMBIENT_NPCS_SPAWN_TAG, nNth++)) != OBJECT_INVALID) 36 | { 37 | int nWanderNPCAmount = GetLocalInt(oWaypoint, "ai_b_wander"); 38 | int nSitOnChairNPCAmount = GetLocalInt(oWaypoint, "ai_b_sitonchair"); 39 | object oArea = GetArea(oWaypoint); 40 | location locSpawn = GetLocation(oWaypoint); 41 | 42 | ES_Util_Log(AMBIENT_NPCS_LOG_TAG, "* Spawning '" + IntToString(nWanderNPCAmount + nSitOnChairNPCAmount) + "' Ambient NPCs in Area: " + GetName(oArea)); 43 | 44 | AmbientNPCs_SpawnNPCs(nWanderNPCAmount, "ai_b_wander", locSpawn); 45 | AmbientNPCs_SpawnNPCs(nSitOnChairNPCAmount, "ai_b_sitonchair", locSpawn); 46 | 47 | SetLocalInt(oArea, AMBIENT_NPCS_SPAWN_TAG, TRUE); 48 | } 49 | 50 | Events_SubscribeEvent_NWNX(sSubsystemScript, "NWNX_ON_QUICKCHAT_BEFORE"); 51 | } 52 | 53 | // @EventHandler 54 | void AmbientNPCs_EventHandler(string sSubsystemScript, string sEvent) 55 | { 56 | if (sEvent == "NWNX_ON_QUICKCHAT_BEFORE") 57 | { 58 | object oPlayer = OBJECT_SELF; 59 | object oArea = GetArea(oPlayer); 60 | 61 | if (!GetLocalInt(oArea, AMBIENT_NPCS_SPAWN_TAG)) 62 | return; 63 | 64 | int nVoiceChatID = Events_GetEventData_NWNX_Int("QUICKCHAT_COMMAND"); 65 | 66 | switch (nVoiceChatID) 67 | { 68 | case VOICE_CHAT_MOVEOVER: 69 | { 70 | object oNPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC, oPlayer, 1, CREATURE_TYPE_IS_ALIVE, TRUE); 71 | 72 | if (GetIsObjectValid(oNPC) && GetTag(oNPC) == AMBIENT_NPCS_NPC_TAG) 73 | { 74 | if (GetCurrentAction(oNPC) == ACTION_SIT) 75 | DelayCommand(1.0f, AmbientNPCs_ReactMove(oNPC)); 76 | } 77 | 78 | break; 79 | } 80 | 81 | case VOICE_CHAT_HELLO: 82 | case VOICE_CHAT_GOODBYE: 83 | { 84 | location locSelf = ES_Util_GetAheadLocation(oPlayer, 2.0f); 85 | object oNPC = GetFirstObjectInShape(SHAPE_SPHERE, 4.0f, locSelf); 86 | 87 | while (GetIsObjectValid(oNPC)) 88 | { 89 | if (GetTag(oNPC) == AMBIENT_NPCS_NPC_TAG) 90 | { 91 | if (!Random(3)) 92 | DelayCommand(1.0f + (Random(16) / 10.0f), SimpleAI_PlayVoiceChat(nVoiceChatID, oNPC)); 93 | } 94 | 95 | oNPC = GetNextObjectInShape(SHAPE_SPHERE, 4.0f, locSelf); 96 | } 97 | 98 | break; 99 | } 100 | 101 | case VOICE_CHAT_LOOKHERE: 102 | { 103 | 104 | location locSelf = GetLocation(oPlayer); 105 | object oNPC = GetFirstObjectInShape(SHAPE_SPHERE, 5.0f, locSelf); 106 | 107 | while (GetIsObjectValid(oNPC)) 108 | { 109 | if (GetTag(oNPC) == AMBIENT_NPCS_NPC_TAG) 110 | { 111 | if (!Random(4)) 112 | { 113 | DelayCommand(1.0f + (Random(16) / 10.0f), AmbientNPCs_ReactLookHere(oPlayer, oNPC)); 114 | } 115 | } 116 | 117 | oNPC = GetNextObjectInShape(SHAPE_SPHERE, 5.0f, locSelf); 118 | } 119 | break; 120 | } 121 | } 122 | } 123 | } 124 | 125 | void AmbientNPCs_SpawnNPCs(int nAmount, string sBehavior, location locSpawn) 126 | { 127 | int nNPC; 128 | for(nNPC = 0; nNPC < nAmount; nNPC++) 129 | { 130 | object oNPC = RandomNPC_GetRandomPregeneratedNPC(AMBIENT_NPCS_NPC_TAG, locSpawn); 131 | object oClothes = RandomArmor_GetClothes(oNPC); 132 | 133 | SetLocalObject(oNPC, "AMBIENT_NPC_CLOTHES", oClothes); 134 | SimpleAI_SetAIBehavior(oNPC, sBehavior); 135 | SetPlotFlag(oNPC, TRUE); 136 | } 137 | } 138 | 139 | void AmbientNPCs_ReactMove(object oNPC) 140 | { 141 | if (GetLocalInt(oNPC, "AmbientNPC_Annoyed")) 142 | SimpleAI_PlayVoiceChat(VOICE_CHAT_THREATEN, oNPC); 143 | else 144 | { 145 | if (!Random(3)) 146 | { 147 | SetLocalInt(oNPC, "AmbientNPC_Annoyed", TRUE); 148 | SimpleAI_PlayVoiceChat(VOICE_CHAT_CANTDO, oNPC); 149 | DelayCommand(15.0f, DeleteLocalInt(oNPC, "AmbientNPC_Annoyed")); 150 | } 151 | else 152 | { 153 | AssignCommand(oNPC, ClearAllActions()); 154 | SimpleAI_PlayVoiceChat(VOICE_CHAT_CANDO, oNPC); 155 | } 156 | } 157 | } 158 | 159 | void AmbientNPCs_ReactLookHere(object oPlayer, object oNPC) 160 | { 161 | if (GetLocalInt(oNPC, "AmbientNPC_RecentlyLooked")) 162 | SimpleAI_PlayVoiceChat(VOICE_CHAT_NO, oNPC); 163 | else 164 | { 165 | SetLocalInt(oNPC, "AmbientNPC_RecentlyLooked", TRUE); 166 | DelayCommand(60.0f, DeleteLocalInt(oNPC, "AmbientNPC_RecentlyLooked")); 167 | 168 | SimpleAI_PlayVoiceChat(VOICE_CHAT_YES, oNPC); 169 | AssignCommand(oNPC, ClearAllActions()); 170 | AssignCommand(oNPC, ActionForceMoveToObject(oPlayer, FALSE, 1.0f, 30.0f)); 171 | AssignCommand(oNPC, ActionWait(1.0f + (Random(50) / 10.0f))); 172 | } 173 | } 174 | 175 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_autoiditem.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_autoiditem.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: An EventSystem Subsystem that automatically identifies the items a player acquires. 9 | If es_s_iditem is enabled, it will use its identify item skill instead of Lore. 10 | */ 11 | 12 | //void main() {} 13 | 14 | #include "es_inc_core" 15 | #include "es_cc_events" 16 | #include "es_srv_mediator" 17 | 18 | const string AUTOIDITEM_LOG_TAG = "AutoIdentifyItem"; 19 | const string AUTOIDITEM_SCRIPT_NAME = "es_s_autoiditem"; 20 | 21 | const string AUTOIDITEM_SKILL_NAME = "AutoIdentifySkill"; 22 | 23 | // @Load 24 | void AutoIDItem_Load(string sComponentScript) 25 | { 26 | Events_SubscribeEvent_Object(sComponentScript, EVENT_SCRIPT_MODULE_ON_ACQUIRE_ITEM); 27 | } 28 | 29 | // @EventHandler 30 | void AutoIDItem_EventHandler(string sComponentScript, string sEvent) 31 | { 32 | object oPlayer = GetModuleItemAcquiredBy(); 33 | object oItem = GetModuleItemAcquired(); 34 | 35 | if (GetIsPC(oPlayer) && !GetIdentified(oItem)) 36 | { 37 | int nIdentifySkill = GetLocalInt(ES_Util_GetDataObject(sComponentScript), AUTOIDITEM_SKILL_NAME); 38 | int nIdentifySkillRank = GetSkillRank(nIdentifySkill, oPlayer); 39 | int nMaxItemGPValue = StringToInt(Get2DAString("skillvsitemcost", "DeviceCostMax", nIdentifySkillRank == -1 ? 0 : nIdentifySkillRank > 55 ? 55 : nIdentifySkillRank)); 40 | 41 | SetIdentified(oItem, TRUE); 42 | 43 | int nGoldPieceValue = GetGoldPieceValue(oItem); 44 | if (nGoldPieceValue > nMaxItemGPValue) 45 | SetIdentified(oItem, FALSE); 46 | else 47 | FloatingTextStringOnCreature("Identified '" + GetName(oItem) + "'!", oPlayer, FALSE); 48 | } 49 | } 50 | 51 | // @Post 52 | void AutoIDItem_Post(string sComponentScript) 53 | { 54 | if (Mediator_ExecuteFunction("es_s_iditem", "IdentifyItem_GetIdentifySkill", "", GetModule(), FALSE)) 55 | { 56 | int nIdentifySkill = Mediator_GetReturnValueInt(); 57 | 58 | SetLocalInt(ES_Util_GetDataObject(sComponentScript), AUTOIDITEM_SKILL_NAME, nIdentifySkill); 59 | 60 | ES_Util_Log(AUTOIDITEM_LOG_TAG, "Subsystem 'es_s_iditem' is enabled, using its Identify Skill: " + Get2DAString("skills", "Label", nIdentifySkill)); 61 | } 62 | else 63 | { 64 | SetLocalInt(ES_Util_GetDataObject(sComponentScript), AUTOIDITEM_SKILL_NAME, SKILL_LORE); 65 | 66 | ES_Util_Log(AUTOIDITEM_LOG_TAG, "Subsystem 'es_s_iditem' is not enabled, using default Identify Skill: " + Get2DAString("skills", "Label", SKILL_LORE)); 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_charsave.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_charsave.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: An EventSystem subsystem that periodically saves all player 9 | characters and adds a chat command for players to manually 10 | save their character. Also limits how often player my export 11 | their character to their localvault. 12 | */ 13 | 14 | //void main() {} 15 | 16 | #include "es_inc_core" 17 | #include "es_cc_events" 18 | #include "es_srv_wtimer" 19 | #include "es_srv_chatcom" 20 | 21 | const string CHARACTERSAVE_LOG_TAG = "CharacterSave"; 22 | const string CHARACTERSAVE_SCRIPT_NAME = "es_s_charsave"; 23 | 24 | const string CHARACTERSAVE_CHAT_COMMAND = "save"; 25 | const string CHARACTERSAVE_AUTO_SAVE_INTERVAL = WORLD_TIMER_EVENT_5_MINUTES; 26 | 27 | const float CHARACTERSAVE_MANUAL_SAVE_COOLDOWN = 60.0f; 28 | const float CHARACTERSAVE_EXPORT_COOLDOWN = 300.0f; 29 | 30 | // @Load 31 | void CharacterSave_Load(string sSubsystemScript) 32 | { 33 | WorldTimer_SubscribeEvent(sSubsystemScript, CHARACTERSAVE_AUTO_SAVE_INTERVAL); 34 | Events_SubscribeEvent_NWNX(sSubsystemScript, "NWNX_ON_CLIENT_EXPORT_CHARACTER_BEFORE"); 35 | 36 | if (CHARACTERSAVE_CHAT_COMMAND != "") 37 | { 38 | int nId = ChatCommand_Register(sSubsystemScript, "CharacterSave_SaveChatCommand", 39 | CHATCOMMAND_GLOBAL_PREFIX + CHARACTERSAVE_CHAT_COMMAND, "", "Manually save your character."); 40 | 41 | ChatCommand_SetPermission(nId, "", "!GetIsDM(oPlayer)", "", ""); 42 | } 43 | } 44 | 45 | // @EventHandler 46 | void CharacterSave_EventHandler(string sSubsystemScript, string sEvent) 47 | { 48 | if (sEvent == CHARACTERSAVE_AUTO_SAVE_INTERVAL) 49 | { 50 | if (!ES_Util_GetPlayersOnline()) return; 51 | 52 | ES_Util_Log(CHARACTERSAVE_LOG_TAG, "Saving all characters."); 53 | 54 | object oPlayer = GetFirstPC(); 55 | while (GetIsObjectValid(oPlayer)) 56 | { 57 | if (!GetIsDM(oPlayer)) 58 | { 59 | ExportSingleCharacter(oPlayer); 60 | 61 | ES_Util_SendServerMessage("Your character has been automatically saved.", oPlayer); 62 | } 63 | 64 | oPlayer = GetNextPC(); 65 | } 66 | } 67 | else 68 | if (sEvent == "NWNX_ON_CLIENT_EXPORT_CHARACTER_BEFORE") 69 | { 70 | object oPlayer = OBJECT_SELF; 71 | 72 | if (GetIsDM(oPlayer)) 73 | return; 74 | 75 | object oDataObject = ES_Util_GetDataObject(CHARACTERSAVE_SCRIPT_NAME); 76 | string sExportCooldownVariable = "SaveCooldown_" + GetObjectUUID(oPlayer); 77 | 78 | if (!GetLocalInt(oDataObject, sExportCooldownVariable)) 79 | { 80 | SetLocalInt(oDataObject, sExportCooldownVariable, TRUE); 81 | DelayCommand(CHARACTERSAVE_EXPORT_COOLDOWN, DeleteLocalInt(oDataObject, sExportCooldownVariable)); 82 | } 83 | else 84 | { 85 | NWNX_Events_SkipEvent(); 86 | 87 | SendMessageToPC(oPlayer, ES_Util_ColorString("Request denied, you may only export your character every '" + 88 | FloatToString(CHARACTERSAVE_EXPORT_COOLDOWN, 0, 0) + "' seconds.", "700")); 89 | } 90 | } 91 | } 92 | 93 | void CharacterSave_SaveChatCommand(object oPlayer, string sParams, int nVolume) 94 | { 95 | object oDataObject = ES_Util_GetDataObject(CHARACTERSAVE_SCRIPT_NAME); 96 | string sSaveCooldownVariable = "SaveCooldown_" + GetObjectUUID(oPlayer); 97 | 98 | if (!GetLocalInt(oDataObject, sSaveCooldownVariable)) 99 | { 100 | ExportSingleCharacter(oPlayer); 101 | 102 | SetLocalInt(oDataObject, sSaveCooldownVariable, TRUE); 103 | DelayCommand(CHARACTERSAVE_MANUAL_SAVE_COOLDOWN, DeleteLocalInt(oDataObject, sSaveCooldownVariable)); 104 | 105 | ES_Util_SendServerMessage("Your character has been manually saved.", oPlayer); 106 | } 107 | else 108 | { 109 | ES_Util_SendServerMessage("You may only save your character every '" + 110 | FloatToString(CHARACTERSAVE_MANUAL_SAVE_COOLDOWN, 0, 0) + "' seconds.", oPlayer); 111 | } 112 | 113 | SetPCChatMessage(""); 114 | } 115 | 116 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_closedoor.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_closedoor.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: An EventSystem Subsystem that automatically closes doors. 9 | */ 10 | 11 | //void main() {} 12 | 13 | #include "es_inc_core" 14 | #include "es_cc_events" 15 | 16 | const string CLOSEDOOR_LOG_TAG = "CloseDoor"; 17 | const string CLOSEDOOR_SCRIPT_NAME = "es_s_closedoor"; 18 | 19 | const float CLOSEDOOR_CLOSE_DELAY = 7.5f; 20 | 21 | // @Load 22 | void CloseDoor_Load(string sComponentScript) 23 | { 24 | Events_SubscribeEvent_Object(sComponentScript, EVENT_SCRIPT_DOOR_ON_OPEN, EVENTS_EVENT_FLAG_AFTER, TRUE); 25 | 26 | object oDoor; 27 | int nNth = 1; 28 | string sDoorOnOpenEvent = Events_GetEventName_Object(EVENT_SCRIPT_DOOR_ON_OPEN, EVENTS_EVENT_FLAG_AFTER); 29 | 30 | while ((oDoor = NWNX_Util_GetLastCreatedObject(10, nNth++)) != OBJECT_INVALID) 31 | { 32 | if (NWNX_Object_GetDoorHasVisibleModel(oDoor)) 33 | { 34 | Events_SetObjectEventScript(oDoor, EVENT_SCRIPT_DOOR_ON_OPEN); 35 | Events_AddObjectToDispatchList(sComponentScript, sDoorOnOpenEvent, oDoor); 36 | } 37 | } 38 | } 39 | 40 | // @EventHandler 41 | void CloseDoor_EventHandler(string sComponentScript, string sEvent) 42 | { 43 | object oDoor = OBJECT_SELF; 44 | 45 | ClearAllActions(); 46 | ActionWait(CLOSEDOOR_CLOSE_DELAY); 47 | ActionCloseDoor(oDoor); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_dumplocals.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_dumplocals.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: An EventSystem Subsystem that replaces the dm_dumplocals 9 | console command with a NWScript implementation 10 | */ 11 | 12 | //void main() {} 13 | 14 | #include "es_inc_core" 15 | #include "es_cc_events" 16 | #include "es_srv_chatcom" 17 | #include "es_srv_mediator" 18 | 19 | const string DUMPLOCALS_LOG_TAG = "DumpLocals"; 20 | const string DUMPLOCALS_SCRIPT_NAME = "es_s_dumplocals"; 21 | 22 | const string DUMPLOCALS_CHATCOMMAND_NAME = "dumplocals"; 23 | const string DUMPLOCALS_CHATCOMMAND_DESCRIPTION = "Dump the locals of the targeted object."; 24 | 25 | const int DUMPLOCALS_TYPE_OBJECT = 0; 26 | const int DUMPLOCALS_TYPE_AREA = 1; 27 | const int DUMPLOCALS_TYPE_MODULE = 2; 28 | const int DUMPLOCALS_TYPE_CHAT_COMMAND = 3; 29 | 30 | // Dump the locals of oTarget, depending on nType 31 | void DumpLocals_DumpLocals(object oPlayer, int nType, object oTarget = OBJECT_INVALID); 32 | 33 | // @Load 34 | void DumpLocals_Load(string sSubsystemScript) 35 | { 36 | Events_SubscribeEvent_NWNX(sSubsystemScript, "NWNX_ON_DM_DUMP_LOCALS_BEFORE"); 37 | Events_SubscribeEvent_Object(sSubsystemScript, EVENT_SCRIPT_MODULE_ON_PLAYER_TARGET); 38 | 39 | Mediator_RegisterFunction(sSubsystemScript, "DumpLocals_DumpLocals", "oio"); 40 | 41 | ChatCommand_Register(sSubsystemScript, "DumpLocals_ChatCommand", CHATCOMMAND_GLOBAL_PREFIX + DUMPLOCALS_CHATCOMMAND_NAME, "", DUMPLOCALS_CHATCOMMAND_DESCRIPTION); 42 | } 43 | 44 | // @EventHandler 45 | void DumpLocals_EventHandler(string sSubsystemScript, string sEvent) 46 | { 47 | if (sEvent == "NWNX_ON_DM_DUMP_LOCALS_BEFORE") 48 | { 49 | object oDM = OBJECT_SELF; 50 | object oTarget = Events_GetEventData_NWNX_Object("TARGET"); 51 | int nType = Events_GetEventData_NWNX_Int("TYPE"); 52 | 53 | DumpLocals_DumpLocals(oDM, nType, oTarget); 54 | 55 | Events_SkipEvent(); 56 | } 57 | else 58 | if (StringToInt(sEvent) == EVENT_SCRIPT_MODULE_ON_PLAYER_TARGET) 59 | { 60 | object oPlayer = GetLastPlayerToSelectTarget(); 61 | 62 | if (Events_GetCurrentTargetingMode(oPlayer) == DUMPLOCALS_SCRIPT_NAME) 63 | { 64 | DumpLocals_DumpLocals(oPlayer, DUMPLOCALS_TYPE_CHAT_COMMAND, GetTargetingModeSelectedObject()); 65 | } 66 | } 67 | } 68 | 69 | void DumpLocals_ChatCommand(object oPlayer, string sParams, int nVolume) 70 | { 71 | Events_EnterTargetingMode(oPlayer, DUMPLOCALS_SCRIPT_NAME); 72 | SetPCChatMessage(""); 73 | } 74 | 75 | void DumpLocals_DumpLocals(object oPlayer, int nType, object oTarget = OBJECT_INVALID) 76 | { 77 | string sMessage; 78 | 79 | switch (nType) 80 | { 81 | case DUMPLOCALS_TYPE_OBJECT: // dm_dumplocals 82 | { 83 | sMessage = "*** Variable Dump *** [Object] Tag: " + GetTag(oTarget); 84 | break; 85 | } 86 | case DUMPLOCALS_TYPE_AREA: // dm_dumparealocals 87 | { 88 | oTarget = GetArea(oTarget); 89 | sMessage = "*** Variable Dump *** [Area] Tag: " + GetTag(oTarget); 90 | break; 91 | } 92 | case DUMPLOCALS_TYPE_MODULE: // dm_dumpmodulelocals 93 | { 94 | oTarget = GetModule(); 95 | sMessage = "*** Variable Dump *** [Module]"; 96 | break; 97 | } 98 | case DUMPLOCALS_TYPE_CHAT_COMMAND: 99 | { 100 | sMessage = "*** Variable Dump *** [" + GetName(oTarget) + "] Tag: " + GetTag(oTarget); 101 | break; 102 | } 103 | } 104 | 105 | if (!GetIsObjectValid(oTarget)) return; 106 | 107 | int nCount = NWNX_Object_GetLocalVariableCount(oTarget); 108 | 109 | if (!nCount) 110 | { 111 | sMessage += "\nNone defined."; 112 | } 113 | else 114 | { 115 | int i; 116 | for(i = 0; i < nCount; i++) 117 | { 118 | struct NWNX_Object_LocalVariable var = NWNX_Object_GetLocalVariable(oTarget, i); 119 | 120 | switch (var.type) 121 | { 122 | case NWNX_OBJECT_LOCALVAR_TYPE_UNKNOWN: 123 | sMessage += "\n[UNKNOWN] " + var.key + " = ?"; 124 | break; 125 | 126 | case NWNX_OBJECT_LOCALVAR_TYPE_INT: 127 | sMessage += "\n[INT] " + var.key + " = " + IntToString(GetLocalInt(oTarget, var.key)); 128 | break; 129 | 130 | case NWNX_OBJECT_LOCALVAR_TYPE_FLOAT: 131 | sMessage += "\n[FLT] " + var.key + " = " + FloatToString(GetLocalFloat(oTarget, var.key), 0); 132 | break; 133 | 134 | case NWNX_OBJECT_LOCALVAR_TYPE_STRING: 135 | sMessage += "\n[STR] " + var.key + " = \"" + GetLocalString(oTarget, var.key) + "\""; 136 | break; 137 | 138 | case NWNX_OBJECT_LOCALVAR_TYPE_OBJECT: 139 | sMessage += "\n[OID] " + var.key + " = " + ObjectToString(GetLocalObject(oTarget, var.key)); 140 | break; 141 | 142 | case NWNX_OBJECT_LOCALVAR_TYPE_LOCATION: 143 | { 144 | location locLocation = GetLocalLocation(oTarget, var.key); 145 | object oArea = GetAreaFromLocation(locLocation); 146 | vector vPos = GetPositionFromLocation(locLocation); 147 | 148 | sMessage += "\n[LOC] " + var.key + " = (" + GetTag(oArea) + ")(" + FloatToString(vPos.x, 0, 3) + ", " + FloatToString(vPos.y, 0, 3) + ", " + FloatToString(vPos.z, 0, 3) + ")"; 149 | break; 150 | } 151 | } 152 | } 153 | } 154 | 155 | if (oPlayer == OBJECT_INVALID) 156 | PrintString(sMessage); 157 | else 158 | SendMessageToPC(oPlayer, sMessage); 159 | } 160 | 161 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_emote.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_emote.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: A subsystem that adds an /emote chat command that allows players to emote 9 | */ 10 | 11 | //void main() {} 12 | 13 | #include "es_inc_core" 14 | #include "es_srv_chatcom" 15 | 16 | const float EMOTE_DURATION_LOOPING = 86400.0f; 17 | 18 | // @Load 19 | void Emote_Load(string sSubsystemScript) 20 | { 21 | ChatCommand_Register(sSubsystemScript, "Emote_HandleEmoteChatCommand", CHATCOMMAND_GLOBAL_PREFIX + "emote", "[emote]", "Perform an emote!"); 22 | } 23 | 24 | void Emote_DoEmote(object oPlayer, int nEmote, float fDuration = 0.0f) 25 | { 26 | AssignCommand(oPlayer, ClearAllActions()); 27 | AssignCommand(oPlayer, ActionPlayAnimation(nEmote, 1.0, fDuration)); 28 | } 29 | 30 | void Emote_HandleEmoteChatCommand(object oPlayer, string sEmote, int nVolume) 31 | { 32 | if (sEmote == "bow") 33 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_BOW); 34 | else 35 | if (sEmote == "duck") 36 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_DODGE_DUCK); 37 | else 38 | if (sEmote == "dodge") 39 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_DODGE_SIDE); 40 | else 41 | if (sEmote == "drink") 42 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_DRINK); 43 | else 44 | if (sEmote == "greet") 45 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_GREETING); 46 | else 47 | if (sEmote == "bored") 48 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_PAUSE_BORED); 49 | else 50 | if (sEmote == "scratch") 51 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_PAUSE_SCRATCH_HEAD); 52 | else 53 | if (sEmote == "read") 54 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_READ); 55 | else 56 | if (sEmote == "salute") 57 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_SALUTE); 58 | else 59 | if (sEmote == "steal") 60 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_STEAL); 61 | else 62 | if (sEmote == "taunt") 63 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_TAUNT); 64 | else 65 | if (sEmote == "victory1") 66 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_VICTORY1); 67 | else 68 | if (sEmote == "victory2") 69 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_VICTORY2); 70 | else 71 | if (sEmote == "victory3") 72 | Emote_DoEmote(oPlayer, ANIMATION_FIREFORGET_VICTORY3); 73 | else 74 | if (sEmote == "cast1") 75 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_CONJURE1, EMOTE_DURATION_LOOPING); 76 | else 77 | if (sEmote == "cast2") 78 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_CONJURE2, EMOTE_DURATION_LOOPING); 79 | else 80 | if (sEmote == "deadback") 81 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_DEAD_BACK, EMOTE_DURATION_LOOPING); 82 | else 83 | if (sEmote == "deadfront") 84 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_DEAD_FRONT, EMOTE_DURATION_LOOPING); 85 | else 86 | if (sEmote == "low") 87 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_GET_LOW, EMOTE_DURATION_LOOPING); 88 | else 89 | if (sEmote == "mid") 90 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_GET_MID, EMOTE_DURATION_LOOPING); 91 | else 92 | if (sEmote == "meditate") 93 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_MEDITATE, EMOTE_DURATION_LOOPING); 94 | else 95 | if (sEmote == "drunk") 96 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_PAUSE_DRUNK, EMOTE_DURATION_LOOPING); 97 | else 98 | if (sEmote == "tired") 99 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_PAUSE_TIRED, EMOTE_DURATION_LOOPING); 100 | else 101 | if (sEmote == "sit") 102 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_SIT_CROSS, EMOTE_DURATION_LOOPING); 103 | else 104 | if (sEmote == "spasm") 105 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_SPASM, EMOTE_DURATION_LOOPING); 106 | else 107 | if (sEmote == "forceful") 108 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_TALK_FORCEFUL, EMOTE_DURATION_LOOPING); 109 | else 110 | if (sEmote == "laugh") 111 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_TALK_LAUGHING, EMOTE_DURATION_LOOPING); 112 | else 113 | if (sEmote == "talk") 114 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_TALK_NORMAL, EMOTE_DURATION_LOOPING); 115 | else 116 | if (sEmote == "plead") 117 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_TALK_PLEADING, EMOTE_DURATION_LOOPING); 118 | else 119 | if (sEmote == "worship") 120 | Emote_DoEmote(oPlayer, ANIMATION_LOOPING_WORSHIP, EMOTE_DURATION_LOOPING); 121 | else 122 | { 123 | SendMessageToPC(oPlayer, "Available Emotes: bow, duck, dodge, drink, greet, bored, scratch, " + 124 | "read, salute, steal, taunt, victory1, victory2, victory3, cast1, cast2, deadback, deadfront, " + 125 | "low, mid, meditate, drunk, tired, sit, spasm, forceful, laugh, talk, plead, worship"); 126 | } 127 | 128 | SetPCChatMessage(""); 129 | } 130 | 131 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_iditem.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_iditem.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: An EventSystem Subsystem that replaces the skill needed to 9 | identify an item with a custom one. 10 | */ 11 | 12 | //void main() {} 13 | 14 | #include "es_inc_core" 15 | #include "es_cc_events" 16 | #include "es_srv_mediator" 17 | 18 | const string IDITEM_LOG_TAG = "IdentifyItem"; 19 | const string IDITEM_SCRIPT_NAME = "es_s_iditem"; 20 | 21 | const int IDITEM_IDENTIFY_SKILL = SKILL_SPELLCRAFT; 22 | 23 | // Returns the skill used to identify items 24 | int IdentifyItem_GetIdentifySkill(); 25 | 26 | // @Load 27 | void IdentifyItem_Load(string sSubsystemScript) 28 | { 29 | Events_SubscribeEvent_NWNX(sSubsystemScript, "NWNX_ON_ITEM_USE_LORE_BEFORE"); 30 | Mediator_RegisterFunction(sSubsystemScript, "IdentifyItem_GetIdentifySkill", "", "i"); 31 | } 32 | 33 | // @EventHandler 34 | void IdentifyItem_EventHandler(string sSubsystemScript, string sEvent) 35 | { 36 | if (sEvent == "NWNX_ON_ITEM_USE_LORE_BEFORE") 37 | { 38 | object oPlayer = OBJECT_SELF; 39 | object oItem = Events_GetEventData_NWNX_Object("ITEM"); 40 | 41 | SetIdentified(oItem, TRUE); 42 | 43 | int nIdentifySkillRank = GetSkillRank(IDITEM_IDENTIFY_SKILL, oPlayer); 44 | int nMaxItemGPValue = StringToInt(Get2DAString("skillvsitemcost", "DeviceCostMax", nIdentifySkillRank == -1 ? 0 : nIdentifySkillRank > 55 ? 55 : nIdentifySkillRank)); 45 | int nGoldPieceValue = GetGoldPieceValue(oItem); 46 | 47 | if (nGoldPieceValue > nMaxItemGPValue) 48 | { 49 | SetIdentified(oItem, FALSE); 50 | Events_SkipEvent(); 51 | } 52 | } 53 | } 54 | 55 | int IdentifyItem_GetIdentifySkill() 56 | { 57 | return IDITEM_IDENTIFY_SKILL; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_intchair.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_intchair.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: 9 | */ 10 | 11 | //void main() {} 12 | 13 | #include "es_inc_core" 14 | #include "es_cc_events" 15 | #include "es_srv_toolbox" 16 | #include "es_srv_simdialog" 17 | 18 | const string INTCHAIR_LOG_TAG = "InteractiveChair"; 19 | const string INTCHAIRT_SCRIPT_NAME = "es_s_intchair"; 20 | 21 | const string INTCHAIR_WAYPOINT_TAG = "INTCHAIR_SPAWN"; 22 | 23 | void InteractiveChair_SpawnChairs(string sSubsystemScript); 24 | 25 | // @Load 26 | void InteractiveChair_Load(string sSubsystemScript) 27 | { 28 | Events_SubscribeEvent_Object(sSubsystemScript, EVENT_SCRIPT_PLACEABLE_ON_USED, EVENTS_EVENT_FLAG_DEFAULT, TRUE); 29 | Events_SubscribeEvent_Object(sSubsystemScript, EVENT_SCRIPT_TRIGGER_ON_OBJECT_ENTER, EVENTS_EVENT_FLAG_DEFAULT, TRUE); 30 | Events_SubscribeEvent_Object(sSubsystemScript, EVENT_SCRIPT_TRIGGER_ON_OBJECT_EXIT, EVENTS_EVENT_FLAG_DEFAULT, TRUE); 31 | 32 | SimpleDialog_SubscribeEvent(sSubsystemScript, SIMPLE_DIALOG_EVENT_ACTION_TAKEN, TRUE); 33 | 34 | object oConversation = SimpleDialog_CreateConversation(sSubsystemScript); 35 | SimpleDialog_AddPage(oConversation, "Sitting Action Menu.", TRUE); 36 | SimpleDialog_AddOption(oConversation, SimpleDialog_Token_Action("[Sit]")); 37 | 38 | InteractiveChair_SpawnChairs(sSubsystemScript); 39 | } 40 | 41 | // @EventHandler 42 | void InteractiveChair_EventHandler(string sSubsystemScript, string sEvent) 43 | { 44 | if (sEvent == SIMPLE_DIALOG_EVENT_ACTION_TAKEN) 45 | { 46 | int nOption = Events_GetEventData_NWNX_Int("OPTION"); 47 | object oPlayer = Events_GetEventData_NWNX_Object("PLAYER"); 48 | object oChair = GetLocalObject(oPlayer, "INTCHAIR_CURRENT_CHAIR"); 49 | 50 | if (nOption == 1) 51 | { 52 | AssignCommand(oPlayer, ActionSit(oChair)); 53 | } 54 | } 55 | else 56 | switch (StringToInt(sEvent)) 57 | { 58 | case EVENT_SCRIPT_PLACEABLE_ON_USED: 59 | { 60 | object oSelf = OBJECT_SELF; 61 | object oPlayer = GetLastUsedBy(); 62 | 63 | if (!GetIsObjectValid(GetSittingCreature(oSelf))) 64 | { 65 | //SimpleDialog_StartConversation(oPlayer, oSelf, sSubsystemScript); 66 | AssignCommand(oPlayer, ActionSit(oSelf)); 67 | } 68 | 69 | break; 70 | } 71 | 72 | case EVENT_SCRIPT_TRIGGER_ON_OBJECT_ENTER: 73 | { 74 | object oTrigger = OBJECT_SELF; 75 | object oPlayer = GetEnteringObject(); 76 | object oChair = GetLocalObject(oTrigger, "INTCHAIR_CHAIR"); 77 | 78 | SetLocalObject(oPlayer, "INTCHAIR_CURRENT_CHAIR", oChair); 79 | 80 | Events_AddObjectToDispatchList(sSubsystemScript, SIMPLE_DIALOG_EVENT_ACTION_TAKEN, oPlayer); 81 | 82 | SimpleDialog_StartConversation(oPlayer, oPlayer, sSubsystemScript); 83 | 84 | break; 85 | } 86 | 87 | case EVENT_SCRIPT_TRIGGER_ON_OBJECT_EXIT: 88 | { 89 | object oTrigger = OBJECT_SELF; 90 | object oPlayer = GetExitingObject(); 91 | 92 | DeleteLocalObject(oPlayer, "INTCHAIR_CURRENT_CHAIR"); 93 | 94 | SimpleDialog_AbortConversation(oPlayer); 95 | Events_RemoveObjectFromDispatchList(sSubsystemScript, SIMPLE_DIALOG_EVENT_ACTION_TAKEN, oPlayer); 96 | 97 | break; 98 | } 99 | } 100 | } 101 | 102 | void InteractiveChair_SpawnChairs(string sSubsystemScript) 103 | { 104 | int nNth = 0; 105 | object oSpawnpoint; 106 | 107 | struct Toolbox_CircleTriggerData ctd; 108 | ctd.sTag = "INTCHAIR_TRIGGER"; 109 | ctd.fRadius = 1.25f; 110 | ctd.nPoints = 12; 111 | ctd.scriptOnEnter = TRUE; 112 | ctd.scriptOnExit = TRUE; 113 | //ctd.scriptOnClick = TRUE; 114 | 115 | struct Toolbox_PlaceableData pd; 116 | pd.nModel = 179; 117 | pd.sTag = "INTCHAIR_CHAIR"; 118 | pd.sName = "Chair"; 119 | pd.sDescription = "It is a simple chair but the grace of its lines speaks to the quality of its craftmanship."; 120 | pd.bPlot = TRUE; 121 | //pd.bUseable = TRUE; 122 | //pd.scriptOnUsed = TRUE; 123 | 124 | string sSerializedChair = Toolbox_GeneratePlaceable(pd); 125 | 126 | string sPlaceableOnUsed = Events_GetEventName_Object(EVENT_SCRIPT_PLACEABLE_ON_USED); 127 | string sTriggerOnEnter = Events_GetEventName_Object(EVENT_SCRIPT_TRIGGER_ON_OBJECT_ENTER); 128 | string sTriggerOnExit = Events_GetEventName_Object(EVENT_SCRIPT_TRIGGER_ON_OBJECT_EXIT); 129 | 130 | while ((oSpawnpoint = GetObjectByTag(INTCHAIR_WAYPOINT_TAG, nNth++)) != OBJECT_INVALID) 131 | { 132 | location locSpawn = GetLocation(oSpawnpoint); 133 | object oTrigger = Toolbox_CreateCircleTrigger(ctd, locSpawn); 134 | object oChair = Toolbox_CreatePlaceable(sSerializedChair, locSpawn); 135 | 136 | SetLocalObject(oTrigger, GetTag(oChair), oChair); 137 | SetLocalObject(oChair, GetTag(oTrigger), oTrigger); 138 | 139 | Events_AddObjectToDispatchList(sSubsystemScript, sPlaceableOnUsed, oChair); 140 | Events_AddObjectToDispatchList(sSubsystemScript, sTriggerOnEnter, oTrigger); 141 | Events_AddObjectToDispatchList(sSubsystemScript, sTriggerOnExit, oTrigger); 142 | } 143 | } 144 | 145 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_objsit.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_objsit.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: An EventSystem Subsystem that allows players to sit on objects 9 | with the following tag: OBJSIT_SINGLE 10 | */ 11 | 12 | //void main() {} 13 | 14 | #include "es_inc_core" 15 | #include "es_cc_events" 16 | #include "es_srv_simdialog" 17 | #include "es_srv_toolbox" 18 | 19 | const string OBJSIT_LOG_TAG = "ObjectSit"; 20 | const string OBJSIT_SCRIPT_NAME = "es_s_objsit"; 21 | 22 | const string OBJSIT_SINGLE_SPAWN_TAG = "OBJSIT_SINGLE"; 23 | 24 | void ObjectSit_SpawnSittingObjects(string sSubsystemScript); 25 | 26 | // @Load 27 | void ObjectSit_Load(string sSubsystemScript) 28 | { 29 | Events_SubscribeEvent_Object(sSubsystemScript, EVENT_SCRIPT_PLACEABLE_ON_USED, EVENTS_EVENT_FLAG_DEFAULT, TRUE); 30 | SimpleDialog_SubscribeEvent(sSubsystemScript, SIMPLE_DIALOG_EVENT_ACTION_TAKEN, TRUE); 31 | SimpleDialog_SubscribeEvent(sSubsystemScript, SIMPLE_DIALOG_EVENT_CONDITIONAL_PAGE, TRUE); 32 | 33 | object oConversation = SimpleDialog_CreateConversation(sSubsystemScript); 34 | SimpleDialog_AddPage(oConversation, "Sitting Action Menu.", TRUE); 35 | SimpleDialog_AddOption(oConversation, SimpleDialog_Token_Action("[Rotate clockwise]")); 36 | SimpleDialog_AddOption(oConversation, SimpleDialog_Token_Action("[Rotate counter-clockwise]")); 37 | SimpleDialog_AddOption(oConversation, SimpleDialog_Token_Action("[Do nothing]")); 38 | 39 | ObjectSit_SpawnSittingObjects(sSubsystemScript); 40 | } 41 | 42 | // @EventHandler 43 | void ObjectSit_EventHandler(string sSubsystemScript, string sEvent) 44 | { 45 | if (sEvent == SIMPLE_DIALOG_EVENT_CONDITIONAL_PAGE) 46 | { 47 | SimpleDialog_SetOverrideText("While sitting on the " + GetStringLowerCase(GetName(OBJECT_SELF)) + " you..."); 48 | } 49 | else 50 | if (sEvent == SIMPLE_DIALOG_EVENT_ACTION_TAKEN) 51 | { 52 | object oSittingObject = OBJECT_SELF; 53 | object oPlayer = Events_GetEventData_NWNX_Object("PLAYER"); 54 | int nOption = Events_GetEventData_NWNX_Int("OPTION"); 55 | 56 | if (GetSittingCreature(oSittingObject) != oPlayer) 57 | { 58 | SimpleDialog_EndConversation(oPlayer); 59 | return; 60 | } 61 | 62 | switch (nOption) 63 | { 64 | case 1: 65 | case 2: 66 | NWNX_Object_SetFacing(oSittingObject, GetFacing(oSittingObject) + (nOption == 1 ? -20.0f : 20.0f)); 67 | break; 68 | 69 | case 3: 70 | SimpleDialog_EndConversation(oPlayer); 71 | break; 72 | } 73 | } 74 | else 75 | { 76 | switch (StringToInt(sEvent)) 77 | { 78 | case EVENT_SCRIPT_PLACEABLE_ON_USED: 79 | { 80 | object oSittingObject = OBJECT_SELF; 81 | object oPlayer = GetLastUsedBy(); 82 | 83 | if (!GetIsObjectValid(GetSittingCreature(oSittingObject))) 84 | { 85 | SimpleDialog_StartConversation(oPlayer, oSittingObject, sSubsystemScript); 86 | //SetLocalObject(oPlayer, "OBJSIT_SINGLE_CHAIR", oSittingObject); 87 | //Events_AddObjectToDispatchList(sSubsystemScript, "NWNX_ON_INPUT_KEYBOARD_BEFORE", oPlayer); 88 | 89 | AssignCommand(oPlayer, ActionSit(oSittingObject)); 90 | } 91 | 92 | break; 93 | } 94 | } 95 | } 96 | } 97 | 98 | void ObjectSit_SpawnSittingObjects(string sSubsystemScript) 99 | { 100 | struct Toolbox_PlaceableData pd; 101 | pd.nModel = 179; 102 | pd.sTag = "OBJSIT_SINGLE_CHAIR"; 103 | pd.sName = "Chair"; 104 | pd.sDescription = "It is a simple chair but the grace of its lines speaks to the quality of its craftmanship."; 105 | pd.bPlot = TRUE; 106 | pd.bUseable = TRUE; 107 | pd.scriptOnUsed = TRUE; 108 | pd.fFacingAdjustment = 180.0f; 109 | 110 | string sSerializedChair = Toolbox_GeneratePlaceable(pd); 111 | 112 | int nNth = 0; 113 | object oSpawnpoint; 114 | while ((oSpawnpoint = GetObjectByTag(OBJSIT_SINGLE_SPAWN_TAG, nNth++)) != OBJECT_INVALID) 115 | { 116 | object oSittingObject = Toolbox_CreatePlaceable(sSerializedChair, GetLocation(oSpawnpoint)); 117 | 118 | SetLocalObject(oSpawnpoint, "OBJSIT_SINGLE_CHAIR", oSittingObject); 119 | 120 | Events_AddObjectToAllDispatchLists(sSubsystemScript, oSittingObject); 121 | } 122 | 123 | ES_Util_Log(OBJSIT_LOG_TAG, "* Created '" + IntToString(--nNth) + "' Sitting Objects"); 124 | } 125 | 126 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_persisthp.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_persisthp.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[Object] 7 | 8 | Description: An EventSystem Subsystem that saves a player's hitpoints to 9 | their .bic file when they log out and sets their hitpoints 10 | when they log back in. 11 | */ 12 | 13 | //void main() {} 14 | 15 | #include "es_inc_core" 16 | #include "es_cc_events" 17 | #include "es_cc_pos" 18 | 19 | const string PERSISTENT_HITPOINTS_LOG_TAG = "PersistentHitPoints"; 20 | const string PERSISTENT_HITPOINTS_SCRIPT_NAME = "es_s_persisthp"; 21 | 22 | void PersistentHitPoints_SaveHitPoints(object oPlayer); 23 | void PersistentHitPoints_RestoreHitPoints(object oPlayer); 24 | 25 | // @Load 26 | void PersistentHitPoints_Load(string sSubsystemScript) 27 | { 28 | Events_SubscribeEvent_NWNX(sSubsystemScript, "NWNX_ON_CLIENT_DISCONNECT_BEFORE"); 29 | Events_SubscribeEvent_Object(sSubsystemScript, EVENT_SCRIPT_MODULE_ON_CLIENT_ENTER); 30 | } 31 | 32 | // @EventHandler 33 | void PersistentHitPoints_EventHandler(string sSubsystemScript, string sEvent) 34 | { 35 | if (sEvent == "NWNX_ON_CLIENT_DISCONNECT_BEFORE") 36 | PersistentHitPoints_SaveHitPoints(OBJECT_SELF); 37 | else 38 | if (StringToInt(sEvent) == EVENT_SCRIPT_MODULE_ON_CLIENT_ENTER) 39 | PersistentHitPoints_RestoreHitPoints(GetEnteringObject()); 40 | } 41 | 42 | void PersistentHitPoints_SaveHitPoints(object oPlayer) 43 | { 44 | if (!GetIsObjectValid(oPlayer) || GetIsDM(oPlayer) || GetIsDMPossessed(oPlayer)) return; 45 | 46 | object oMaster = GetMaster(oPlayer); 47 | if (GetIsObjectValid(oMaster)) oPlayer = oMaster; 48 | 49 | POS_SetInt(oPlayer, PERSISTENT_HITPOINTS_SCRIPT_NAME + "_Dead", GetIsDead(oPlayer), TRUE); 50 | POS_SetInt(oPlayer, PERSISTENT_HITPOINTS_SCRIPT_NAME + "_HP", GetCurrentHitPoints(oPlayer), TRUE); 51 | } 52 | 53 | void PersistentHitPoints_RestoreHitPoints(object oPlayer) 54 | { 55 | if (GetIsDM(oPlayer)) return; 56 | 57 | int bDead = POS_GetInt(oPlayer, PERSISTENT_HITPOINTS_SCRIPT_NAME + "_Dead"); 58 | 59 | if (bDead) 60 | ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDeath(), oPlayer); 61 | else 62 | { 63 | int nHitPoints = POS_GetInt(oPlayer, PERSISTENT_HITPOINTS_SCRIPT_NAME + "_HP"); 64 | int nMaxHitPoints = GetMaxHitPoints(oPlayer); 65 | 66 | if (nHitPoints > 0 && nHitPoints < nMaxHitPoints) 67 | NWNX_Object_SetCurrentHitPoints(oPlayer, nHitPoints); 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_persistloc.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_persistloc.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[ELC Player] 7 | 8 | Description: An EventSystem Subsystem that saves a player's location to 9 | their .bic file when they log out and respawns them there 10 | when the server is restarted. 11 | */ 12 | 13 | //void main() {} 14 | 15 | #include "es_inc_core" 16 | #include "es_cc_events" 17 | #include "es_cc_pos" 18 | #include "nwnx_player" 19 | 20 | const string PERSISTENT_LOCATION_LOG_TAG = "PersistentLocation"; 21 | const string PERSISTENT_LOCATION_SCRIPT_NAME = "es_s_persistloc"; 22 | 23 | void PersistentLocation_SaveLocation(object oPlayer); 24 | void PersistentLocation_LoadLocation(object oPlayer); 25 | 26 | // @Load 27 | void PersistentLocation_Load(string sSubsystemScript) 28 | { 29 | Events_SubscribeEvent_NWNX(sSubsystemScript, "NWNX_ON_CLIENT_DISCONNECT_BEFORE"); 30 | Events_SubscribeEvent_NWNX(sSubsystemScript, "NWNX_ON_ELC_VALIDATE_CHARACTER_AFTER"); 31 | } 32 | 33 | // @EventHandler 34 | void PersistentLocation_EventHandler(string sSubsystemScript, string sEvent) 35 | { 36 | if (sEvent == "NWNX_ON_CLIENT_DISCONNECT_BEFORE") 37 | PersistentLocation_SaveLocation(OBJECT_SELF); 38 | else 39 | if (sEvent == "NWNX_ON_ELC_VALIDATE_CHARACTER_AFTER") 40 | PersistentLocation_LoadLocation(OBJECT_SELF); 41 | } 42 | 43 | void PersistentLocation_SaveLocation(object oPlayer) 44 | { 45 | if (!GetIsObjectValid(oPlayer) || GetIsDM(oPlayer) || GetIsDMPossessed(oPlayer)) return; 46 | 47 | object oMaster = GetMaster(oPlayer); 48 | if (GetIsObjectValid(oMaster)) oPlayer = oMaster; 49 | 50 | POS_SetLocation(oPlayer, PERSISTENT_LOCATION_SCRIPT_NAME + "_Location", GetLocation(oPlayer), TRUE); 51 | } 52 | 53 | void PersistentLocation_LoadLocation(object oPlayer) 54 | { 55 | string sUUID = GetObjectUUID(oPlayer); 56 | object oDataObject = ES_Util_GetDataObject(PERSISTENT_LOCATION_SCRIPT_NAME); 57 | 58 | if (!GetLocalInt(oDataObject, sUUID)) 59 | { 60 | location locLocation = POS_GetLocation(oPlayer, PERSISTENT_LOCATION_SCRIPT_NAME + "_Location"); 61 | 62 | if (GetAreaFromLocation(locLocation) != OBJECT_INVALID) 63 | NWNX_Player_SetSpawnLocation(oPlayer, locLocation); 64 | 65 | SetLocalInt(oDataObject, sUUID, TRUE); 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_portrait.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_portrait.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[Player] 7 | 8 | Description: A Portrait Change Subsystem 9 | */ 10 | 11 | //void main() {} 12 | 13 | #include "es_inc_core" 14 | #include "es_cc_events" 15 | #include "es_srv_gui" 16 | #include "es_srv_simdialog" 17 | #include "es_srv_chatcom" 18 | 19 | #include "nwnx_player" 20 | 21 | const string PORTRAIT_LOG_TAG = "Portrait"; 22 | const string PORTRAIT_SCRIPT_NAME = "es_s_portrait"; 23 | const string PORTRAIT_CHATCOMMAND_NAME = "portrait"; 24 | const string PORTRAIT_CHATCOMMAND_DESCRIPTION = "Change your portrait!"; 25 | const int PORTRAIT_GUI_NUM_IDS = 70; 26 | const string PORTRAIT_FONT_TEXTURE_NAME = "fnt_es_portrait"; 27 | const string PORTRAIT_GLYPH_NAME = "a"; 28 | 29 | // @Load 30 | void Portrait_Load(string sSubsystemScript) 31 | { 32 | SimpleDialog_SubscribeEvent(sSubsystemScript, SIMPLE_DIALOG_EVENT_ACTION_TAKEN, TRUE); 33 | SimpleDialog_SubscribeEvent(sSubsystemScript, SIMPLE_DIALOG_EVENT_CONVERSATION_END, TRUE); 34 | 35 | object oConversation = SimpleDialog_CreateConversation(sSubsystemScript); 36 | SimpleDialog_AddPage(oConversation, SIMPLE_DIALOG_BLANK_ENTRY_TEXT); // Portrait Change Menu 37 | SimpleDialog_AddOption(oConversation, SIMPLE_DIALOG_BLANK_ENTRY_TEXT); // Select 38 | SimpleDialog_AddOption(oConversation, SIMPLE_DIALOG_BLANK_ENTRY_TEXT); // Next 39 | SimpleDialog_AddOption(oConversation, SIMPLE_DIALOG_BLANK_ENTRY_TEXT); // Previous 40 | SimpleDialog_AddOption(oConversation, SIMPLE_DIALOG_BLANK_ENTRY_TEXT); // Race 41 | SimpleDialog_AddOption(oConversation, SIMPLE_DIALOG_BLANK_ENTRY_TEXT); // Gender 42 | SimpleDialog_AddOption(oConversation, SIMPLE_DIALOG_BLANK_ENTRY_TEXT); // End 43 | 44 | ChatCommand_Register(sSubsystemScript, "Portrait_ChatCommand", CHATCOMMAND_GLOBAL_PREFIX + PORTRAIT_CHATCOMMAND_NAME, "", PORTRAIT_CHATCOMMAND_DESCRIPTION); 45 | 46 | GUI_ReserveIDs(sSubsystemScript, PORTRAIT_GUI_NUM_IDS); 47 | } 48 | 49 | string Portrait_GetPortraitTexture(int nPortraitNumber, int nRace, int nGender) 50 | { 51 | string sNumber = nPortraitNumber < 10 ? "0" + IntToString(nPortraitNumber) : IntToString(nPortraitNumber); 52 | string sRace = GetSubString("dwelgnhahuorhu", 2 * nRace, 2); 53 | string sGender = !nGender ? "m" : "f"; 54 | 55 | string sPortrait = "po_" + sRace + "_" + sGender + "_" + sNumber + "_"; 56 | 57 | if (NWNX_Util_IsValidResRef(sPortrait + "h", 3/* TGA */)) 58 | return sPortrait; 59 | else 60 | return "po_hu_" + sGender + "_99_"; 61 | } 62 | 63 | void Portrait_DrawMainPortraitGUI(object oPlayer) 64 | { 65 | int nID = GUI_GetEndID(PORTRAIT_SCRIPT_NAME); 66 | int nTextColor = GUI_COLOR_WHITE; 67 | int nPortraitColor = GUI_COLOR_WHITE; 68 | string sTextFont = GUI_FONT_TEXT_NAME; 69 | float fLifeTime = 0.0f; 70 | 71 | // Conversation Window 72 | nID -= GUI_DrawConversationWindow(oPlayer, nID, 51, 31, fLifeTime, FALSE); 73 | 74 | // Options Window 75 | nID -= GUI_DrawWindow(oPlayer, nID, SCREEN_ANCHOR_TOP_LEFT, 1, 5, 13, 8, fLifeTime, FALSE); 76 | 77 | // Portrait Texture 78 | PostString(oPlayer, PORTRAIT_GLYPH_NAME, 15, 2, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nPortraitColor, nPortraitColor, nID--, PORTRAIT_FONT_TEXTURE_NAME); 79 | 80 | // Header Window 81 | nID -= GUI_DrawWindow(oPlayer, nID, SCREEN_ANCHOR_TOP_LEFT, 14, 0, 32, 1, fLifeTime, FALSE); 82 | 83 | // Header Text 84 | string sHeader = GetName(oPlayer) + "'s Portrait"; 85 | PostString(oPlayer, sHeader, GUI_CenterStringInWindow(sHeader, 14, 32), 1, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nTextColor, nTextColor, nID--, sTextFont); 86 | 87 | // Portrait Name Window 88 | nID -= GUI_DrawWindow(oPlayer, nID, SCREEN_ANCHOR_TOP_LEFT, 14, 29, 32, 1, fLifeTime, FALSE); 89 | } 90 | 91 | void Portrait_UpdatePortraitGUI(object oPlayer, int nPortraitNumber, int nRace, int nGender) 92 | { 93 | int nID = GUI_GetStartID(PORTRAIT_SCRIPT_NAME); 94 | int nTextColor = GUI_COLOR_WHITE; 95 | string sTextFont = GUI_FONT_TEXT_NAME; 96 | int nPortraitTextColor = GUI_COLOR_WHITE; 97 | float fLifeTime = 0.0f; 98 | 99 | string sRace = Get2DAString("racialtypes", "Label", nRace); 100 | string sGender = nGender ? "Female" : "Male"; 101 | string sPortraitString = sRace + ", " + sGender + ": " + IntToString(nPortraitNumber); 102 | string sPortraitTexture = Portrait_GetPortraitTexture(nPortraitNumber, nRace, nGender) + "h"; 103 | 104 | if (sPortraitTexture == "po_hu_m_99_h" || sPortraitTexture == "po_hu_f_99_h") 105 | nPortraitTextColor = GUI_COLOR_RED; 106 | 107 | // Portrait Name 108 | PostString(oPlayer, sPortraitString, GUI_CenterStringInWindow(sPortraitString, 14, 32), 30, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nPortraitTextColor, nPortraitTextColor, nID++, sTextFont); 109 | 110 | // Options 111 | int nOptionsX = 4, nOptionsY = 8; 112 | PostString(oPlayer, "Options", 4, 6, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nTextColor, nTextColor, nID++, sTextFont); 113 | 114 | GUI_Draw(oPlayer, GUI_FONT_GUI_GLYPH_ARROW, 2, nOptionsY, SCREEN_ANCHOR_TOP_LEFT, nID++, fLifeTime); 115 | PostString(oPlayer, "1.Select", nOptionsX, nOptionsY++, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nTextColor, nTextColor, nID++, sTextFont); 116 | 117 | GUI_Draw(oPlayer, GUI_FONT_GUI_GLYPH_ARROW, 2, nOptionsY, SCREEN_ANCHOR_TOP_LEFT, nID++, fLifeTime); 118 | PostString(oPlayer, "2.Next", nOptionsX, nOptionsY++, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nTextColor, nTextColor, nID++, sTextFont); 119 | 120 | GUI_Draw(oPlayer, GUI_FONT_GUI_GLYPH_ARROW, 2, nOptionsY, SCREEN_ANCHOR_TOP_LEFT, nID++, fLifeTime); 121 | PostString(oPlayer, "3.Previous", nOptionsX, nOptionsY++, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nTextColor, nTextColor, nID++, sTextFont); 122 | 123 | GUI_Draw(oPlayer, GUI_FONT_GUI_GLYPH_ARROW, 2, nOptionsY, SCREEN_ANCHOR_TOP_LEFT, nID++, fLifeTime); 124 | PostString(oPlayer, "4." + sRace, nOptionsX, nOptionsY++, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nTextColor, nTextColor, nID++, sTextFont); 125 | 126 | GUI_Draw(oPlayer, GUI_FONT_GUI_GLYPH_ARROW, 2, nOptionsY, SCREEN_ANCHOR_TOP_LEFT, nID++, fLifeTime); 127 | PostString(oPlayer, "5." + sGender, nOptionsX, nOptionsY++, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nTextColor, nTextColor, nID++, sTextFont); 128 | 129 | GUI_Draw(oPlayer, GUI_FONT_GUI_GLYPH_ARROW, 2, nOptionsY, SCREEN_ANCHOR_TOP_LEFT, nID++, fLifeTime); 130 | PostString(oPlayer, "6.End", nOptionsX, nOptionsY, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nTextColor, nTextColor, nID++, sTextFont); 131 | 132 | SetTextureOverride(PORTRAIT_FONT_TEXTURE_NAME, sPortraitTexture, oPlayer); 133 | } 134 | 135 | void Portrait_ChatCommand(object oPlayer, string sParams, int nVolume) 136 | { 137 | if (SimpleDialog_IsInConversation(oPlayer, PORTRAIT_SCRIPT_NAME)) 138 | SimpleDialog_AbortConversation(oPlayer); 139 | else 140 | { 141 | if (IsInConversation(oPlayer)) 142 | SimpleDialog_AbortConversation(oPlayer); 143 | 144 | int nParams = StringToInt(sParams); 145 | int nPortraitNumber = (nParams != 0 ? nParams : 1); 146 | int nRace = GetRacialType(oPlayer); 147 | int nGender = GetGender(oPlayer); 148 | 149 | SetLocalInt(oPlayer, PORTRAIT_SCRIPT_NAME + "_PortraitNumber", nPortraitNumber); 150 | SetLocalInt(oPlayer, PORTRAIT_SCRIPT_NAME + "_Race", nRace); 151 | SetLocalInt(oPlayer, PORTRAIT_SCRIPT_NAME + "_Gender", nGender); 152 | 153 | NWNX_Player_PlaySound(oPlayer, "gui_select"); 154 | 155 | Events_AddObjectToDispatchList(PORTRAIT_SCRIPT_NAME, SIMPLE_DIALOG_EVENT_ACTION_TAKEN, oPlayer); 156 | Events_AddObjectToDispatchList(PORTRAIT_SCRIPT_NAME, SIMPLE_DIALOG_EVENT_CONVERSATION_END, oPlayer); 157 | 158 | SimpleDialog_StartConversation(oPlayer, oPlayer, PORTRAIT_SCRIPT_NAME, 1, TRUE); 159 | 160 | Portrait_DrawMainPortraitGUI(oPlayer); 161 | Portrait_UpdatePortraitGUI(oPlayer, nPortraitNumber, nRace, nGender); 162 | } 163 | 164 | SetPCChatMessage(""); 165 | } 166 | 167 | // @EventHandler 168 | void Portrait_EventHandler(string sSubsystemScript, string sEvent) 169 | { 170 | if (sEvent == SIMPLE_DIALOG_EVENT_ACTION_TAKEN) 171 | { 172 | object oPlayer = OBJECT_SELF; 173 | int nOption = Events_GetEventData_NWNX_Int("OPTION"); 174 | 175 | int nPortraitNumber = GetLocalInt(oPlayer, PORTRAIT_SCRIPT_NAME + "_PortraitNumber"); 176 | int nRace = GetLocalInt(oPlayer, PORTRAIT_SCRIPT_NAME + "_Race"); 177 | int nGender = GetLocalInt(oPlayer, PORTRAIT_SCRIPT_NAME + "_Gender"); 178 | 179 | NWNX_Player_PlaySound(oPlayer, "gui_select"); 180 | 181 | switch (nOption) 182 | { 183 | case 1: // Select 184 | { 185 | string sPortrait = Portrait_GetPortraitTexture(nPortraitNumber, nRace, nGender); 186 | SetPortraitResRef(oPlayer, sPortrait); 187 | break; 188 | } 189 | 190 | case 2: // Next 191 | { 192 | SetLocalInt(oPlayer, PORTRAIT_SCRIPT_NAME + "_PortraitNumber", ++nPortraitNumber); 193 | break; 194 | } 195 | 196 | case 3: // Previous 197 | { 198 | if (nPortraitNumber > 1) 199 | SetLocalInt(oPlayer, PORTRAIT_SCRIPT_NAME + "_PortraitNumber", --nPortraitNumber); 200 | break; 201 | } 202 | 203 | case 4: // Race 204 | { 205 | if (++nRace > 6) 206 | nRace = 0; 207 | 208 | SetLocalInt(oPlayer, PORTRAIT_SCRIPT_NAME + "_Race", nRace); 209 | break; 210 | } 211 | 212 | case 5: // Gender 213 | { 214 | nGender = !nGender; 215 | SetLocalInt(oPlayer, PORTRAIT_SCRIPT_NAME + "_Gender", nGender); 216 | break; 217 | } 218 | 219 | case 6: // End 220 | { 221 | SimpleDialog_EndConversation(oPlayer); 222 | return; 223 | } 224 | } 225 | 226 | Portrait_UpdatePortraitGUI(oPlayer, nPortraitNumber, nRace, nGender); 227 | } 228 | else 229 | if (sEvent == SIMPLE_DIALOG_EVENT_CONVERSATION_END) 230 | { 231 | object oPlayer = OBJECT_SELF; 232 | 233 | DeleteLocalInt(oPlayer, PORTRAIT_SCRIPT_NAME + "_PortraitNumber"); 234 | DeleteLocalInt(oPlayer, PORTRAIT_SCRIPT_NAME + "_Race"); 235 | DeleteLocalInt(oPlayer, PORTRAIT_SCRIPT_NAME + "_Gender"); 236 | 237 | Events_RemoveObjectFromDispatchList(sSubsystemScript, SIMPLE_DIALOG_EVENT_ACTION_TAKEN, oPlayer); 238 | Events_RemoveObjectFromDispatchList(sSubsystemScript, SIMPLE_DIALOG_EVENT_CONVERSATION_END, oPlayer); 239 | 240 | SetTextureOverride(PORTRAIT_FONT_TEXTURE_NAME, "", oPlayer); 241 | 242 | DelayCommand(0.1f, GUI_ClearBySubsystem(oPlayer, PORTRAIT_SCRIPT_NAME)); 243 | } 244 | } 245 | 246 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_quickbar.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_quickbar.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[Creature] 7 | 8 | Description: A subsystem that allows players to save and load quickbar configurations 9 | */ 10 | 11 | //void main() {} 12 | 13 | #include "es_inc_core" 14 | #include "es_cc_profiler" 15 | #include "es_srv_chatcom" 16 | #include "nwnx_creature" 17 | 18 | const string QUICKBAR_LOG_TAG = "Quickbar"; 19 | const string QUICKBAR_SCRIPT_NAME = "es_s_quickbar"; 20 | 21 | const string QUICKBAR_CHATCOMMAND_NAME = "qb"; 22 | const string QUICKBAR_CHATCOMMAND_DESCRIPTION = "Save or Load Quickbar Configurations."; 23 | 24 | // @Load 25 | void Quickbar_Load(string sSubsystemScript) 26 | { 27 | string sQuery = "CREATE TABLE IF NOT EXISTS quickbar_data (" + 28 | "uuid TEXT NOT NULL, " + 29 | "name TEXT NOT NULL, " + 30 | "quickbar TEXT NOT NULL, " + 31 | "PRIMARY KEY(uuid, name));"; 32 | sqlquery sql = SqlPrepareQueryCampaign(sSubsystemScript, sQuery); 33 | SqlStep(sql); 34 | 35 | ChatCommand_Register(sSubsystemScript, "Quickbar_ChatCommand", CHATCOMMAND_GLOBAL_PREFIX + QUICKBAR_CHATCOMMAND_NAME, "", QUICKBAR_CHATCOMMAND_DESCRIPTION); 36 | } 37 | 38 | string Quickbar_GetQuickbar(object oPlayer, string sName) 39 | { 40 | string sSerializedQuickbar; 41 | string sQuery = "SELECT quickbar FROM quickbar_data WHERE uuid=@uuid AND name=@name;"; 42 | sqlquery sql = SqlPrepareQueryCampaign(QUICKBAR_SCRIPT_NAME, sQuery); 43 | 44 | SqlBindString(sql, "@uuid", GetObjectUUID(oPlayer)); 45 | SqlBindString(sql, "@name", sName); 46 | 47 | return SqlStep(sql) ? SqlGetString(sql, 0) : ""; 48 | } 49 | 50 | void Quickbar_SaveQuickbar(object oPlayer, string sName, string sSerializedQuickbar) 51 | { 52 | string sQuery = "REPLACE INTO quickbar_data (uuid, name, quickbar) VALUES(@uuid, @name, @quickbar);"; 53 | sqlquery sql = SqlPrepareQueryCampaign(QUICKBAR_SCRIPT_NAME, sQuery); 54 | 55 | SqlBindString(sql, "@uuid", GetObjectUUID(oPlayer)); 56 | SqlBindString(sql, "@name", sName); 57 | SqlBindString(sql, "@quickbar", sSerializedQuickbar); 58 | SqlStep(sql); 59 | } 60 | 61 | void Quickbar_DeleteQuickbar(object oPlayer, string sName) 62 | { 63 | string sQuery = "DELETE FROM quickbar_data WHERE uuid=@uuid AND name=@name;"; 64 | sqlquery sql = SqlPrepareQueryCampaign(QUICKBAR_SCRIPT_NAME, sQuery); 65 | 66 | SqlBindString(sql, "@uuid", GetObjectUUID(oPlayer)); 67 | SqlBindString(sql, "@name", sName); 68 | SqlStep(sql); 69 | } 70 | 71 | string Quickbar_ListQuickbars(object oPlayer) 72 | { 73 | string sQuickbarList, sQuery = "SELECT name FROM quickbar_data WHERE uuid=@uuid;"; 74 | sqlquery sql = SqlPrepareQueryCampaign(QUICKBAR_SCRIPT_NAME, sQuery); 75 | 76 | SqlBindString(sql, "@uuid", GetObjectUUID(oPlayer)); 77 | 78 | while (SqlStep(sql)) 79 | { 80 | sQuickbarList += SqlGetString(sql, 0) + ", "; 81 | } 82 | 83 | return GetSubString(sQuickbarList, 0, GetStringLength(sQuickbarList) - 2); 84 | } 85 | 86 | void Quickbar_ChatCommand(object oPlayer, string sOption, int nVolume) 87 | { 88 | string sParams; 89 | 90 | if ((sParams = ChatCommand_Parse(sOption, "list")) != CHATCOMMAND_PARSE_ERROR) 91 | { 92 | string sQuickbarList = Quickbar_ListQuickbars(oPlayer); 93 | 94 | if (sQuickbarList != "") 95 | ChatCommand_SendInfoMessage(oPlayer, QUICKBAR_LOG_TAG, "Available quickbars: " + sQuickbarList); 96 | else 97 | ChatCommand_SendInfoMessage(oPlayer, QUICKBAR_LOG_TAG, "No saved quickbars found."); 98 | } 99 | else 100 | if ((sParams = ChatCommand_Parse(sOption, "load")) != CHATCOMMAND_PARSE_ERROR) 101 | { 102 | sParams = trim(sParams); 103 | 104 | if (sParams != "") 105 | { 106 | int bSuccess = FALSE; 107 | string sSerializedQuickbar = Quickbar_GetQuickbar(oPlayer, sParams); 108 | 109 | if (sSerializedQuickbar != "") 110 | bSuccess = NWNX_Creature_DeserializeQuickbar(oPlayer, sSerializedQuickbar); 111 | 112 | if (bSuccess) 113 | ChatCommand_SendInfoMessage(oPlayer, QUICKBAR_LOG_TAG, "Loaded: " + sParams); 114 | else 115 | ChatCommand_SendInfoMessage(oPlayer, QUICKBAR_LOG_TAG, "Failed to load: " + sParams); 116 | } 117 | else 118 | ChatCommand_SendInfoMessage(oPlayer, QUICKBAR_LOG_TAG, "Invalid name."); 119 | } 120 | else 121 | if ((sParams = ChatCommand_Parse(sOption, "save")) != CHATCOMMAND_PARSE_ERROR) 122 | { 123 | sParams = trim(sParams); 124 | 125 | if (sParams != "") 126 | { 127 | int bSuccess = FALSE; 128 | string sSerializedQuickbar = NWNX_Creature_SerializeQuickbar(oPlayer); 129 | 130 | if (sSerializedQuickbar != "") 131 | { 132 | Quickbar_SaveQuickbar(oPlayer, sParams, sSerializedQuickbar); 133 | bSuccess = TRUE; 134 | } 135 | 136 | if (bSuccess) 137 | ChatCommand_SendInfoMessage(oPlayer, QUICKBAR_LOG_TAG, "Saved: " + sParams); 138 | else 139 | ChatCommand_SendInfoMessage(oPlayer, QUICKBAR_LOG_TAG, "Failed to save: " + sParams); 140 | } 141 | else 142 | ChatCommand_SendInfoMessage(oPlayer, QUICKBAR_LOG_TAG, "Invalid name."); 143 | } 144 | else 145 | if ((sParams = ChatCommand_Parse(sOption, "delete")) != CHATCOMMAND_PARSE_ERROR) 146 | { 147 | sParams = trim(sParams); 148 | 149 | if (sParams != "") 150 | { 151 | if (Quickbar_GetQuickbar(oPlayer, sParams) != "") 152 | { 153 | Quickbar_DeleteQuickbar(oPlayer, sParams); 154 | 155 | ChatCommand_SendInfoMessage(oPlayer, QUICKBAR_LOG_TAG, "Deleted: " + sParams); 156 | } 157 | else 158 | ChatCommand_SendInfoMessage(oPlayer, QUICKBAR_LOG_TAG, "Quickbar '" + sParams + "' does not exist."); 159 | } 160 | else 161 | ChatCommand_SendInfoMessage(oPlayer, QUICKBAR_LOG_TAG, "Invalid name."); 162 | } 163 | else 164 | { 165 | string sHelp = "Available " + ES_Util_ColorString(QUICKBAR_LOG_TAG, "070") + " Commands:\n"; 166 | sHelp += "\n" + ES_Util_ColorString("list", "070") + " - List your saved Quickbars"; 167 | sHelp += "\n" + ES_Util_ColorString("load [name]", "070") + " - Load a Quickbar"; 168 | sHelp += "\n" + ES_Util_ColorString("save [name]", "070") + " - Save your current Quickbar"; 169 | sHelp += "\n" + ES_Util_ColorString("delete [name]", "070") + " - Delete a Quickbar"; 170 | 171 | SendMessageToPC(oPlayer, sHelp); 172 | } 173 | 174 | SetPCChatMessage(""); 175 | } 176 | 177 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_spellbook.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_spellbook.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[Regex Creature] 7 | 8 | Description: A Spellbook Subsystem 9 | 10 | Note: This is a very rough proof of concept which only works for Sorcerers. 11 | */ 12 | 13 | //void main() {} 14 | 15 | #include "es_inc_core" 16 | #include "es_cc_events" 17 | #include "es_srv_gui" 18 | #include "es_srv_chatcom" 19 | 20 | #include "nwnx_regex" 21 | #include "nwnx_creature" 22 | 23 | const string SPELLBOOK_LOG_TAG = "Spellbook"; 24 | const string SPELLBOOK_SCRIPT_NAME = "es_s_spellbook"; 25 | const string SPELLBOOK_CHATCOMMAND_NAME = "spellbook"; 26 | const string SPELLBOOK_CHATCOMMAND_DESCRIPTION = "Look at all the cool spells you know!"; 27 | 28 | const int SPELLBOOK_GUI_NUM_IDS = 50; 29 | 30 | const string SPELLBOOK_BOOK_TEXTURE_NAME = "fnt_book"; 31 | const string SPELLBOOK_ICON_TEXTURE_NAME = "fnt_es_icon32"; 32 | const string SPELLBOOK_GLYPH_NAME = "a"; 33 | 34 | const string SPELLBOOK_SPELL_DESCRIPTION = "SpellDescription_"; 35 | const string SPELLBOOK_SPELL_DATA_ARRAY = "SpellData_"; 36 | 37 | // @Load 38 | void Spellbook_Load(string sSubsystemScript) 39 | { 40 | Events_SubscribeEvent_NWNX(sSubsystemScript, "NWNX_ON_INPUT_KEYBOARD_BEFORE", TRUE); 41 | 42 | ChatCommand_Register(sSubsystemScript, "Spellbook_ChatCommand", CHATCOMMAND_GLOBAL_PREFIX + SPELLBOOK_CHATCOMMAND_NAME, "", SPELLBOOK_CHATCOMMAND_DESCRIPTION); 43 | 44 | GUI_ReserveIDs(sSubsystemScript, SPELLBOOK_GUI_NUM_IDS); 45 | } 46 | 47 | void Spellbook_ExtractSpellData(int nSpellID) 48 | { 49 | object oDataObject = ES_Util_GetDataObject(SPELLBOOK_SCRIPT_NAME); 50 | 51 | if (GetLocalString(oDataObject, SPELLBOOK_SPELL_DESCRIPTION + IntToString(nSpellID)) != "") 52 | return; 53 | 54 | string sArrayName = SPELLBOOK_SPELL_DATA_ARRAY + IntToString(nSpellID); 55 | 56 | string sSpellData = NWNX_Regex_Replace(GetStringByStrRef(StringToInt(Get2DAString("spells", "SpellDesc", nSpellID))), "\n", "*", FALSE); 57 | 58 | int nDescriptionStart = FindSubString(sSpellData, "**", 0); 59 | string sDescription = GetSubString(sSpellData, nDescriptionStart + 2, GetStringLength(sSpellData) - nDescriptionStart - 2); 60 | 61 | SetLocalString(oDataObject, SPELLBOOK_SPELL_DESCRIPTION + IntToString(nSpellID), sDescription); 62 | 63 | sSpellData = GetSubString(sSpellData, 0, GetStringLength(sSpellData) - GetStringLength(sDescription) - 1); 64 | 65 | int nDataStart = 0, nDataEnd = FindSubString(sSpellData, "*", nDataStart); 66 | 67 | while (nDataEnd != -1) 68 | { 69 | string sData = GetSubString(sSpellData, nDataStart, nDataEnd - nDataStart); 70 | 71 | StringArray_Insert(oDataObject, sArrayName, sData); 72 | 73 | nDataStart = nDataEnd + 1; 74 | nDataEnd = FindSubString(sSpellData, "*", nDataStart); 75 | } 76 | } 77 | 78 | void Spellbook_DrawSpellbookGUI(object oPlayer, int nSpellID) 79 | { 80 | object oDataObject = ES_Util_GetDataObject(SPELLBOOK_SCRIPT_NAME); 81 | int nID = GUI_GetStartID(SPELLBOOK_SCRIPT_NAME); 82 | int nTextColor = GUI_COLOR_WHITE; 83 | string sTextFont = "fnt_dialog_big16"; 84 | int nMaxLength = 47; 85 | float fLifeTime = 0.0f; 86 | 87 | string sSpellName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", nSpellID))); 88 | string sSpellIconResRef = GetStringLowerCase(Get2DAString("spells", "IconResRef", nSpellID)); 89 | 90 | // *** KNOWN SPELLS PAGE 91 | int nCurrentSpellLevel = GetLocalInt(oPlayer, SPELLBOOK_SCRIPT_NAME + "CurrentSpellLevel"); 92 | int nNumSpells = StringArray_Size(oPlayer, SPELLBOOK_SCRIPT_NAME + "Spells_" + IntToString(nCurrentSpellLevel)); 93 | 94 | PostString(oPlayer, "Spell Level: " + IntToString(nCurrentSpellLevel), 10, 5, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nTextColor, nTextColor, nID++, sTextFont); 95 | 96 | int nSpellsX = 10, nSpellsY = 7; 97 | 98 | int nSpellIndex; 99 | for (nSpellIndex = 0; nSpellIndex < nNumSpells; nSpellIndex++) 100 | { 101 | string sName = GetStringByStrRef(StringToInt(Get2DAString("spells", "Name", StringToInt(StringArray_At(oPlayer, SPELLBOOK_SCRIPT_NAME + "Spells_" + IntToString(nCurrentSpellLevel), nSpellIndex))))); 102 | 103 | if (nSpellIndex == GetLocalInt(oPlayer, SPELLBOOK_SCRIPT_NAME + "CurrentSpellIndex")) 104 | PostString(oPlayer, "*", nSpellsX - 1, nSpellsY, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nTextColor, nTextColor, nID++, sTextFont); 105 | 106 | PostString(oPlayer, sName, nSpellsX, nSpellsY++, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nTextColor, nTextColor, nID++, sTextFont); 107 | } 108 | 109 | // *** SPELL INFO PAGE 110 | // Spell Icon Texture 111 | PostString(oPlayer, SPELLBOOK_GLYPH_NAME, 42, 3, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, GUI_COLOR_WHITE, GUI_COLOR_WHITE, nID++, SPELLBOOK_ICON_TEXTURE_NAME); 112 | 113 | // Spell Name 114 | PostString(oPlayer, sSpellName, 47, 4, SCREEN_ANCHOR_TOP_LEFT, fLifeTime, nTextColor, nTextColor, nID++, sTextFont); 115 | 116 | // Spell Description 117 | int nDX = 42, nDY = 6; 118 | string sDescription = GetLocalString(oDataObject, SPELLBOOK_SPELL_DESCRIPTION + IntToString(nSpellID)); 119 | int nLines = GUI_DrawSplitText(oPlayer, sDescription, nMaxLength, nDX, nDY, nID++, nTextColor, fLifeTime, sTextFont); 120 | nID += nLines; 121 | 122 | // Spell Data 123 | string sArrayName = SPELLBOOK_SPELL_DATA_ARRAY + IntToString(nSpellID); 124 | int nSpellDataSize = StringArray_Size(oDataObject, sArrayName); 125 | int nSpellDataIndex; 126 | 127 | nDY += nLines + 1; 128 | for (nSpellDataIndex = 0; nSpellDataIndex < nSpellDataSize; nSpellDataIndex++) 129 | { 130 | string sSpellData = StringArray_At(oDataObject, sArrayName, nSpellDataIndex); 131 | 132 | nLines = GUI_DrawSplitText(oPlayer, sSpellData, nMaxLength, nDX, nDY, nID++, nTextColor, fLifeTime, sTextFont); 133 | nID += nLines; 134 | nDY += nLines; 135 | } 136 | 137 | // Update Spell Icon 138 | SetTextureOverride(SPELLBOOK_ICON_TEXTURE_NAME, sSpellIconResRef, oPlayer); 139 | } 140 | 141 | void SpellBook_ExtractKnownSpells(object oPlayer, int nLevel) 142 | { 143 | if (StringArray_Size(oPlayer, SPELLBOOK_SCRIPT_NAME + "Spells_" + IntToString(nLevel))) return; 144 | 145 | int nNumSpells = NWNX_Creature_GetKnownSpellCount(oPlayer, CLASS_TYPE_SORCERER, nLevel); 146 | 147 | int nSpellIndex; 148 | for (nSpellIndex = 0; nSpellIndex < nNumSpells; nSpellIndex++) 149 | { 150 | StringArray_Insert(oPlayer, SPELLBOOK_SCRIPT_NAME + "Spells_" + IntToString(nLevel), IntToString(NWNX_Creature_GetKnownSpell(oPlayer, CLASS_TYPE_SORCERER, nLevel, nSpellIndex))); 151 | } 152 | } 153 | 154 | void Spellbook_ChatCommand(object oPlayer, string sParams, int nVolume) 155 | { 156 | GUI_ClearBySubsystem(oPlayer, SPELLBOOK_SCRIPT_NAME); 157 | 158 | if (GUI_GetIsPlayerInputLocked(oPlayer)) 159 | { 160 | GUI_UnlockPlayerInput(oPlayer); 161 | 162 | Events_RemoveObjectFromDispatchList(SPELLBOOK_SCRIPT_NAME, "NWNX_ON_INPUT_KEYBOARD_BEFORE", oPlayer); 163 | 164 | DeleteLocalInt(oPlayer, SPELLBOOK_SCRIPT_NAME + "CurrentSpellIndex"); 165 | DeleteLocalInt(oPlayer, SPELLBOOK_SCRIPT_NAME + "CurrentSpellLevel"); 166 | } 167 | else 168 | { 169 | GUI_LockPlayerInput(oPlayer); 170 | 171 | Events_AddObjectToDispatchList(SPELLBOOK_SCRIPT_NAME, "NWNX_ON_INPUT_KEYBOARD_BEFORE", oPlayer); 172 | 173 | int nCurrentSpellLevel = GetLocalInt(oPlayer, SPELLBOOK_SCRIPT_NAME + "CurrentSpellLevel"); 174 | 175 | SpellBook_ExtractKnownSpells(oPlayer, nCurrentSpellLevel); 176 | 177 | int nCurrentSpell = StringToInt(StringArray_At(oPlayer, SPELLBOOK_SCRIPT_NAME + "Spells_" + IntToString(nCurrentSpellLevel), GetLocalInt(oPlayer, "CurrentSpellIndex"))); 178 | 179 | int nID = GUI_GetEndID(SPELLBOOK_SCRIPT_NAME); 180 | // Draw Book 181 | PostString(oPlayer, SPELLBOOK_GLYPH_NAME, 1, 1, SCREEN_ANCHOR_TOP_LEFT, 0.0f, GUI_COLOR_WHITE, GUI_COLOR_WHITE, nID--, SPELLBOOK_BOOK_TEXTURE_NAME); 182 | // Draw Spell Icon 183 | PostString(oPlayer, SPELLBOOK_GLYPH_NAME, 42, 3, SCREEN_ANCHOR_TOP_LEFT, 0.0f, GUI_COLOR_WHITE, GUI_COLOR_WHITE, nID--, SPELLBOOK_ICON_TEXTURE_NAME); 184 | // Header 185 | string sHeader = GetName(oPlayer) + "'s Spellbook"; 186 | PostString(oPlayer, sHeader, 10, 3, SCREEN_ANCHOR_TOP_LEFT, 0.0f, GUI_COLOR_WHITE, GUI_COLOR_WHITE, nID, "fnt_dialog_big16"); 187 | 188 | Spellbook_ExtractSpellData(nCurrentSpell); 189 | Spellbook_DrawSpellbookGUI(oPlayer, nCurrentSpell); 190 | } 191 | 192 | SetPCChatMessage(""); 193 | } 194 | 195 | // @EventHandler 196 | void Spellbook_EventHandler(string sSubsystemScript, string sEvent) 197 | { 198 | if (sEvent == "NWNX_ON_INPUT_KEYBOARD_BEFORE") 199 | { 200 | object oPlayer = OBJECT_SELF; 201 | 202 | if (!GUI_GetIsPlayerInputLocked(oPlayer)) 203 | return; 204 | 205 | string sKey = Events_GetEventData_NWNX_String("KEY"); 206 | 207 | int bRedraw = FALSE; 208 | int nCurrentSpellLevel = GetLocalInt(oPlayer, SPELLBOOK_SCRIPT_NAME + "CurrentSpellLevel"); 209 | int nCurrentSpellIndex = GetLocalInt(oPlayer, SPELLBOOK_SCRIPT_NAME + "CurrentSpellIndex"); 210 | 211 | if (sKey == "W") 212 | { 213 | if (nCurrentSpellIndex > 0) 214 | { 215 | nCurrentSpellIndex--; 216 | bRedraw = TRUE; 217 | } 218 | } 219 | else 220 | if (sKey == "S") 221 | { 222 | if (nCurrentSpellIndex < StringArray_Size(oPlayer, SPELLBOOK_SCRIPT_NAME + "Spells_"+ IntToString(nCurrentSpellLevel)) - 1) 223 | { 224 | nCurrentSpellIndex++; 225 | bRedraw = TRUE; 226 | } 227 | } 228 | else 229 | if (sKey == "E") 230 | { 231 | if (nCurrentSpellLevel < 9) 232 | { 233 | nCurrentSpellLevel++; 234 | nCurrentSpellIndex = 0; 235 | bRedraw = TRUE; 236 | } 237 | } 238 | else 239 | if (sKey == "Q") 240 | { 241 | if (nCurrentSpellLevel > 0) 242 | { 243 | nCurrentSpellLevel--; 244 | nCurrentSpellIndex = 0; 245 | bRedraw = TRUE; 246 | } 247 | } 248 | 249 | SetLocalInt(oPlayer, SPELLBOOK_SCRIPT_NAME + "CurrentSpellLevel", nCurrentSpellLevel); 250 | SetLocalInt(oPlayer, SPELLBOOK_SCRIPT_NAME + "CurrentSpellIndex", nCurrentSpellIndex); 251 | 252 | if (bRedraw) 253 | { 254 | SpellBook_ExtractKnownSpells(oPlayer, nCurrentSpellLevel); 255 | 256 | int nCurrentSpell = StringToInt(StringArray_At(oPlayer, SPELLBOOK_SCRIPT_NAME + "Spells_" + IntToString(nCurrentSpellLevel), nCurrentSpellIndex)); 257 | 258 | int nStartID = GUI_GetStartID(SPELLBOOK_SCRIPT_NAME); 259 | GUI_ClearByRange(oPlayer, nStartID, nStartID + GUI_GetIDAmount(SPELLBOOK_SCRIPT_NAME) - 3); 260 | Spellbook_ExtractSpellData(nCurrentSpell); 261 | Spellbook_DrawSpellbookGUI(oPlayer, nCurrentSpell); 262 | } 263 | } 264 | } 265 | 266 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_spiders.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_spiders.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: Help, spiders. 9 | */ 10 | 11 | //void main() {} 12 | 13 | #include "es_inc_core" 14 | #include "es_cc_events" 15 | #include "es_srv_toolbox" 16 | #include "x0_i0_position" 17 | 18 | const string SPIDERS_LOG_TAG = "SpiderExplosion"; 19 | const string SPIDERS_SCRIPT_NAME = "es_s_spiders"; 20 | 21 | const string SPIDERS_COCOON_WAYPOINT_TAG = "SPIDERS_COCOON_SPAWN"; 22 | 23 | void Spiders_PreloadSpider(string sSubsystemScript); 24 | void Spiders_SpawnCocoons(string sSubsystemScript); 25 | 26 | // @Load 27 | void Spiders_Load(string sSubsystemScript) 28 | { 29 | Events_SubscribeEvent_Object(sSubsystemScript, EVENT_SCRIPT_TRIGGER_ON_OBJECT_ENTER, EVENTS_EVENT_FLAG_DEFAULT, TRUE); 30 | 31 | Spiders_PreloadSpider(sSubsystemScript); 32 | Spiders_SpawnCocoons(sSubsystemScript); 33 | } 34 | 35 | void Spider_DestroySelf(object oSpider) 36 | { 37 | DestroyObject(oSpider); 38 | } 39 | 40 | location GetRandomLocationAroundPoint(location locPoint, float fDistance) 41 | { 42 | float fAngle = IntToFloat(Random(360)); 43 | float fOrient = IntToFloat(Random(360)); 44 | 45 | return GenerateNewLocationFromLocation(locPoint, fDistance, fAngle, fOrient); 46 | } 47 | 48 | // @EventHandler 49 | void Spiders_EventHandler(string sSubsystemScript, string sEvent) 50 | { 51 | switch (StringToInt(sEvent)) 52 | { 53 | case EVENT_SCRIPT_TRIGGER_ON_OBJECT_ENTER: 54 | { 55 | object oTrigger = OBJECT_SELF; 56 | object oPlayer = GetEnteringObject(); 57 | 58 | // We don't want infinite spiders... 59 | if (!GetIsPC(oPlayer)) return; 60 | 61 | object oDataObject = ES_Util_GetDataObject(sSubsystemScript); 62 | object oCocoon = GetLocalObject(oTrigger, "SPIDERS_COCOON"); 63 | object oCocoonArea = GetArea(oCocoon); 64 | location locCocoon = GetLocation(oTrigger); 65 | 66 | string sSpider = GetLocalString(oDataObject, "SPIDER_TEMPLATE"); 67 | 68 | SendMessageToPC(oPlayer, "Oh no, spiderlings!"); 69 | 70 | ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_FNF_GAS_EXPLOSION_ACID), oCocoon); 71 | 72 | effect eFear = EffectLinkEffects(EffectVisualEffect(VFX_DUR_MIND_AFFECTING_FEAR), EffectFrightened()); 73 | ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFear, oPlayer, 7.5f); 74 | ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectCutsceneGhost(), oPlayer, 7.5f); 75 | 76 | int nSpider, nNumSpiders = 25; 77 | for(nSpider = 0; nSpider < nNumSpiders; nSpider++) 78 | { 79 | object oSpider = NWNX_Object_Deserialize(sSpider); 80 | 81 | SetObjectVisualTransform(oSpider, OBJECT_VISUAL_TRANSFORM_SCALE, 0.25f + (IntToFloat(Random(25)) / 100.0f)); 82 | 83 | location locSpawn = GetRandomLocationAroundPoint(locCocoon, 5.0f); 84 | NWNX_Object_AddToArea(oSpider, oCocoonArea, GetPositionFromLocation(locSpawn)); 85 | 86 | location locMove = GetRandomLocationAroundPoint(locCocoon, 30.0f); 87 | 88 | AssignCommand(oSpider, ActionWait(0.25f)); 89 | AssignCommand(oSpider, JumpToLocation(locSpawn)); 90 | AssignCommand(oSpider, ActionForceMoveToLocation(locMove, TRUE, 15.0f)); 91 | AssignCommand(oSpider, ActionDoCommand(Spider_DestroySelf(oSpider))); 92 | } 93 | 94 | break; 95 | } 96 | } 97 | } 98 | 99 | void Spiders_SpawnCocoons(string sSubsystemScript) 100 | { 101 | struct Toolbox_CircleTriggerData ctd; 102 | ctd.sTag = "SPIDERS_TRIGGER"; 103 | ctd.fRadius = 2.5f; 104 | ctd.nPoints = 16; 105 | ctd.scriptOnEnter = TRUE; 106 | 107 | struct Toolbox_PlaceableData pd; 108 | pd.nModel = 90; 109 | pd.sTag = "SPIDERS_COCOON"; 110 | pd.sName = "Cocoon"; 111 | pd.sDescription = "A cocoon filled with icky spiders."; 112 | pd.bPlot = TRUE; 113 | 114 | string sSerializedCocoon = Toolbox_GeneratePlaceable(pd); 115 | string sTriggerOnEnter = Events_GetEventName_Object(EVENT_SCRIPT_TRIGGER_ON_OBJECT_ENTER); 116 | 117 | int nNth = 0; 118 | object oSpawnpoint; 119 | while ((oSpawnpoint = GetObjectByTag(SPIDERS_COCOON_WAYPOINT_TAG, nNth++)) != OBJECT_INVALID) 120 | { 121 | location locSpawn = GetLocation(oSpawnpoint); 122 | object oTrigger = Toolbox_CreateCircleTrigger(ctd, locSpawn); 123 | 124 | vector vSpawnpoint = GetPosition(oSpawnpoint); 125 | vSpawnpoint.z -= 0.15; 126 | location locCocoon = Location(GetArea(oSpawnpoint), vSpawnpoint, GetFacing(oSpawnpoint)); 127 | 128 | object oCocoon = Toolbox_CreatePlaceable(sSerializedCocoon, locCocoon); 129 | 130 | SetLocalObject(oTrigger, GetTag(oCocoon), oCocoon); 131 | SetLocalObject(oCocoon, GetTag(oTrigger), oTrigger); 132 | 133 | Events_AddObjectToDispatchList(sSubsystemScript, sTriggerOnEnter, oTrigger); 134 | } 135 | } 136 | 137 | void Spiders_PreloadSpider(string sSubsystemScript) 138 | { 139 | object oSpider = CreateObject(OBJECT_TYPE_CREATURE, "nw_spidgiant", GetStartingLocation(), FALSE, "SPIDERS_SPIDER"); 140 | 141 | Events_ClearCreatureEventScripts(oSpider); 142 | 143 | SetName(oSpider, "Spiderling"); 144 | 145 | ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectCutsceneGhost(), oSpider); 146 | 147 | string sSpider = NWNX_Object_Serialize(oSpider); 148 | SetLocalString(ES_Util_GetDataObject(sSubsystemScript), "SPIDER_TEMPLATE", sSpider); 149 | 150 | DestroyObject(oSpider); 151 | } 152 | 153 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_subsysman.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_subsysman.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[] 7 | 8 | Description: 9 | */ 10 | 11 | //void main() {} 12 | 13 | #include "es_inc_core" 14 | #include "es_cc_events" 15 | 16 | const string SUBSYSTEM_MANAGER_LOG_TAG = "SubsystemManager"; 17 | const string SUBSYSTEM_MANAGER_SCRIPT_NAME = "es_s_subsysman"; 18 | 19 | // @Load 20 | void SubsystemManager_Load(string sSubsystemScript) 21 | { 22 | Events_SubscribeEvent_NWNX(sSubsystemScript, "NWNX_ON_RESOURCE_MODIFIED"); 23 | } 24 | 25 | // @EventHandler 26 | void SubsystemManager_EventHandler(string sSubsystemScript, string sEvent) 27 | { 28 | if (sEvent == "NWNX_ON_RESOURCE_MODIFIED") 29 | { 30 | string sAlias = Events_GetEventData_NWNX_String("ALIAS"); 31 | int nType = Events_GetEventData_NWNX_Int("TYPE"); 32 | 33 | if (sAlias == "NWNX" && nType == NWNX_UTIL_RESREF_TYPE_NSS) 34 | { 35 | string sResRef = Events_GetEventData_NWNX_String("RESREF"); 36 | int nComponentType = ES_Core_Component_GetTypeFromScriptName(sResRef); 37 | 38 | if (nComponentType == ES_CORE_COMPONENT_TYPE_SUBSYSTEM) 39 | { 40 | object oDataObject = ES_Util_GetDataObject(SUBSYSTEM_MANAGER_SCRIPT_NAME); 41 | object oComponent = ES_Core_GetComponentDataObject(sResRef, FALSE); 42 | 43 | if (GetIsObjectValid(oComponent)) 44 | { 45 | string sScriptFlags = GetLocalString(oComponent, "Flags"); 46 | 47 | if (FindSubString(sScriptFlags, "HotSwap") != -1) 48 | { 49 | ES_Util_Log(SUBSYSTEM_MANAGER_LOG_TAG, "Detected changes for '" + sResRef + "', recompiling EventHandler", FALSE); 50 | 51 | ES_Core_Component_ExecuteFunction(sResRef, "Unload", TRUE, TRUE); 52 | 53 | ES_Core_Component_Initialize(sResRef, nComponentType); 54 | ES_Core_Component_CheckEventHandler(sResRef); 55 | 56 | ES_Core_Component_ExecuteFunction(sResRef, "Load", FALSE, TRUE); 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_testing.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_testing.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[Player Administration Object] 7 | 8 | Flags: 9 | @HotSwap 10 | 11 | Description: A test subsystem 12 | */ 13 | 14 | //void main() {} 15 | 16 | #include "es_inc_core" 17 | #include "es_cc_events" 18 | #include "es_cc_profiler" 19 | #include "es_srv_gui" 20 | #include "es_srv_mediator" 21 | #include "nwnx_player" 22 | #include "nwnx_admin" 23 | #include "nwnx_object" 24 | 25 | #include "x0_i0_position" 26 | 27 | const string TESTING_LOG_TAG = "Testing"; 28 | const string TESTING_SCRIPT_NAME = "es_s_testing"; 29 | 30 | // @Load 31 | void Testing_Load(string sSubsystemScript) 32 | { 33 | Events_SubscribeEvent_Object(sSubsystemScript, EVENT_SCRIPT_MODULE_ON_PLAYER_CHAT); 34 | //Events_SubscribeEvent_NWNX(sSubsystemScript, "NWNX_ON_INPUT_WALK_TO_WAYPOINT_BEFORE"); 35 | //Events_SubscribeEvent_NWNX(sSubsystemScript, "NWNX_ON_INPUT_KEYBOARD_BEFORE"); 36 | 37 | object oPlayer = GetFirstPC(); 38 | if (GetIsObjectValid(oPlayer)) 39 | { 40 | GUI_ClearByRange(oPlayer, 1, 100); 41 | } 42 | } 43 | 44 | // @Unload 45 | void Testing_Unload(string sSubsystemScript) 46 | { 47 | Events_UnsubscribeAllEvents(sSubsystemScript, TRUE); 48 | } 49 | 50 | void Testing_ShutdownNotification(object oPlayer, int nCountdown) 51 | { 52 | if (nCountdown) 53 | { 54 | string sMessage = "Server shutting down in '" + IntToString(nCountdown) + "' second" + (nCountdown == 1 ? "" : "s") + "."; 55 | 56 | GUI_DrawNotification(oPlayer, sMessage, 1, 0, 1, nCountdown <= 5 ? GUI_COLOR_RED: GUI_COLOR_WHITE, 1.1f); 57 | 58 | DelayCommand(1.0f, Testing_ShutdownNotification(oPlayer, --nCountdown)); 59 | } 60 | else 61 | { 62 | NWNX_Administration_ShutdownServer(); 63 | } 64 | } 65 | 66 | void DoDamage(object oCreature, int nAmount) 67 | { 68 | effect eDamage = EffectDamage(nAmount); 69 | 70 | ApplyEffectToObject(DURATION_TYPE_INSTANT, eDamage, oCreature); 71 | } 72 | 73 | // @EventHandler 74 | void Testing_EventHandler(string sSubsystemScript, string sEvent) 75 | { 76 | if (StringToInt(sEvent) == EVENT_SCRIPT_MODULE_ON_PLAYER_CHAT) 77 | { 78 | object oPlayer = GetPCChatSpeaker(); 79 | string sMessage = GetPCChatMessage(); 80 | 81 | if (sMessage == "/tl") 82 | { 83 | if (GUI_GetIsPlayerInputLocked(oPlayer)) 84 | { 85 | GUI_ClearByRange(oPlayer, 1, 500); 86 | GUI_UnlockPlayerInput(oPlayer); 87 | } 88 | else 89 | { 90 | GUI_LockPlayerInput(oPlayer); 91 | } 92 | 93 | SetPCChatMessage(""); 94 | } 95 | 96 | if (sMessage == "/shutdown") 97 | { 98 | NWNX_Player_PlaySound(oPlayer, "gui_dm_alert"); 99 | 100 | Testing_ShutdownNotification(oPlayer, 15); 101 | 102 | SetPCChatMessage(""); 103 | } 104 | 105 | if (sMessage == "/dc") 106 | { 107 | object oCreature = GetNearestObjectByTag("NW_KOBOLD001", oPlayer); 108 | 109 | if (!GetIsDead(oCreature)) 110 | { 111 | int nAmount = Random(5) + 1; 112 | 113 | AssignCommand(oPlayer, DoDamage(oCreature, nAmount)); 114 | ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_MAGBLUE), oCreature); 115 | } 116 | SetPCChatMessage(""); 117 | } 118 | 119 | if (sMessage == "/ds") 120 | { 121 | int nAmount = 1; 122 | 123 | AssignCommand(oPlayer, DoDamage(oPlayer, nAmount)); 124 | ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_IMP_MAGBLUE), oPlayer); 125 | 126 | SetPCChatMessage(""); 127 | } 128 | 129 | if (sMessage == "/npc") 130 | { 131 | object oCreature = CreateObject(OBJECT_TYPE_CREATURE, "nw_kobold001", GetStartingLocation()); 132 | 133 | SetName(oCreature, "Angery Kobold"); 134 | SetCommandable(FALSE, oCreature); 135 | 136 | NWNX_Object_SetMaxHitPoints(oCreature, 5 + Random(10)); 137 | 138 | ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectHeal(GetMaxHitPoints(oCreature)), oCreature); 139 | 140 | struct ProfilerData pd = Profiler_Start("Mediator_ExecuteFunction"); 141 | 142 | //Mediator_ExecuteFunction("es_s_hpbar", "HealthBar_EnableHealthBar", Mediator_Object(oCreature)); 143 | 144 | Mediator_ExecuteFunction("es_s_hpbar", "HealthBar_SetInfoBlurb", Mediator_Object(oCreature) + Mediator_String("Very ANGERY at YOU.")); 145 | 146 | //Mediator_ExecuteFunction("es_s_dumplocals", "DumpLocals_DumpLocals", Mediator_Object(oPlayer) + Mediator_Int(0) + Mediator_Object(oCreature)); 147 | 148 | Profiler_Stop(pd); 149 | 150 | SetPCChatMessage(""); 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /Components/Subsystems/es_s_travel.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_s_travel.nss 3 | Created by: Daz 4 | 5 | Required NWNX Plugins: 6 | @NWNX[Player] 7 | 8 | Flags: 9 | @HotSwap 10 | 11 | Description: A subsystem that gives players a movement speed increase when 12 | they're travelling on roads and a movement speed decrease while 13 | in water. 14 | */ 15 | 16 | //void main() {} 17 | 18 | #include "es_inc_core" 19 | #include "es_cc_events" 20 | #include "nwnx_player" 21 | 22 | const string TRAVEL_EFFECT_TAG = "TravelEffectTag"; 23 | const float TRAVEL_EFFECT_DURATION = 300.0f; 24 | const int TRAVEL_SPEED_INCREASE_PERCENTAGE = 75; 25 | const int TRAVEL_SPEED_DECREASE_PERCENTAGE = 50; 26 | const float TRAVEL_IMPACT_DELAY_TIMER = 0.5f; 27 | 28 | void Travel_ApplyEffect(object oPlayer, int nVFX, int nMaterial, effect eEffect); 29 | 30 | // @Load 31 | void Travel_Load(string sSubsystemScript) 32 | { 33 | Events_SubscribeEvent_NWNX(sSubsystemScript, "NWNX_ON_MATERIALCHANGE_AFTER"); 34 | } 35 | 36 | // @Unload 37 | void Travel_Unload(string sSubsystemScript) 38 | { 39 | Events_UnsubscribeAllEvents(sSubsystemScript); 40 | 41 | object oPlayer = GetFirstPC(); 42 | while (GetIsObjectValid(oPlayer)) 43 | { 44 | effect eEffect = GetFirstEffect(oPlayer); 45 | while (GetIsEffectValid(eEffect)) 46 | { 47 | if (GetEffectTag(eEffect) == TRAVEL_EFFECT_TAG) 48 | RemoveEffect(oPlayer, eEffect); 49 | 50 | eEffect = GetNextEffect(oPlayer); 51 | } 52 | 53 | oPlayer = GetNextPC(); 54 | } 55 | } 56 | 57 | // @EventHandler 58 | void Travel_EventHandler(string sSubsystemScript, string sEvent) 59 | { 60 | object oPlayer = OBJECT_SELF; 61 | 62 | if (!GetIsPC(oPlayer) || GetIsDM(oPlayer)) return; 63 | 64 | int nMaterial = Events_GetEventData_NWNX_Int("MATERIAL_TYPE"); 65 | 66 | Effects_RemoveEffectsWithTag(oPlayer, TRAVEL_EFFECT_TAG); 67 | 68 | switch (nMaterial) 69 | { 70 | case 1: // Dirt 71 | { 72 | effect eEffect = EffectLinkEffects( 73 | EffectVisualEffect(VFX_DUR_CESSATE_POSITIVE), 74 | EffectMovementSpeedIncrease(TRAVEL_SPEED_INCREASE_PERCENTAGE)); 75 | 76 | DelayCommand(TRAVEL_IMPACT_DELAY_TIMER, Travel_ApplyEffect(oPlayer, VFX_IMP_HASTE, nMaterial, eEffect)); 77 | break; 78 | } 79 | 80 | case 6: // Water 81 | { 82 | effect eEffect = EffectLinkEffects( 83 | EffectVisualEffect(VFX_DUR_CESSATE_NEGATIVE), 84 | EffectMovementSpeedDecrease(TRAVEL_SPEED_DECREASE_PERCENTAGE)); 85 | 86 | DelayCommand(TRAVEL_IMPACT_DELAY_TIMER, Travel_ApplyEffect(oPlayer, VFX_IMP_SLOW, nMaterial, eEffect)); 87 | break; 88 | } 89 | } 90 | } 91 | 92 | void Travel_ApplyEffect(object oPlayer, int nVFX, int nMaterial, effect eEffect) 93 | { 94 | if (GetSurfaceMaterial(GetLocation(oPlayer)) == nMaterial) 95 | { 96 | NWNX_Player_ApplyInstantVisualEffectToObject(oPlayer, oPlayer, nVFX); 97 | ApplyEffectToObject(DURATION_TYPE_TEMPORARY, TagEffect(SupernaturalEffect(eEffect), TRAVEL_EFFECT_TAG), oPlayer, TRAVEL_EFFECT_DURATION); 98 | } 99 | } 100 | 101 | -------------------------------------------------------------------------------- /Core/es_inc_effects.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_inc_effects.nss 3 | Created by: Daz 4 | 5 | Description: Event System Effects Include 6 | */ 7 | 8 | // Remove effects with sTag from oObject 9 | void Effects_RemoveEffectsWithTag(object oObject, string sTag, int bFirstOnly = FALSE); 10 | // Remove all effects from oObject 11 | void Effects_RemoveAllEffects(object oObject); 12 | // Toggle CutsceneInvisibility and CutsceneGhost on oObject 13 | void Effects_ToggleCutsceneInvisibility(object oObject, int bInvisible); 14 | // Get a visual effect of oCreature's blood color 15 | effect Effects_GetBloodEffect(object oCreature); 16 | // Apply eImpactVisualEffect nNumImpacts times with fDelay 17 | void Effects_ApplyImpactVisualEffects(object oObject, effect eImpactVisualEffect, int nNumImpacts, float fInitialDelay = 0.0f, float fDelay = 0.5f); 18 | // Apply nVisualEffect as a permanent effect to oObject with sTag 19 | void Effects_ApplyPermanentVisualEffectWithTag(object oObject, int nVisualEffect, string sTag); 20 | // Apply sparks to oObject and play sSound 21 | void Effects_PlaySoundAndApplySparks(object oObject, string sSound); 22 | 23 | void Effects_RemoveEffectsWithTag(object oObject, string sTag, int bFirstOnly = FALSE) 24 | { 25 | effect eEffect = GetFirstEffect(oObject); 26 | 27 | while (GetIsEffectValid(eEffect)) 28 | { 29 | if (GetEffectTag(eEffect) == sTag) 30 | { 31 | RemoveEffect(oObject, eEffect); 32 | 33 | if (bFirstOnly) 34 | break; 35 | } 36 | 37 | eEffect = GetNextEffect(oObject); 38 | } 39 | } 40 | 41 | void Effects_RemoveAllEffects(object oObject) 42 | { 43 | effect eEffect = GetFirstEffect(oObject); 44 | 45 | while (GetIsEffectValid(eEffect)) 46 | { 47 | RemoveEffect(oObject, eEffect); 48 | eEffect = GetNextEffect(oObject); 49 | } 50 | } 51 | 52 | void Effects_ToggleCutsceneInvisibility(object oObject, int bInvisible) 53 | { 54 | if (bInvisible) 55 | { 56 | effect eCutsceneInvisibility = TagEffect( 57 | SupernaturalEffect( 58 | EffectLinkEffects(EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY), EffectCutsceneGhost())), 59 | "EFFECTS_CUTSCENE_INVISIBILITY"); 60 | 61 | ApplyEffectToObject(DURATION_TYPE_PERMANENT, eCutsceneInvisibility, oObject); 62 | } 63 | else 64 | { 65 | Effects_RemoveEffectsWithTag(oObject, "EFFECTS_CUTSCENE_INVISIBILITY"); 66 | } 67 | } 68 | 69 | effect Effects_GetBloodEffect(object oCreature) 70 | { 71 | int nBloodColor; 72 | string sBloodColor = Get2DAString("appearance", "BLOODCOLR", GetAppearanceType(oCreature)); 73 | 74 | if (sBloodColor == "R") 75 | nBloodColor = VFX_COM_BLOOD_CRT_RED; 76 | else 77 | if (sBloodColor == "W") 78 | nBloodColor = VFX_COM_BLOOD_CRT_WIMP; 79 | else 80 | if (sBloodColor == "G") 81 | nBloodColor = VFX_COM_BLOOD_CRT_GREEN; 82 | else 83 | if (sBloodColor == "Y") 84 | nBloodColor = VFX_COM_BLOOD_CRT_YELLOW; 85 | else 86 | nBloodColor = VFX_COM_BLOOD_CRT_RED; 87 | 88 | return EffectVisualEffect(nBloodColor); 89 | } 90 | 91 | void Effects_ApplyImpactVisualEffects(object oObject, effect eImpactVisualEffect, int nNumImpacts, float fInitialDelay = 0.0f, float fDelay = 0.5f) 92 | { 93 | int nImpact; 94 | for (nImpact = 0; nImpact < nNumImpacts; nImpact++) 95 | { 96 | DelayCommand(fInitialDelay + (fDelay * nImpact), ApplyEffectToObject(DURATION_TYPE_INSTANT, eImpactVisualEffect, oObject)); 97 | } 98 | } 99 | 100 | void Effects_ApplyPermanentVisualEffectWithTag(object oObject, int nVisualEffect, string sTag) 101 | { 102 | ApplyEffectToObject(DURATION_TYPE_PERMANENT, TagEffect(EffectVisualEffect(nVisualEffect), sTag), oObject); 103 | } 104 | 105 | void Effects_PlaySoundAndApplySparks(object oObject, string sSound) 106 | { 107 | if (sSound != "") 108 | AssignCommand(oObject, PlaySound(sSound)); 109 | ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectVisualEffect(VFX_COM_BLOOD_SPARK_LARGE), oObject); 110 | } 111 | 112 | -------------------------------------------------------------------------------- /Core/es_inc_nss.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_inc_nss.nss 3 | Created by: Daz 4 | 5 | Description: Event System NSS Utility Include 6 | */ 7 | 8 | string nssVoidMain(string sContents); 9 | string nssStartingConditional(string sContents); 10 | string nssInclude(string sIncludeFile); 11 | string nssIfStatement(string sFunction, string sComparison = "", string sValue = ""); 12 | string nssElseIfStatement(string sFunction, string sComparison = "", string sValue = ""); 13 | string nssWhile(string sFunction, string sComparison = "", string sValue = ""); 14 | string nssBrackets(string sContents); 15 | string nssEscapeDoubleQuotes(string sString); 16 | string nssSwitch(string sVariable, string sCases); 17 | string nssCaseStatement(int nCase, string sContents, int bBreak = TRUE); 18 | string nssObject(string sVarName, string sFunction = "", int bIncludeType = TRUE); 19 | string nssString(string sVarName, string sFunction = "", int bIncludeType = TRUE); 20 | string nssInt(string sVarName, string sFunction = "", int bIncludeType = TRUE); 21 | string nssFloat(string sVarName, string sFunction = "", int bIncludeType = TRUE); 22 | string nssVector(string sVarName, string sFunction = "", int bIncludeType = TRUE); 23 | string nssLocation(string sVarName, string sFunction = "", int bIncludeType = TRUE); 24 | string nssFunction(string sFunction, string sArguments = "", int bAddSemicolon = TRUE); 25 | // Converts o to Object, s to String, etc 26 | // Only supports the following types: (o)bject, (s)tring, (i)nt, (f)loat, (l)ocation, (v)ector 27 | string nssConvertShortType(string sShortType); 28 | 29 | string nssVoidMain(string sContents) 30 | { 31 | return "void main() { " + sContents + " }"; 32 | } 33 | 34 | string nssStartingConditional(string sContents) 35 | { 36 | return "int StartingConditional() { return " + sContents + " }"; 37 | } 38 | 39 | string nssInclude(string sIncludeFile) 40 | { 41 | return sIncludeFile == "" ? sIncludeFile : "#" + "include \"" + sIncludeFile + "\" "; 42 | } 43 | 44 | string nssIfStatement(string sFunction, string sComparison, string sValue) 45 | { 46 | return "if (" + sFunction + " " + sComparison + " " + sValue + ") "; 47 | } 48 | 49 | string nssElseIfStatement(string sFunction, string sComparison, string sValue) 50 | { 51 | return "else if (" + sFunction + " " + sComparison + " " + sValue + ") "; 52 | } 53 | 54 | string nssWhile(string sFunction, string sComparison, string sValue) 55 | { 56 | return "while (" + sFunction + " " + sComparison + " " + sValue + ") "; 57 | } 58 | 59 | string nssBrackets(string sContents) 60 | { 61 | return "{ " + sContents + " } "; 62 | } 63 | 64 | string nssEscapeDoubleQuotes(string sString) 65 | { 66 | return "\"" + sString + "\""; 67 | } 68 | 69 | string nssSwitch(string sVariable, string sCases) 70 | { 71 | return "switch (" + sVariable + ") { " + sCases + " }"; 72 | } 73 | 74 | string nssCaseStatement(int nCase, string sContents, int bBreak = TRUE) 75 | { 76 | return "case " + IntToString(nCase) + ": { " + sContents + (bBreak ? " break;" : "") + " } "; 77 | } 78 | 79 | string nssSemicolon(string sString) 80 | { 81 | return (GetStringRight(sString, 1) == ";" || GetStringRight(sString, 2) == "; ") ? sString + " " : sString + "; "; 82 | } 83 | 84 | string nssVariable(string sType, string sVarName, string sFunction) 85 | { 86 | return sType + " " + sVarName + (sFunction == "" ? "; " : " = " + nssSemicolon(sFunction)); 87 | } 88 | 89 | string nssObject(string sVarName, string sFunction = "", int bIncludeType = TRUE) 90 | { 91 | return nssVariable(bIncludeType ? "object" : "", sVarName, sFunction); 92 | } 93 | 94 | string nssString(string sVarName, string sFunction = "", int bIncludeType = TRUE) 95 | { 96 | return nssVariable(bIncludeType ? "string" : "", sVarName, sFunction); 97 | } 98 | 99 | string nssInt(string sVarName, string sFunction = "", int bIncludeType = TRUE) 100 | { 101 | return nssVariable(bIncludeType ? "int" : "", sVarName, sFunction); 102 | } 103 | 104 | string nssFloat(string sVarName, string sFunction = "", int bIncludeType = TRUE) 105 | { 106 | return nssVariable(bIncludeType ? "float" : "", sVarName, sFunction); 107 | } 108 | 109 | string nssVector(string sVarName, string sFunction = "", int bIncludeType = TRUE) 110 | { 111 | return nssVariable(bIncludeType ? "vector" : "", sVarName, sFunction); 112 | } 113 | 114 | string nssLocation(string sVarName, string sFunction = "", int bIncludeType = TRUE) 115 | { 116 | return nssVariable(bIncludeType ? "location" : "", sVarName, sFunction); 117 | } 118 | 119 | string nssFunction(string sFunction, string sArguments, int bAddSemicolon = TRUE) 120 | { 121 | return sFunction + "(" + sArguments + (bAddSemicolon ? ");" : ")") + " "; 122 | } 123 | 124 | string nssConvertShortType(string sShortType) 125 | { 126 | sShortType = GetStringLowerCase(sShortType); 127 | 128 | if (sShortType == "o") return "Object"; 129 | if (sShortType == "s") return "String"; 130 | if (sShortType == "i") return "Int"; 131 | if (sShortType == "f") return "Float"; 132 | if (sShortType == "l") return "Location"; 133 | if (sShortType == "v") return "Vector"; 134 | 135 | return ""; 136 | } 137 | 138 | -------------------------------------------------------------------------------- /Core/es_inc_sqlite.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_inc_sqlite.nss 3 | Created by: Daz 4 | 5 | Description: Event System SQLite Utility Include 6 | */ 7 | 8 | // Returns TRUE if sTableName exists in sDatabase. 9 | int SqlGetTableExistsCampaign(string sDatabase, string sTableName); 10 | // Returns TRUE if sTableName exists on oObject. 11 | int SqlGetTableExistsObject(object oObject, string sTableName); 12 | // Returns the last insert id for sDatabase, -1 on error. 13 | int SqlGetLastInsertIdCampaign(string sDatabase); 14 | // Returns the last insert id for oObject, -1 on error. 15 | int SqlGetLastInsertIdObject(object oObject); 16 | // Returns the number of affected rows by the most recent INSERT, UPDATE or DELETE query for sDatabase, -1 on error. 17 | int SqlGetAffectedRowsCampaign(string sDatabase); 18 | // Returns the number of affected rows by the most recent INSERT, UPDATE or DELETE query for oObject, -1 on error. 19 | int SqlGetAffectedRowsObject(object oObject); 20 | // Prepare a query, if bUseModule is TRUE, the module will be used to hold the database. 21 | sqlquery SqlPrepareQuery(string sDatabase, string sQuery, int bUseModule); 22 | 23 | int SqlGetTableExistsCampaign(string sDatabase, string sTableName) 24 | { 25 | string sQuery = "SELECT name FROM sqlite_master WHERE type='table' AND name=@tableName;"; 26 | sqlquery sql = SqlPrepareQueryCampaign(sDatabase, sQuery); 27 | SqlBindString(sql, "@tableName", sTableName); 28 | 29 | return SqlStep(sql); 30 | } 31 | 32 | int SqlGetTableExistsObject(object oObject, string sTableName) 33 | { 34 | string sQuery = "SELECT name FROM sqlite_master WHERE type='table' AND name=@tableName;"; 35 | sqlquery sql = SqlPrepareQueryObject(oObject, sQuery); 36 | SqlBindString(sql, "@tableName", sTableName); 37 | 38 | return SqlStep(sql); 39 | } 40 | 41 | int SqlGetLastInsertIdCampaign(string sDatabase) 42 | { 43 | sqlquery sql = SqlPrepareQueryCampaign(sDatabase, "SELECT last_insert_rowid();"); 44 | 45 | return SqlStep(sql) ? SqlGetInt(sql, 0) : -1; 46 | } 47 | 48 | int SqlGetLastInsertIdObject(object oObject) 49 | { 50 | sqlquery sql = SqlPrepareQueryObject(oObject, "SELECT last_insert_rowid();"); 51 | 52 | return SqlStep(sql) ? SqlGetInt(sql, 0) : -1; 53 | } 54 | 55 | int SqlGetAffectedRowsCampaign(string sDatabase) 56 | { 57 | sqlquery sql = SqlPrepareQueryCampaign(sDatabase, "SELECT changes();"); 58 | 59 | return SqlStep(sql) ? SqlGetInt(sql, 0) : -1; 60 | } 61 | 62 | int SqlGetAffectedRowsObject(object oObject) 63 | { 64 | sqlquery sql = SqlPrepareQueryObject(oObject, "SELECT changes();"); 65 | 66 | return SqlStep(sql) ? SqlGetInt(sql, 0) : -1; 67 | } 68 | 69 | sqlquery SqlPrepareQuery(string sDatabase, string sQuery, int bUseModule) 70 | { 71 | if (bUseModule) 72 | return SqlPrepareQueryObject(GetModule(), sQuery); 73 | else 74 | return SqlPrepareQueryCampaign(sDatabase, sQuery); 75 | } 76 | 77 | -------------------------------------------------------------------------------- /Core/es_inc_test.nss: -------------------------------------------------------------------------------- 1 | /* 2 | ScriptName: es_inc_test.nss 3 | Created by: Daz 4 | 5 | Description: Event System Test Include 6 | */ 7 | 8 | #include "es_inc_util" 9 | 10 | const string TEST_SCRIPT_NAME = "es_inc_test"; 11 | 12 | void Test_Assert(string sTestName, int bTestResult); 13 | void Test_Warn(string sTestName, int bTestResult); 14 | 15 | int Test_ExecuteTestFunction(string sComponent, string sFunctionName) 16 | { 17 | int bReturn; 18 | string sError = ES_Util_ExecuteScriptChunk(sComponent, nssFunction(sFunctionName, nssEscapeDoubleQuotes(sComponent)), GetModule()); 19 | 20 | if (sError != "") 21 | { 22 | ES_Util_Log("Test", " > WARNING: Failed to run tests with error: " + sError); 23 | bReturn = FALSE; 24 | } 25 | else 26 | { 27 | object oDataObject = ES_Util_GetDataObject(TEST_SCRIPT_NAME); 28 | int nTotal = GetLocalInt(oDataObject, "NumberOfTests"); 29 | int nFailed = GetLocalInt(oDataObject, "Failures"); 30 | int nWarn = GetLocalInt(oDataObject, "Warnings"); 31 | int nPassed = nTotal - nFailed - nWarn; 32 | 33 | ES_Util_Log("Test", " * RESULT: Total: " + IntToString(nTotal) + " -> " + 34 | IntToString(nPassed) + " Passed | " + 35 | IntToString(nFailed) + " Failed | " + 36 | IntToString(nWarn) + (nWarn == 1 ? " Warning" : " Warnings")); 37 | 38 | DeleteLocalInt(oDataObject, "NumberOfTests"); 39 | DeleteLocalInt(oDataObject, "Failures"); 40 | DeleteLocalInt(oDataObject, "Warnings"); 41 | 42 | bReturn = !nFailed; 43 | } 44 | 45 | return bReturn; 46 | } 47 | 48 | void Test_Assert(string sTestName, int bTestResult) 49 | { 50 | object oDataObject = ES_Util_GetDataObject(TEST_SCRIPT_NAME); 51 | int nCurrentTest = GetLocalInt(oDataObject, "NumberOfTests") + 1; 52 | 53 | ES_Util_Log("Test", " [" + IntToString(nCurrentTest) + "] " + sTestName + " -> " + (bTestResult ? "PASS" : "FAIL")); 54 | 55 | if (!bTestResult) 56 | SetLocalInt(oDataObject, "Failures", GetLocalInt(oDataObject, "Failures") + 1); 57 | 58 | SetLocalInt(oDataObject, "NumberOfTests", nCurrentTest); 59 | } 60 | 61 | void Test_Warn(string sTestName, int bTestResult) 62 | { 63 | object oDataObject = ES_Util_GetDataObject(TEST_SCRIPT_NAME); 64 | int nCurrentTest = GetLocalInt(oDataObject, "NumberOfTests") + 1; 65 | 66 | ES_Util_Log("Test", " [" + IntToString(nCurrentTest) + "] " + sTestName + " -> " + (bTestResult ? "PASS" : "FAIL (WARNING)")); 67 | 68 | if (!bTestResult) 69 | SetLocalInt(oDataObject, "Warnings", GetLocalInt(oDataObject, "Warnings") + 1); 70 | 71 | SetLocalInt(oDataObject, "NumberOfTests", nCurrentTest); 72 | } 73 | 74 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Daz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EventSystem 2 | This is an easy to use modular Event System for Neverwinter Nights using NWNX:EE. TODO: Write a better description. 3 | 4 | ## Requirements for Core 5 | - **NWNX:EE Plugins**: 6 | - Object 7 | - Util 8 | - **NWNX:EE Environment Variables**: 9 | - `NWNX_CORE_ALLOW_NWNX_FUNCTIONS_IN_EXECUTE_SCRIPT_CHUNK=true` 10 | - `NWNX_CORE_SHUTDOWN_SCRIPT=es_obj_e_3019` 11 | - `NWNX_UTIL_PRE_MODULE_START_SCRIPT_CHUNK="#include \"es_inc_core\" void main() { ES_Core_Init(); }"` 12 | 13 | ## Docker Setup 14 | The only difference on setting up the system in Docker than in native Linux is on setting the `NWNX_UTIL_PRE_MODULE_START_SCRIPT_CHUNK` variable. It should be set up as follows: 15 | - `NWNX_UTIL_PRE_MODULE_START_SCRIPT_CHUNK=#include "es_inc_core" void main() { ES_Core_Init(); }` 16 | 17 | ## How To Use 18 | 1) Make sure you have enabled the required plugins and set the required environment variables listed above. 19 | 2) Add the script files in the [Core](https://github.com/Daztek/EventSystem/tree/master/Core) folder to your module. 20 | 3) Add one or more [Core Components](https://github.com/Daztek/EventSystem/tree/master/Components/Core), [Services](https://github.com/Daztek/EventSystem/tree/master/Components/Services) and [Subsystems](https://github.com/Daztek/EventSystem/tree/master/Components/Subsystems) script files to your module. 21 | 4) Start your server! 22 | 23 | ## Want to write your own subsystem? 24 | Have a look at heavily commented es_s_example.nss! (TODO) 25 | -------------------------------------------------------------------------------- /Resources/Fonts/fnt_book.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daztek/EventSystem/c0055c96b81be91c99194272d6121395777578f2/Resources/Fonts/fnt_book.tga -------------------------------------------------------------------------------- /Resources/Fonts/fnt_book.txi: -------------------------------------------------------------------------------- 1 | mipmap 0 2 | filter 0 3 | downsamplemax 0 4 | downsamplemin 0 5 | numchars 127 6 | fontheight 4.800000 7 | baselineheight 4.800000 8 | texturewidth 7.680000 9 | spacingR 0.000000 10 | spacingB 0.000000 11 | upperleftcoords 127 12 | 0.000000 0.000000 0 13 | 0.000000 0.000000 0 14 | 0.000000 0.000000 0 15 | 0.000000 0.000000 0 16 | 0.000000 0.000000 0 17 | 0.000000 0.000000 0 18 | 0.000000 0.000000 0 19 | 0.000000 0.000000 0 20 | 0.000000 0.000000 0 21 | 0.000000 0.000000 0 22 | 0.000000 0.000000 0 23 | 0.000000 0.000000 0 24 | 0.000000 0.000000 0 25 | 0.000000 0.000000 0 26 | 0.000000 0.000000 0 27 | 0.000000 0.000000 0 28 | 0.312500 0.625000 0 29 | 0.000000 0.000000 0 30 | 0.000000 0.000000 0 31 | 0.000000 0.000000 0 32 | 0.000000 0.000000 0 33 | 0.000000 0.000000 0 34 | 0.000000 0.000000 0 35 | 0.000000 0.000000 0 36 | 0.000000 0.000000 0 37 | 0.000000 0.000000 0 38 | 0.000000 0.000000 0 39 | 0.000000 0.000000 0 40 | 0.000000 0.000000 0 41 | 0.000000 0.000000 0 42 | 0.000000 0.000000 0 43 | 0.000000 0.000000 0 44 | 0.250000 0.625000 0 45 | 0.375000 0.500000 0 46 | 0.875000 0.375000 0 47 | 0.250000 0.375000 0 48 | 0.312500 0.375000 0 49 | 0.375000 0.375000 0 50 | 0.500000 0.375000 0 51 | 0.500000 0.500000 0 52 | 0.187500 0.500000 0 53 | 0.562500 0.500000 0 54 | 0.312500 0.500000 0 55 | 0.625000 0.375000 0 56 | 0.062500 0.500000 0 57 | 0.750000 0.500000 0 58 | 0.937500 0.625000 0 59 | 0.062500 0.375000 0 60 | 0.687500 0.500000 0 61 | 0.375000 0.625000 0 62 | 0.437500 0.625000 0 63 | 0.500000 0.625000 0 64 | 0.562500 0.625000 0 65 | 0.625000 0.625000 0 66 | 0.687500 0.625000 0 67 | 0.750000 0.625000 0 68 | 0.812500 0.625000 0 69 | 0.875000 0.625000 0 70 | 0.250000 0.500000 0 71 | 0.125000 0.500000 0 72 | 0.937500 0.375000 0 73 | 0.812500 0.500000 0 74 | 0.000000 0.250000 0 75 | 0.437500 0.500000 0 76 | 0.187500 0.375000 0 77 | 0.625000 0.875000 0 78 | 0.687500 0.875000 0 79 | 0.750000 0.875000 0 80 | 0.812500 0.875000 0 81 | 0.875000 0.875000 0 82 | 0.937500 0.875000 0 83 | 0.000000 0.750000 0 84 | 0.062500 0.750000 0 85 | 0.125000 0.750000 0 86 | 0.187500 0.750000 0 87 | 0.250000 0.750000 0 88 | 0.312500 0.750000 0 89 | 0.375000 0.750000 0 90 | 0.437500 0.750000 0 91 | 0.500000 0.750000 0 92 | 0.562500 0.750000 0 93 | 0.625000 0.750000 0 94 | 0.687500 0.750000 0 95 | 0.750000 0.750000 0 96 | 0.812500 0.750000 0 97 | 0.875000 0.750000 0 98 | 0.937500 0.750000 0 99 | 0.000000 0.625000 0 100 | 0.062500 0.625000 0 101 | 0.125000 0.625000 0 102 | 0.187500 0.625000 0 103 | 0.875000 0.500000 0 104 | 0.000000 0.375000 0 105 | 0.937500 0.500000 0 106 | 0.437500 0.375000 0 107 | 0.562500 0.375000 0 108 | 0.625000 0.500000 0 109 | 0.000000 1.000000 0 110 | 0.062500 1.000000 0 111 | 0.125000 1.000000 0 112 | 0.187500 1.000000 0 113 | 0.250000 1.000000 0 114 | 0.312500 1.000000 0 115 | 0.375000 1.000000 0 116 | 0.437500 1.000000 0 117 | 0.500000 1.000000 0 118 | 0.562500 1.000000 0 119 | 0.625000 1.000000 0 120 | 0.687500 1.000000 0 121 | 0.750000 1.000000 0 122 | 0.812500 1.000000 0 123 | 0.875000 1.000000 0 124 | 0.937500 1.000000 0 125 | 0.000000 0.875000 0 126 | 0.062500 0.875000 0 127 | 0.125000 0.875000 0 128 | 0.187500 0.875000 0 129 | 0.250000 0.875000 0 130 | 0.312500 0.875000 0 131 | 0.375000 0.875000 0 132 | 0.437500 0.875000 0 133 | 0.500000 0.875000 0 134 | 0.562500 0.875000 0 135 | 0.687500 0.375000 0 136 | 0.812500 0.375000 0 137 | 0.750000 0.375000 0 138 | 0.125000 0.375000 0 139 | lowerrightcoords 127 140 | 0.000000 0.000000 0 141 | 0.000000 0.000000 0 142 | 0.000000 0.000000 0 143 | 0.000000 0.000000 0 144 | 0.000000 0.000000 0 145 | 0.000000 0.000000 0 146 | 0.000000 0.000000 0 147 | 0.000000 0.000000 0 148 | 0.000000 0.000000 0 149 | 0.000000 0.000000 0 150 | 0.000000 0.000000 0 151 | 0.000000 0.000000 0 152 | 0.000000 0.000000 0 153 | 0.000000 0.000000 0 154 | 0.000000 0.000000 0 155 | 0.000000 0.000000 0 156 | 0.375000 0.500000 0 157 | 0.000000 0.000000 0 158 | 0.000000 0.000000 0 159 | 0.000000 0.000000 0 160 | 0.000000 0.000000 0 161 | 0.000000 0.000000 0 162 | 0.000000 0.000000 0 163 | 0.000000 0.000000 0 164 | 0.000000 0.000000 0 165 | 0.000000 0.000000 0 166 | 0.000000 0.000000 0 167 | 0.000000 0.000000 0 168 | 0.000000 0.000000 0 169 | 0.000000 0.000000 0 170 | 0.000000 0.000000 0 171 | 0.000000 0.000000 0 172 | 0.312500 0.500000 0 173 | 0.437500 0.375000 0 174 | 0.937500 0.250000 0 175 | 0.312500 0.250000 0 176 | 0.375000 0.250000 0 177 | 0.437500 0.250000 0 178 | 0.562500 0.250000 0 179 | 0.562500 0.375000 0 180 | 0.250000 0.375000 0 181 | 0.625000 0.375000 0 182 | 0.375000 0.375000 0 183 | 0.687500 0.250000 0 184 | 0.125000 0.375000 0 185 | 0.812500 0.375000 0 186 | 1.000000 0.500000 0 187 | 0.125000 0.250000 0 188 | 0.750000 0.375000 0 189 | 0.437500 0.500000 0 190 | 0.500000 0.500000 0 191 | 0.562500 0.500000 0 192 | 0.625000 0.500000 0 193 | 0.687500 0.500000 0 194 | 0.750000 0.500000 0 195 | 0.812500 0.500000 0 196 | 0.875000 0.500000 0 197 | 0.937500 0.500000 0 198 | 0.312500 0.375000 0 199 | 0.187500 0.375000 0 200 | 1.000000 0.250000 0 201 | 0.875000 0.375000 0 202 | 0.062500 0.125000 0 203 | 0.500000 0.375000 0 204 | 0.250000 0.250000 0 205 | 0.687500 0.750000 0 206 | 0.750000 0.750000 0 207 | 0.812500 0.750000 0 208 | 0.875000 0.750000 0 209 | 0.937500 0.750000 0 210 | 1.000000 0.750000 0 211 | 0.062500 0.625000 0 212 | 0.125000 0.625000 0 213 | 0.187500 0.625000 0 214 | 0.250000 0.625000 0 215 | 0.312500 0.625000 0 216 | 0.375000 0.625000 0 217 | 0.437500 0.625000 0 218 | 0.500000 0.625000 0 219 | 0.562500 0.625000 0 220 | 0.625000 0.625000 0 221 | 0.687500 0.625000 0 222 | 0.750000 0.625000 0 223 | 0.812500 0.625000 0 224 | 0.875000 0.625000 0 225 | 0.937500 0.625000 0 226 | 1.000000 0.625000 0 227 | 0.062500 0.500000 0 228 | 0.125000 0.500000 0 229 | 0.187500 0.500000 0 230 | 0.250000 0.500000 0 231 | 0.937500 0.375000 0 232 | 0.062500 0.250000 0 233 | 1.000000 0.375000 0 234 | 0.500000 0.250000 0 235 | 0.625000 0.250000 0 236 | 0.687500 0.375000 0 237 | 1.000000 0.300000 0 238 | 0.125000 0.875000 0 239 | 0.187500 0.875000 0 240 | 0.250000 0.875000 0 241 | 0.312500 0.875000 0 242 | 0.375000 0.875000 0 243 | 0.437500 0.875000 0 244 | 0.500000 0.875000 0 245 | 0.562500 0.875000 0 246 | 0.625000 0.875000 0 247 | 0.687500 0.875000 0 248 | 0.750000 0.875000 0 249 | 0.812500 0.875000 0 250 | 0.875000 0.875000 0 251 | 0.937500 0.875000 0 252 | 1.000000 0.875000 0 253 | 0.062500 0.750000 0 254 | 0.125000 0.750000 0 255 | 0.187500 0.750000 0 256 | 0.250000 0.750000 0 257 | 0.312500 0.750000 0 258 | 0.375000 0.750000 0 259 | 0.437500 0.750000 0 260 | 0.500000 0.750000 0 261 | 0.562500 0.750000 0 262 | 0.625000 0.750000 0 263 | 0.750000 0.250000 0 264 | 0.875000 0.250000 0 265 | 0.812500 0.250000 0 266 | 0.187500 0.250000 0 267 | -------------------------------------------------------------------------------- /Resources/Fonts/fnt_es_gui.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daztek/EventSystem/c0055c96b81be91c99194272d6121395777578f2/Resources/Fonts/fnt_es_gui.tga -------------------------------------------------------------------------------- /Resources/Fonts/fnt_es_gui.txi: -------------------------------------------------------------------------------- 1 | mipmap 0 2 | filter 0 3 | downsamplemax 0 4 | downsamplemin 0 5 | numchars 127 6 | fontheight 0.160000 7 | baselineheight 0.140000 8 | texturewidth 1.280000 9 | spacingR 0.000000 10 | spacingB 0.000000 11 | upperleftcoords 127 12 | 0.000000 0.000000 0 13 | 0.000000 0.000000 0 14 | 0.000000 0.000000 0 15 | 0.000000 0.000000 0 16 | 0.000000 0.000000 0 17 | 0.000000 0.000000 0 18 | 0.000000 0.000000 0 19 | 0.000000 0.000000 0 20 | 0.000000 0.000000 0 21 | 0.000000 0.000000 0 22 | 0.000000 0.000000 0 23 | 0.000000 0.000000 0 24 | 0.000000 0.000000 0 25 | 0.000000 0.000000 0 26 | 0.000000 0.000000 0 27 | 0.000000 0.000000 0 28 | 0.312500 0.625000 0 29 | 0.000000 0.000000 0 30 | 0.000000 0.000000 0 31 | 0.000000 0.000000 0 32 | 0.000000 0.000000 0 33 | 0.000000 0.000000 0 34 | 0.000000 0.000000 0 35 | 0.000000 0.000000 0 36 | 0.000000 0.000000 0 37 | 0.000000 0.000000 0 38 | 0.000000 0.000000 0 39 | 0.000000 0.000000 0 40 | 0.000000 0.000000 0 41 | 0.000000 0.000000 0 42 | 0.000000 0.000000 0 43 | 0.000000 0.000000 0 44 | 0.250000 0.625000 0 45 | 0.375000 0.500000 0 46 | 0.875000 0.375000 0 47 | 0.250000 0.375000 0 48 | 0.312500 0.375000 0 49 | 0.375000 0.375000 0 50 | 0.500000 0.375000 0 51 | 0.500000 0.500000 0 52 | 0.187500 0.500000 0 53 | 0.562500 0.500000 0 54 | 0.312500 0.500000 0 55 | 0.625000 0.375000 0 56 | 0.062500 0.500000 0 57 | 0.750000 0.500000 0 58 | 0.937500 0.625000 0 59 | 0.062500 0.375000 0 60 | 0.687500 0.500000 0 61 | 0.375000 0.625000 0 62 | 0.437500 0.625000 0 63 | 0.500000 0.625000 0 64 | 0.562500 0.625000 0 65 | 0.625000 0.625000 0 66 | 0.687500 0.625000 0 67 | 0.750000 0.625000 0 68 | 0.812500 0.625000 0 69 | 0.875000 0.625000 0 70 | 0.250000 0.500000 0 71 | 0.125000 0.500000 0 72 | 0.937500 0.375000 0 73 | 0.812500 0.500000 0 74 | 0.000000 0.250000 0 75 | 0.437500 0.500000 0 76 | 0.187500 0.375000 0 77 | 0.625000 0.875000 0 78 | 0.687500 0.875000 0 79 | 0.750000 0.875000 0 80 | 0.812500 0.875000 0 81 | 0.875000 0.875000 0 82 | 0.937500 0.875000 0 83 | 0.000000 0.750000 0 84 | 0.062500 0.750000 0 85 | 0.125000 0.750000 0 86 | 0.187500 0.750000 0 87 | 0.250000 0.750000 0 88 | 0.312500 0.750000 0 89 | 0.375000 0.750000 0 90 | 0.437500 0.750000 0 91 | 0.500000 0.750000 0 92 | 0.562500 0.750000 0 93 | 0.625000 0.750000 0 94 | 0.687500 0.750000 0 95 | 0.750000 0.750000 0 96 | 0.812500 0.750000 0 97 | 0.875000 0.750000 0 98 | 0.937500 0.750000 0 99 | 0.000000 0.625000 0 100 | 0.062500 0.625000 0 101 | 0.125000 0.625000 0 102 | 0.187500 0.625000 0 103 | 0.875000 0.500000 0 104 | 0.000000 0.375000 0 105 | 0.937500 0.500000 0 106 | 0.437500 0.375000 0 107 | 0.562500 0.375000 0 108 | 0.625000 0.500000 0 109 | 0.000000 1.000000 0 110 | 0.062500 1.000000 0 111 | 0.125000 1.000000 0 112 | 0.187500 1.000000 0 113 | 0.250000 1.000000 0 114 | 0.312500 1.000000 0 115 | 0.375000 1.000000 0 116 | 0.437500 1.000000 0 117 | 0.500000 1.000000 0 118 | 0.562500 1.000000 0 119 | 0.625000 1.000000 0 120 | 0.687500 1.000000 0 121 | 0.750000 1.000000 0 122 | 0.812500 1.000000 0 123 | 0.875000 1.000000 0 124 | 0.937500 1.000000 0 125 | 0.000000 0.875000 0 126 | 0.062500 0.875000 0 127 | 0.125000 0.875000 0 128 | 0.187500 0.875000 0 129 | 0.250000 0.875000 0 130 | 0.312500 0.875000 0 131 | 0.375000 0.875000 0 132 | 0.437500 0.875000 0 133 | 0.500000 0.875000 0 134 | 0.562500 0.875000 0 135 | 0.687500 0.375000 0 136 | 0.812500 0.375000 0 137 | 0.750000 0.375000 0 138 | 0.125000 0.375000 0 139 | lowerrightcoords 127 140 | 0.000000 0.000000 0 141 | 0.000000 0.000000 0 142 | 0.000000 0.000000 0 143 | 0.000000 0.000000 0 144 | 0.000000 0.000000 0 145 | 0.000000 0.000000 0 146 | 0.000000 0.000000 0 147 | 0.000000 0.000000 0 148 | 0.000000 0.000000 0 149 | 0.000000 0.000000 0 150 | 0.000000 0.000000 0 151 | 0.000000 0.000000 0 152 | 0.000000 0.000000 0 153 | 0.000000 0.000000 0 154 | 0.000000 0.000000 0 155 | 0.000000 0.000000 0 156 | 0.375000 0.500000 0 157 | 0.000000 0.000000 0 158 | 0.000000 0.000000 0 159 | 0.000000 0.000000 0 160 | 0.000000 0.000000 0 161 | 0.000000 0.000000 0 162 | 0.000000 0.000000 0 163 | 0.000000 0.000000 0 164 | 0.000000 0.000000 0 165 | 0.000000 0.000000 0 166 | 0.000000 0.000000 0 167 | 0.000000 0.000000 0 168 | 0.000000 0.000000 0 169 | 0.000000 0.000000 0 170 | 0.000000 0.000000 0 171 | 0.000000 0.000000 0 172 | 0.312500 0.500000 0 173 | 0.437500 0.375000 0 174 | 0.937500 0.250000 0 175 | 0.312500 0.250000 0 176 | 0.375000 0.250000 0 177 | 0.437500 0.250000 0 178 | 0.562500 0.250000 0 179 | 0.562500 0.375000 0 180 | 0.250000 0.375000 0 181 | 0.625000 0.375000 0 182 | 0.375000 0.375000 0 183 | 0.687500 0.250000 0 184 | 0.125000 0.375000 0 185 | 0.812500 0.375000 0 186 | 1.000000 0.500000 0 187 | 0.125000 0.250000 0 188 | 0.750000 0.375000 0 189 | 0.437500 0.500000 0 190 | 0.500000 0.500000 0 191 | 0.562500 0.500000 0 192 | 0.625000 0.500000 0 193 | 0.687500 0.500000 0 194 | 0.750000 0.500000 0 195 | 0.812500 0.500000 0 196 | 0.875000 0.500000 0 197 | 0.937500 0.500000 0 198 | 0.312500 0.375000 0 199 | 0.187500 0.375000 0 200 | 1.000000 0.250000 0 201 | 0.875000 0.375000 0 202 | 0.062500 0.125000 0 203 | 0.500000 0.375000 0 204 | 0.250000 0.250000 0 205 | 0.687500 0.750000 0 206 | 0.750000 0.750000 0 207 | 0.812500 0.750000 0 208 | 0.875000 0.750000 0 209 | 0.937500 0.750000 0 210 | 1.000000 0.750000 0 211 | 0.062500 0.625000 0 212 | 0.125000 0.625000 0 213 | 0.187500 0.625000 0 214 | 0.250000 0.625000 0 215 | 0.312500 0.625000 0 216 | 0.375000 0.625000 0 217 | 0.437500 0.625000 0 218 | 0.500000 0.625000 0 219 | 0.562500 0.625000 0 220 | 0.625000 0.625000 0 221 | 0.687500 0.625000 0 222 | 0.750000 0.625000 0 223 | 0.812500 0.625000 0 224 | 0.875000 0.625000 0 225 | 0.937500 0.625000 0 226 | 1.000000 0.625000 0 227 | 0.062500 0.500000 0 228 | 0.125000 0.500000 0 229 | 0.187500 0.500000 0 230 | 0.250000 0.500000 0 231 | 0.937500 0.375000 0 232 | 0.062500 0.250000 0 233 | 1.000000 0.375000 0 234 | 0.500000 0.250000 0 235 | 0.625000 0.250000 0 236 | 0.687500 0.375000 0 237 | 0.062500 0.875000 0 238 | 0.125000 0.875000 0 239 | 0.187500 0.875000 0 240 | 0.250000 0.875000 0 241 | 0.312500 0.875000 0 242 | 0.375000 0.875000 0 243 | 0.437500 0.875000 0 244 | 0.500000 0.875000 0 245 | 0.562500 0.875000 0 246 | 0.625000 0.875000 0 247 | 0.687500 0.875000 0 248 | 0.750000 0.875000 0 249 | 0.812500 0.875000 0 250 | 0.875000 0.875000 0 251 | 0.937500 0.875000 0 252 | 1.000000 0.875000 0 253 | 0.062500 0.750000 0 254 | 0.125000 0.750000 0 255 | 0.187500 0.750000 0 256 | 0.250000 0.750000 0 257 | 0.312500 0.750000 0 258 | 0.375000 0.750000 0 259 | 0.437500 0.750000 0 260 | 0.500000 0.750000 0 261 | 0.562500 0.750000 0 262 | 0.625000 0.750000 0 263 | 0.750000 0.250000 0 264 | 0.875000 0.250000 0 265 | 0.812500 0.250000 0 266 | 0.187500 0.250000 0 267 | -------------------------------------------------------------------------------- /Resources/Fonts/fnt_es_hbport.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daztek/EventSystem/c0055c96b81be91c99194272d6121395777578f2/Resources/Fonts/fnt_es_hbport.tga -------------------------------------------------------------------------------- /Resources/Fonts/fnt_es_hbport.txi: -------------------------------------------------------------------------------- 1 | mipmap 0 2 | filter 0 3 | downsamplemax 0 4 | downsamplemin 0 5 | numchars 127 6 | fontheight 0.500000 7 | baselineheight 0.500000 8 | texturewidth 0.320000 9 | spacingR 0.000000 10 | spacingB 0.030000 11 | upperleftcoords 127 12 | 0.000000 0.000000 0 13 | 0.000000 0.000000 0 14 | 0.000000 0.000000 0 15 | 0.000000 0.000000 0 16 | 0.000000 0.000000 0 17 | 0.000000 0.000000 0 18 | 0.000000 0.000000 0 19 | 0.000000 0.000000 0 20 | 0.000000 0.000000 0 21 | 0.000000 0.000000 0 22 | 0.000000 0.000000 0 23 | 0.000000 0.000000 0 24 | 0.000000 0.000000 0 25 | 0.000000 0.000000 0 26 | 0.000000 0.000000 0 27 | 0.000000 0.000000 0 28 | 0.312500 0.625000 0 29 | 0.000000 0.000000 0 30 | 0.000000 0.000000 0 31 | 0.000000 0.000000 0 32 | 0.000000 0.000000 0 33 | 0.000000 0.000000 0 34 | 0.000000 0.000000 0 35 | 0.000000 0.000000 0 36 | 0.000000 0.000000 0 37 | 0.000000 0.000000 0 38 | 0.000000 0.000000 0 39 | 0.000000 0.000000 0 40 | 0.000000 0.000000 0 41 | 0.000000 0.000000 0 42 | 0.000000 0.000000 0 43 | 0.000000 0.000000 0 44 | 0.250000 0.625000 0 45 | 0.375000 0.500000 0 46 | 0.875000 0.375000 0 47 | 0.250000 0.375000 0 48 | 0.312500 0.375000 0 49 | 0.375000 0.375000 0 50 | 0.500000 0.375000 0 51 | 0.500000 0.500000 0 52 | 0.187500 0.500000 0 53 | 0.562500 0.500000 0 54 | 0.312500 0.500000 0 55 | 0.625000 0.375000 0 56 | 0.062500 0.500000 0 57 | 0.750000 0.500000 0 58 | 0.937500 0.625000 0 59 | 0.062500 0.375000 0 60 | 0.687500 0.500000 0 61 | 0.375000 0.625000 0 62 | 0.437500 0.625000 0 63 | 0.500000 0.625000 0 64 | 0.562500 0.625000 0 65 | 0.625000 0.625000 0 66 | 0.687500 0.625000 0 67 | 0.750000 0.625000 0 68 | 0.812500 0.625000 0 69 | 0.875000 0.625000 0 70 | 0.250000 0.500000 0 71 | 0.125000 0.500000 0 72 | 0.937500 0.375000 0 73 | 0.812500 0.500000 0 74 | 0.000000 0.250000 0 75 | 0.437500 0.500000 0 76 | 0.187500 0.375000 0 77 | 0.625000 0.875000 0 78 | 0.687500 0.875000 0 79 | 0.750000 0.875000 0 80 | 0.812500 0.875000 0 81 | 0.875000 0.875000 0 82 | 0.937500 0.875000 0 83 | 0.000000 0.750000 0 84 | 0.062500 0.750000 0 85 | 0.125000 0.750000 0 86 | 0.187500 0.750000 0 87 | 0.250000 0.750000 0 88 | 0.312500 0.750000 0 89 | 0.375000 0.750000 0 90 | 0.437500 0.750000 0 91 | 0.500000 0.750000 0 92 | 0.562500 0.750000 0 93 | 0.625000 0.750000 0 94 | 0.687500 0.750000 0 95 | 0.750000 0.750000 0 96 | 0.812500 0.750000 0 97 | 0.875000 0.750000 0 98 | 0.937500 0.750000 0 99 | 0.000000 0.625000 0 100 | 0.062500 0.625000 0 101 | 0.125000 0.625000 0 102 | 0.187500 0.625000 0 103 | 0.875000 0.500000 0 104 | 0.000000 0.375000 0 105 | 0.937500 0.500000 0 106 | 0.437500 0.375000 0 107 | 0.562500 0.375000 0 108 | 0.625000 0.500000 0 109 | 0.000000 1.000000 0 110 | 0.062500 1.000000 0 111 | 0.125000 1.000000 0 112 | 0.187500 1.000000 0 113 | 0.250000 1.000000 0 114 | 0.312500 1.000000 0 115 | 0.375000 1.000000 0 116 | 0.437500 1.000000 0 117 | 0.500000 1.000000 0 118 | 0.562500 1.000000 0 119 | 0.625000 1.000000 0 120 | 0.687500 1.000000 0 121 | 0.750000 1.000000 0 122 | 0.812500 1.000000 0 123 | 0.875000 1.000000 0 124 | 0.937500 1.000000 0 125 | 0.000000 0.875000 0 126 | 0.062500 0.875000 0 127 | 0.125000 0.875000 0 128 | 0.187500 0.875000 0 129 | 0.250000 0.875000 0 130 | 0.312500 0.875000 0 131 | 0.375000 0.875000 0 132 | 0.437500 0.875000 0 133 | 0.500000 0.875000 0 134 | 0.562500 0.875000 0 135 | 0.687500 0.375000 0 136 | 0.812500 0.375000 0 137 | 0.750000 0.375000 0 138 | 0.125000 0.375000 0 139 | lowerrightcoords 127 140 | 0.000000 0.000000 0 141 | 0.000000 0.000000 0 142 | 0.000000 0.000000 0 143 | 0.000000 0.000000 0 144 | 0.000000 0.000000 0 145 | 0.000000 0.000000 0 146 | 0.000000 0.000000 0 147 | 0.000000 0.000000 0 148 | 0.000000 0.000000 0 149 | 0.000000 0.000000 0 150 | 0.000000 0.000000 0 151 | 0.000000 0.000000 0 152 | 0.000000 0.000000 0 153 | 0.000000 0.000000 0 154 | 0.000000 0.000000 0 155 | 0.000000 0.000000 0 156 | 0.375000 0.500000 0 157 | 0.000000 0.000000 0 158 | 0.000000 0.000000 0 159 | 0.000000 0.000000 0 160 | 0.000000 0.000000 0 161 | 0.000000 0.000000 0 162 | 0.000000 0.000000 0 163 | 0.000000 0.000000 0 164 | 0.000000 0.000000 0 165 | 0.000000 0.000000 0 166 | 0.000000 0.000000 0 167 | 0.000000 0.000000 0 168 | 0.000000 0.000000 0 169 | 0.000000 0.000000 0 170 | 0.000000 0.000000 0 171 | 0.000000 0.000000 0 172 | 0.312500 0.500000 0 173 | 0.437500 0.375000 0 174 | 0.937500 0.250000 0 175 | 0.312500 0.250000 0 176 | 0.375000 0.250000 0 177 | 0.437500 0.250000 0 178 | 0.562500 0.250000 0 179 | 0.562500 0.375000 0 180 | 0.250000 0.375000 0 181 | 0.625000 0.375000 0 182 | 0.375000 0.375000 0 183 | 0.687500 0.250000 0 184 | 0.125000 0.375000 0 185 | 0.812500 0.375000 0 186 | 1.000000 0.500000 0 187 | 0.125000 0.250000 0 188 | 0.750000 0.375000 0 189 | 0.437500 0.500000 0 190 | 0.500000 0.500000 0 191 | 0.562500 0.500000 0 192 | 0.625000 0.500000 0 193 | 0.687500 0.500000 0 194 | 0.750000 0.500000 0 195 | 0.812500 0.500000 0 196 | 0.875000 0.500000 0 197 | 0.937500 0.500000 0 198 | 0.312500 0.375000 0 199 | 0.187500 0.375000 0 200 | 1.000000 0.250000 0 201 | 0.875000 0.375000 0 202 | 0.062500 0.125000 0 203 | 0.500000 0.375000 0 204 | 0.250000 0.250000 0 205 | 0.687500 0.750000 0 206 | 0.750000 0.750000 0 207 | 0.812500 0.750000 0 208 | 0.875000 0.750000 0 209 | 0.937500 0.750000 0 210 | 1.000000 0.750000 0 211 | 0.062500 0.625000 0 212 | 0.125000 0.625000 0 213 | 0.187500 0.625000 0 214 | 0.250000 0.625000 0 215 | 0.312500 0.625000 0 216 | 0.375000 0.625000 0 217 | 0.437500 0.625000 0 218 | 0.500000 0.625000 0 219 | 0.562500 0.625000 0 220 | 0.625000 0.625000 0 221 | 0.687500 0.625000 0 222 | 0.750000 0.625000 0 223 | 0.812500 0.625000 0 224 | 0.875000 0.625000 0 225 | 0.937500 0.625000 0 226 | 1.000000 0.625000 0 227 | 0.062500 0.500000 0 228 | 0.125000 0.500000 0 229 | 0.187500 0.500000 0 230 | 0.250000 0.500000 0 231 | 0.937500 0.375000 0 232 | 0.062500 0.250000 0 233 | 1.000000 0.375000 0 234 | 0.500000 0.250000 0 235 | 0.625000 0.250000 0 236 | 0.687500 0.375000 0 237 | 1.000000 0.220000 0 238 | 0.125000 0.875000 0 239 | 0.187500 0.875000 0 240 | 0.250000 0.875000 0 241 | 0.312500 0.875000 0 242 | 0.375000 0.875000 0 243 | 0.437500 0.875000 0 244 | 0.500000 0.875000 0 245 | 0.562500 0.875000 0 246 | 0.625000 0.875000 0 247 | 0.687500 0.875000 0 248 | 0.750000 0.875000 0 249 | 0.812500 0.875000 0 250 | 0.875000 0.875000 0 251 | 0.937500 0.875000 0 252 | 1.000000 0.875000 0 253 | 0.062500 0.750000 0 254 | 0.125000 0.750000 0 255 | 0.187500 0.750000 0 256 | 0.250000 0.750000 0 257 | 0.312500 0.750000 0 258 | 0.375000 0.750000 0 259 | 0.437500 0.750000 0 260 | 0.500000 0.750000 0 261 | 0.562500 0.750000 0 262 | 0.625000 0.750000 0 263 | 0.750000 0.250000 0 264 | 0.875000 0.250000 0 265 | 0.812500 0.250000 0 266 | 0.187500 0.250000 0 267 | -------------------------------------------------------------------------------- /Resources/Fonts/fnt_es_icon32.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daztek/EventSystem/c0055c96b81be91c99194272d6121395777578f2/Resources/Fonts/fnt_es_icon32.tga -------------------------------------------------------------------------------- /Resources/Fonts/fnt_es_icon32.txi: -------------------------------------------------------------------------------- 1 | mipmap 0 2 | filter 0 3 | downsamplemax 0 4 | downsamplemin 0 5 | numchars 127 6 | fontheight 0.320000 7 | baselineheight 0.320000 8 | texturewidth 0.320000 9 | spacingR 0.000000 10 | spacingB 0.000000 11 | upperleftcoords 127 12 | 0.000000 0.000000 0 13 | 0.000000 0.000000 0 14 | 0.000000 0.000000 0 15 | 0.000000 0.000000 0 16 | 0.000000 0.000000 0 17 | 0.000000 0.000000 0 18 | 0.000000 0.000000 0 19 | 0.000000 0.000000 0 20 | 0.000000 0.000000 0 21 | 0.000000 0.000000 0 22 | 0.000000 0.000000 0 23 | 0.000000 0.000000 0 24 | 0.000000 0.000000 0 25 | 0.000000 0.000000 0 26 | 0.000000 0.000000 0 27 | 0.000000 0.000000 0 28 | 0.312500 0.625000 0 29 | 0.000000 0.000000 0 30 | 0.000000 0.000000 0 31 | 0.000000 0.000000 0 32 | 0.000000 0.000000 0 33 | 0.000000 0.000000 0 34 | 0.000000 0.000000 0 35 | 0.000000 0.000000 0 36 | 0.000000 0.000000 0 37 | 0.000000 0.000000 0 38 | 0.000000 0.000000 0 39 | 0.000000 0.000000 0 40 | 0.000000 0.000000 0 41 | 0.000000 0.000000 0 42 | 0.000000 0.000000 0 43 | 0.000000 0.000000 0 44 | 0.250000 0.625000 0 45 | 0.375000 0.500000 0 46 | 0.875000 0.375000 0 47 | 0.250000 0.375000 0 48 | 0.312500 0.375000 0 49 | 0.375000 0.375000 0 50 | 0.500000 0.375000 0 51 | 0.500000 0.500000 0 52 | 0.187500 0.500000 0 53 | 0.562500 0.500000 0 54 | 0.312500 0.500000 0 55 | 0.625000 0.375000 0 56 | 0.062500 0.500000 0 57 | 0.750000 0.500000 0 58 | 0.937500 0.625000 0 59 | 0.062500 0.375000 0 60 | 0.687500 0.500000 0 61 | 0.375000 0.625000 0 62 | 0.437500 0.625000 0 63 | 0.500000 0.625000 0 64 | 0.562500 0.625000 0 65 | 0.625000 0.625000 0 66 | 0.687500 0.625000 0 67 | 0.750000 0.625000 0 68 | 0.812500 0.625000 0 69 | 0.875000 0.625000 0 70 | 0.250000 0.500000 0 71 | 0.125000 0.500000 0 72 | 0.937500 0.375000 0 73 | 0.812500 0.500000 0 74 | 0.000000 0.250000 0 75 | 0.437500 0.500000 0 76 | 0.187500 0.375000 0 77 | 0.625000 0.875000 0 78 | 0.687500 0.875000 0 79 | 0.750000 0.875000 0 80 | 0.812500 0.875000 0 81 | 0.875000 0.875000 0 82 | 0.937500 0.875000 0 83 | 0.000000 0.750000 0 84 | 0.062500 0.750000 0 85 | 0.125000 0.750000 0 86 | 0.187500 0.750000 0 87 | 0.250000 0.750000 0 88 | 0.312500 0.750000 0 89 | 0.375000 0.750000 0 90 | 0.437500 0.750000 0 91 | 0.500000 0.750000 0 92 | 0.562500 0.750000 0 93 | 0.625000 0.750000 0 94 | 0.687500 0.750000 0 95 | 0.750000 0.750000 0 96 | 0.812500 0.750000 0 97 | 0.875000 0.750000 0 98 | 0.937500 0.750000 0 99 | 0.000000 0.625000 0 100 | 0.062500 0.625000 0 101 | 0.125000 0.625000 0 102 | 0.187500 0.625000 0 103 | 0.875000 0.500000 0 104 | 0.000000 0.375000 0 105 | 0.937500 0.500000 0 106 | 0.437500 0.375000 0 107 | 0.562500 0.375000 0 108 | 0.625000 0.500000 0 109 | 0.000000 1.000000 0 110 | 0.062500 1.000000 0 111 | 0.125000 1.000000 0 112 | 0.187500 1.000000 0 113 | 0.250000 1.000000 0 114 | 0.312500 1.000000 0 115 | 0.375000 1.000000 0 116 | 0.437500 1.000000 0 117 | 0.500000 1.000000 0 118 | 0.562500 1.000000 0 119 | 0.625000 1.000000 0 120 | 0.687500 1.000000 0 121 | 0.750000 1.000000 0 122 | 0.812500 1.000000 0 123 | 0.875000 1.000000 0 124 | 0.937500 1.000000 0 125 | 0.000000 0.875000 0 126 | 0.062500 0.875000 0 127 | 0.125000 0.875000 0 128 | 0.187500 0.875000 0 129 | 0.250000 0.875000 0 130 | 0.312500 0.875000 0 131 | 0.375000 0.875000 0 132 | 0.437500 0.875000 0 133 | 0.500000 0.875000 0 134 | 0.562500 0.875000 0 135 | 0.687500 0.375000 0 136 | 0.812500 0.375000 0 137 | 0.750000 0.375000 0 138 | 0.125000 0.375000 0 139 | lowerrightcoords 127 140 | 0.000000 0.000000 0 141 | 0.000000 0.000000 0 142 | 0.000000 0.000000 0 143 | 0.000000 0.000000 0 144 | 0.000000 0.000000 0 145 | 0.000000 0.000000 0 146 | 0.000000 0.000000 0 147 | 0.000000 0.000000 0 148 | 0.000000 0.000000 0 149 | 0.000000 0.000000 0 150 | 0.000000 0.000000 0 151 | 0.000000 0.000000 0 152 | 0.000000 0.000000 0 153 | 0.000000 0.000000 0 154 | 0.000000 0.000000 0 155 | 0.000000 0.000000 0 156 | 0.375000 0.500000 0 157 | 0.000000 0.000000 0 158 | 0.000000 0.000000 0 159 | 0.000000 0.000000 0 160 | 0.000000 0.000000 0 161 | 0.000000 0.000000 0 162 | 0.000000 0.000000 0 163 | 0.000000 0.000000 0 164 | 0.000000 0.000000 0 165 | 0.000000 0.000000 0 166 | 0.000000 0.000000 0 167 | 0.000000 0.000000 0 168 | 0.000000 0.000000 0 169 | 0.000000 0.000000 0 170 | 0.000000 0.000000 0 171 | 0.000000 0.000000 0 172 | 0.312500 0.500000 0 173 | 0.437500 0.375000 0 174 | 0.937500 0.250000 0 175 | 0.312500 0.250000 0 176 | 0.375000 0.250000 0 177 | 0.437500 0.250000 0 178 | 0.562500 0.250000 0 179 | 0.562500 0.375000 0 180 | 0.250000 0.375000 0 181 | 0.625000 0.375000 0 182 | 0.375000 0.375000 0 183 | 0.687500 0.250000 0 184 | 0.125000 0.375000 0 185 | 0.812500 0.375000 0 186 | 1.000000 0.500000 0 187 | 0.125000 0.250000 0 188 | 0.750000 0.375000 0 189 | 0.437500 0.500000 0 190 | 0.500000 0.500000 0 191 | 0.562500 0.500000 0 192 | 0.625000 0.500000 0 193 | 0.687500 0.500000 0 194 | 0.750000 0.500000 0 195 | 0.812500 0.500000 0 196 | 0.875000 0.500000 0 197 | 0.937500 0.500000 0 198 | 0.312500 0.375000 0 199 | 0.187500 0.375000 0 200 | 1.000000 0.250000 0 201 | 0.875000 0.375000 0 202 | 0.062500 0.125000 0 203 | 0.500000 0.375000 0 204 | 0.250000 0.250000 0 205 | 0.687500 0.750000 0 206 | 0.750000 0.750000 0 207 | 0.812500 0.750000 0 208 | 0.875000 0.750000 0 209 | 0.937500 0.750000 0 210 | 1.000000 0.750000 0 211 | 0.062500 0.625000 0 212 | 0.125000 0.625000 0 213 | 0.187500 0.625000 0 214 | 0.250000 0.625000 0 215 | 0.312500 0.625000 0 216 | 0.375000 0.625000 0 217 | 0.437500 0.625000 0 218 | 0.500000 0.625000 0 219 | 0.562500 0.625000 0 220 | 0.625000 0.625000 0 221 | 0.687500 0.625000 0 222 | 0.750000 0.625000 0 223 | 0.812500 0.625000 0 224 | 0.875000 0.625000 0 225 | 0.937500 0.625000 0 226 | 1.000000 0.625000 0 227 | 0.062500 0.500000 0 228 | 0.125000 0.500000 0 229 | 0.187500 0.500000 0 230 | 0.250000 0.500000 0 231 | 0.937500 0.375000 0 232 | 0.062500 0.250000 0 233 | 1.000000 0.375000 0 234 | 0.500000 0.250000 0 235 | 0.625000 0.250000 0 236 | 0.687500 0.375000 0 237 | 1.000000 0.000000 0 238 | 0.125000 0.875000 0 239 | 0.187500 0.875000 0 240 | 0.250000 0.875000 0 241 | 0.312500 0.875000 0 242 | 0.375000 0.875000 0 243 | 0.437500 0.875000 0 244 | 0.500000 0.875000 0 245 | 0.562500 0.875000 0 246 | 0.625000 0.875000 0 247 | 0.687500 0.875000 0 248 | 0.750000 0.875000 0 249 | 0.812500 0.875000 0 250 | 0.875000 0.875000 0 251 | 0.937500 0.875000 0 252 | 1.000000 0.875000 0 253 | 0.062500 0.750000 0 254 | 0.125000 0.750000 0 255 | 0.187500 0.750000 0 256 | 0.250000 0.750000 0 257 | 0.312500 0.750000 0 258 | 0.375000 0.750000 0 259 | 0.437500 0.750000 0 260 | 0.500000 0.750000 0 261 | 0.562500 0.750000 0 262 | 0.625000 0.750000 0 263 | 0.750000 0.250000 0 264 | 0.875000 0.250000 0 265 | 0.812500 0.250000 0 266 | 0.187500 0.250000 0 267 | -------------------------------------------------------------------------------- /Resources/Fonts/fnt_es_portrait.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daztek/EventSystem/c0055c96b81be91c99194272d6121395777578f2/Resources/Fonts/fnt_es_portrait.tga -------------------------------------------------------------------------------- /Resources/Fonts/fnt_es_portrait.txi: -------------------------------------------------------------------------------- 1 | mipmap 0 2 | filter 0 3 | downsamplemax 0 4 | downsamplemin 0 5 | numchars 127 6 | fontheight 4.000000 7 | baselineheight 4.000000 8 | texturewidth 2.560000 9 | spacingR -0.040000 10 | spacingB 0.000000 11 | upperleftcoords 127 12 | 0.000000 0.000000 0 13 | 0.000000 0.000000 0 14 | 0.000000 0.000000 0 15 | 0.000000 0.000000 0 16 | 0.000000 0.000000 0 17 | 0.000000 0.000000 0 18 | 0.000000 0.000000 0 19 | 0.000000 0.000000 0 20 | 0.000000 0.000000 0 21 | 0.000000 0.000000 0 22 | 0.000000 0.000000 0 23 | 0.000000 0.000000 0 24 | 0.000000 0.000000 0 25 | 0.000000 0.000000 0 26 | 0.000000 0.000000 0 27 | 0.000000 0.000000 0 28 | 0.312500 0.625000 0 29 | 0.000000 0.000000 0 30 | 0.000000 0.000000 0 31 | 0.000000 0.000000 0 32 | 0.000000 0.000000 0 33 | 0.000000 0.000000 0 34 | 0.000000 0.000000 0 35 | 0.000000 0.000000 0 36 | 0.000000 0.000000 0 37 | 0.000000 0.000000 0 38 | 0.000000 0.000000 0 39 | 0.000000 0.000000 0 40 | 0.000000 0.000000 0 41 | 0.000000 0.000000 0 42 | 0.000000 0.000000 0 43 | 0.000000 0.000000 0 44 | 0.250000 0.625000 0 45 | 0.375000 0.500000 0 46 | 0.875000 0.375000 0 47 | 0.250000 0.375000 0 48 | 0.312500 0.375000 0 49 | 0.375000 0.375000 0 50 | 0.500000 0.375000 0 51 | 0.500000 0.500000 0 52 | 0.187500 0.500000 0 53 | 0.562500 0.500000 0 54 | 0.312500 0.500000 0 55 | 0.625000 0.375000 0 56 | 0.062500 0.500000 0 57 | 0.750000 0.500000 0 58 | 0.937500 0.625000 0 59 | 0.062500 0.375000 0 60 | 0.687500 0.500000 0 61 | 0.375000 0.625000 0 62 | 0.437500 0.625000 0 63 | 0.500000 0.625000 0 64 | 0.562500 0.625000 0 65 | 0.625000 0.625000 0 66 | 0.687500 0.625000 0 67 | 0.750000 0.625000 0 68 | 0.812500 0.625000 0 69 | 0.875000 0.625000 0 70 | 0.250000 0.500000 0 71 | 0.125000 0.500000 0 72 | 0.937500 0.375000 0 73 | 0.812500 0.500000 0 74 | 0.000000 0.250000 0 75 | 0.437500 0.500000 0 76 | 0.187500 0.375000 0 77 | 0.625000 0.875000 0 78 | 0.687500 0.875000 0 79 | 0.750000 0.875000 0 80 | 0.812500 0.875000 0 81 | 0.875000 0.875000 0 82 | 0.937500 0.875000 0 83 | 0.000000 0.750000 0 84 | 0.062500 0.750000 0 85 | 0.125000 0.750000 0 86 | 0.187500 0.750000 0 87 | 0.250000 0.750000 0 88 | 0.312500 0.750000 0 89 | 0.375000 0.750000 0 90 | 0.437500 0.750000 0 91 | 0.500000 0.750000 0 92 | 0.562500 0.750000 0 93 | 0.625000 0.750000 0 94 | 0.687500 0.750000 0 95 | 0.750000 0.750000 0 96 | 0.812500 0.750000 0 97 | 0.875000 0.750000 0 98 | 0.937500 0.750000 0 99 | 0.000000 0.625000 0 100 | 0.062500 0.625000 0 101 | 0.125000 0.625000 0 102 | 0.187500 0.625000 0 103 | 0.875000 0.500000 0 104 | 0.000000 0.375000 0 105 | 0.937500 0.500000 0 106 | 0.437500 0.375000 0 107 | 0.562500 0.375000 0 108 | 0.625000 0.500000 0 109 | 0.000000 1.000000 0 110 | 0.062500 1.000000 0 111 | 0.125000 1.000000 0 112 | 0.187500 1.000000 0 113 | 0.250000 1.000000 0 114 | 0.312500 1.000000 0 115 | 0.375000 1.000000 0 116 | 0.437500 1.000000 0 117 | 0.500000 1.000000 0 118 | 0.562500 1.000000 0 119 | 0.625000 1.000000 0 120 | 0.687500 1.000000 0 121 | 0.750000 1.000000 0 122 | 0.812500 1.000000 0 123 | 0.875000 1.000000 0 124 | 0.937500 1.000000 0 125 | 0.000000 0.875000 0 126 | 0.062500 0.875000 0 127 | 0.125000 0.875000 0 128 | 0.187500 0.875000 0 129 | 0.250000 0.875000 0 130 | 0.312500 0.875000 0 131 | 0.375000 0.875000 0 132 | 0.437500 0.875000 0 133 | 0.500000 0.875000 0 134 | 0.562500 0.875000 0 135 | 0.687500 0.375000 0 136 | 0.812500 0.375000 0 137 | 0.750000 0.375000 0 138 | 0.125000 0.375000 0 139 | lowerrightcoords 127 140 | 0.000000 0.000000 0 141 | 0.000000 0.000000 0 142 | 0.000000 0.000000 0 143 | 0.000000 0.000000 0 144 | 0.000000 0.000000 0 145 | 0.000000 0.000000 0 146 | 0.000000 0.000000 0 147 | 0.000000 0.000000 0 148 | 0.000000 0.000000 0 149 | 0.000000 0.000000 0 150 | 0.000000 0.000000 0 151 | 0.000000 0.000000 0 152 | 0.000000 0.000000 0 153 | 0.000000 0.000000 0 154 | 0.000000 0.000000 0 155 | 0.000000 0.000000 0 156 | 0.375000 0.500000 0 157 | 0.000000 0.000000 0 158 | 0.000000 0.000000 0 159 | 0.000000 0.000000 0 160 | 0.000000 0.000000 0 161 | 0.000000 0.000000 0 162 | 0.000000 0.000000 0 163 | 0.000000 0.000000 0 164 | 0.000000 0.000000 0 165 | 0.000000 0.000000 0 166 | 0.000000 0.000000 0 167 | 0.000000 0.000000 0 168 | 0.000000 0.000000 0 169 | 0.000000 0.000000 0 170 | 0.000000 0.000000 0 171 | 0.000000 0.000000 0 172 | 0.312500 0.500000 0 173 | 0.437500 0.375000 0 174 | 0.937500 0.250000 0 175 | 0.312500 0.250000 0 176 | 0.375000 0.250000 0 177 | 0.437500 0.250000 0 178 | 0.562500 0.250000 0 179 | 0.562500 0.375000 0 180 | 0.250000 0.375000 0 181 | 0.625000 0.375000 0 182 | 0.375000 0.375000 0 183 | 0.687500 0.250000 0 184 | 0.125000 0.375000 0 185 | 0.812500 0.375000 0 186 | 1.000000 0.500000 0 187 | 0.125000 0.250000 0 188 | 0.750000 0.375000 0 189 | 0.437500 0.500000 0 190 | 0.500000 0.500000 0 191 | 0.562500 0.500000 0 192 | 0.625000 0.500000 0 193 | 0.687500 0.500000 0 194 | 0.750000 0.500000 0 195 | 0.812500 0.500000 0 196 | 0.875000 0.500000 0 197 | 0.937500 0.500000 0 198 | 0.312500 0.375000 0 199 | 0.187500 0.375000 0 200 | 1.000000 0.250000 0 201 | 0.875000 0.375000 0 202 | 0.062500 0.125000 0 203 | 0.500000 0.375000 0 204 | 0.250000 0.250000 0 205 | 0.687500 0.750000 0 206 | 0.750000 0.750000 0 207 | 0.812500 0.750000 0 208 | 0.875000 0.750000 0 209 | 0.937500 0.750000 0 210 | 1.000000 0.750000 0 211 | 0.062500 0.625000 0 212 | 0.125000 0.625000 0 213 | 0.187500 0.625000 0 214 | 0.250000 0.625000 0 215 | 0.312500 0.625000 0 216 | 0.375000 0.625000 0 217 | 0.437500 0.625000 0 218 | 0.500000 0.625000 0 219 | 0.562500 0.625000 0 220 | 0.625000 0.625000 0 221 | 0.687500 0.625000 0 222 | 0.750000 0.625000 0 223 | 0.812500 0.625000 0 224 | 0.875000 0.625000 0 225 | 0.937500 0.625000 0 226 | 1.000000 0.625000 0 227 | 0.062500 0.500000 0 228 | 0.125000 0.500000 0 229 | 0.187500 0.500000 0 230 | 0.250000 0.500000 0 231 | 0.937500 0.375000 0 232 | 0.062500 0.250000 0 233 | 1.000000 0.375000 0 234 | 0.500000 0.250000 0 235 | 0.625000 0.250000 0 236 | 0.687500 0.375000 0 237 | 1.000000 0.220000 0 238 | 0.125000 0.875000 0 239 | 0.187500 0.875000 0 240 | 0.250000 0.875000 0 241 | 0.312500 0.875000 0 242 | 0.375000 0.875000 0 243 | 0.437500 0.875000 0 244 | 0.500000 0.875000 0 245 | 0.562500 0.875000 0 246 | 0.625000 0.875000 0 247 | 0.687500 0.875000 0 248 | 0.750000 0.875000 0 249 | 0.812500 0.875000 0 250 | 0.875000 0.875000 0 251 | 0.937500 0.875000 0 252 | 1.000000 0.875000 0 253 | 0.062500 0.750000 0 254 | 0.125000 0.750000 0 255 | 0.187500 0.750000 0 256 | 0.250000 0.750000 0 257 | 0.312500 0.750000 0 258 | 0.375000 0.750000 0 259 | 0.437500 0.750000 0 260 | 0.500000 0.750000 0 261 | 0.562500 0.750000 0 262 | 0.625000 0.750000 0 263 | 0.750000 0.250000 0 264 | 0.875000 0.250000 0 265 | 0.812500 0.250000 0 266 | 0.187500 0.250000 0 267 | -------------------------------------------------------------------------------- /Resources/Fonts/fnt_es_text.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daztek/EventSystem/c0055c96b81be91c99194272d6121395777578f2/Resources/Fonts/fnt_es_text.tga -------------------------------------------------------------------------------- /Resources/Fonts/fnt_es_text.txi: -------------------------------------------------------------------------------- 1 | mipmap 0 2 | filter 0 3 | downsamplemax 0 4 | downsamplemin 0 5 | numchars 127 6 | fontheight 0.160000 7 | baselineheight 0.140000 8 | texturewidth 1.280000 9 | spacingR 0.000000 10 | spacingB 0.000000 11 | upperleftcoords 127 12 | 0.000000 0.000000 0 13 | 0.000000 0.000000 0 14 | 0.000000 0.000000 0 15 | 0.000000 0.000000 0 16 | 0.000000 0.000000 0 17 | 0.000000 0.000000 0 18 | 0.000000 0.000000 0 19 | 0.000000 0.000000 0 20 | 0.000000 0.000000 0 21 | 0.000000 0.000000 0 22 | 0.000000 0.000000 0 23 | 0.000000 0.000000 0 24 | 0.000000 0.000000 0 25 | 0.000000 0.000000 0 26 | 0.000000 0.000000 0 27 | 0.000000 0.000000 0 28 | 0.312500 0.625000 0 29 | 0.000000 0.000000 0 30 | 0.000000 0.000000 0 31 | 0.000000 0.000000 0 32 | 0.000000 0.000000 0 33 | 0.000000 0.000000 0 34 | 0.000000 0.000000 0 35 | 0.000000 0.000000 0 36 | 0.000000 0.000000 0 37 | 0.000000 0.000000 0 38 | 0.000000 0.000000 0 39 | 0.000000 0.000000 0 40 | 0.000000 0.000000 0 41 | 0.000000 0.000000 0 42 | 0.000000 0.000000 0 43 | 0.000000 0.000000 0 44 | 0.250000 0.625000 0 45 | 0.375000 0.500000 0 46 | 0.875000 0.375000 0 47 | 0.250000 0.375000 0 48 | 0.312500 0.375000 0 49 | 0.375000 0.375000 0 50 | 0.500000 0.375000 0 51 | 0.500000 0.500000 0 52 | 0.187500 0.500000 0 53 | 0.562500 0.500000 0 54 | 0.312500 0.500000 0 55 | 0.625000 0.375000 0 56 | 0.062500 0.500000 0 57 | 0.750000 0.500000 0 58 | 0.937500 0.625000 0 59 | 0.062500 0.375000 0 60 | 0.687500 0.500000 0 61 | 0.375000 0.625000 0 62 | 0.437500 0.625000 0 63 | 0.500000 0.625000 0 64 | 0.562500 0.625000 0 65 | 0.625000 0.625000 0 66 | 0.687500 0.625000 0 67 | 0.750000 0.625000 0 68 | 0.812500 0.625000 0 69 | 0.875000 0.625000 0 70 | 0.250000 0.500000 0 71 | 0.125000 0.500000 0 72 | 0.937500 0.375000 0 73 | 0.812500 0.500000 0 74 | 0.000000 0.250000 0 75 | 0.437500 0.500000 0 76 | 0.187500 0.375000 0 77 | 0.625000 0.875000 0 78 | 0.687500 0.875000 0 79 | 0.750000 0.875000 0 80 | 0.812500 0.875000 0 81 | 0.875000 0.875000 0 82 | 0.937500 0.875000 0 83 | 0.000000 0.750000 0 84 | 0.062500 0.750000 0 85 | 0.125000 0.750000 0 86 | 0.187500 0.750000 0 87 | 0.250000 0.750000 0 88 | 0.312500 0.750000 0 89 | 0.375000 0.750000 0 90 | 0.437500 0.750000 0 91 | 0.500000 0.750000 0 92 | 0.562500 0.750000 0 93 | 0.625000 0.750000 0 94 | 0.687500 0.750000 0 95 | 0.750000 0.750000 0 96 | 0.812500 0.750000 0 97 | 0.875000 0.750000 0 98 | 0.937500 0.750000 0 99 | 0.000000 0.625000 0 100 | 0.062500 0.625000 0 101 | 0.125000 0.625000 0 102 | 0.187500 0.625000 0 103 | 0.875000 0.500000 0 104 | 0.000000 0.375000 0 105 | 0.937500 0.500000 0 106 | 0.437500 0.375000 0 107 | 0.562500 0.375000 0 108 | 0.625000 0.500000 0 109 | 0.000000 1.000000 0 110 | 0.062500 1.000000 0 111 | 0.125000 1.000000 0 112 | 0.187500 1.000000 0 113 | 0.250000 1.000000 0 114 | 0.312500 1.000000 0 115 | 0.375000 1.000000 0 116 | 0.437500 1.000000 0 117 | 0.500000 1.000000 0 118 | 0.562500 1.000000 0 119 | 0.625000 1.000000 0 120 | 0.687500 1.000000 0 121 | 0.750000 1.000000 0 122 | 0.812500 1.000000 0 123 | 0.875000 1.000000 0 124 | 0.937500 1.000000 0 125 | 0.000000 0.875000 0 126 | 0.062500 0.875000 0 127 | 0.125000 0.875000 0 128 | 0.187500 0.875000 0 129 | 0.250000 0.875000 0 130 | 0.312500 0.875000 0 131 | 0.375000 0.875000 0 132 | 0.437500 0.875000 0 133 | 0.500000 0.875000 0 134 | 0.562500 0.875000 0 135 | 0.687500 0.375000 0 136 | 0.812500 0.375000 0 137 | 0.750000 0.375000 0 138 | 0.125000 0.375000 0 139 | lowerrightcoords 127 140 | 0.000000 0.000000 0 141 | 0.000000 0.000000 0 142 | 0.000000 0.000000 0 143 | 0.000000 0.000000 0 144 | 0.000000 0.000000 0 145 | 0.000000 0.000000 0 146 | 0.000000 0.000000 0 147 | 0.000000 0.000000 0 148 | 0.000000 0.000000 0 149 | 0.000000 0.000000 0 150 | 0.000000 0.000000 0 151 | 0.000000 0.000000 0 152 | 0.000000 0.000000 0 153 | 0.000000 0.000000 0 154 | 0.000000 0.000000 0 155 | 0.000000 0.000000 0 156 | 0.375000 0.500000 0 157 | 0.000000 0.000000 0 158 | 0.000000 0.000000 0 159 | 0.000000 0.000000 0 160 | 0.000000 0.000000 0 161 | 0.000000 0.000000 0 162 | 0.000000 0.000000 0 163 | 0.000000 0.000000 0 164 | 0.000000 0.000000 0 165 | 0.000000 0.000000 0 166 | 0.000000 0.000000 0 167 | 0.000000 0.000000 0 168 | 0.000000 0.000000 0 169 | 0.000000 0.000000 0 170 | 0.000000 0.000000 0 171 | 0.000000 0.000000 0 172 | 0.312500 0.500000 0 173 | 0.437500 0.375000 0 174 | 0.937500 0.250000 0 175 | 0.312500 0.250000 0 176 | 0.375000 0.250000 0 177 | 0.437500 0.250000 0 178 | 0.562500 0.250000 0 179 | 0.562500 0.375000 0 180 | 0.250000 0.375000 0 181 | 0.625000 0.375000 0 182 | 0.375000 0.375000 0 183 | 0.687500 0.250000 0 184 | 0.125000 0.375000 0 185 | 0.812500 0.375000 0 186 | 1.000000 0.500000 0 187 | 0.125000 0.250000 0 188 | 0.750000 0.375000 0 189 | 0.437500 0.500000 0 190 | 0.500000 0.500000 0 191 | 0.562500 0.500000 0 192 | 0.625000 0.500000 0 193 | 0.687500 0.500000 0 194 | 0.750000 0.500000 0 195 | 0.812500 0.500000 0 196 | 0.875000 0.500000 0 197 | 0.937500 0.500000 0 198 | 0.312500 0.375000 0 199 | 0.187500 0.375000 0 200 | 1.000000 0.250000 0 201 | 0.875000 0.375000 0 202 | 0.062500 0.125000 0 203 | 0.500000 0.375000 0 204 | 0.250000 0.250000 0 205 | 0.687500 0.750000 0 206 | 0.750000 0.750000 0 207 | 0.812500 0.750000 0 208 | 0.875000 0.750000 0 209 | 0.937500 0.750000 0 210 | 1.000000 0.750000 0 211 | 0.062500 0.625000 0 212 | 0.125000 0.625000 0 213 | 0.187500 0.625000 0 214 | 0.250000 0.625000 0 215 | 0.312500 0.625000 0 216 | 0.375000 0.625000 0 217 | 0.437500 0.625000 0 218 | 0.500000 0.625000 0 219 | 0.562500 0.625000 0 220 | 0.625000 0.625000 0 221 | 0.687500 0.625000 0 222 | 0.750000 0.625000 0 223 | 0.812500 0.625000 0 224 | 0.875000 0.625000 0 225 | 0.937500 0.625000 0 226 | 1.000000 0.625000 0 227 | 0.062500 0.500000 0 228 | 0.125000 0.500000 0 229 | 0.187500 0.500000 0 230 | 0.250000 0.500000 0 231 | 0.937500 0.375000 0 232 | 0.062500 0.250000 0 233 | 1.000000 0.375000 0 234 | 0.500000 0.250000 0 235 | 0.625000 0.250000 0 236 | 0.687500 0.375000 0 237 | 0.062500 0.875000 0 238 | 0.125000 0.875000 0 239 | 0.187500 0.875000 0 240 | 0.250000 0.875000 0 241 | 0.312500 0.875000 0 242 | 0.375000 0.875000 0 243 | 0.437500 0.875000 0 244 | 0.500000 0.875000 0 245 | 0.562500 0.875000 0 246 | 0.625000 0.875000 0 247 | 0.687500 0.875000 0 248 | 0.750000 0.875000 0 249 | 0.812500 0.875000 0 250 | 0.875000 0.875000 0 251 | 0.937500 0.875000 0 252 | 1.000000 0.875000 0 253 | 0.062500 0.750000 0 254 | 0.125000 0.750000 0 255 | 0.187500 0.750000 0 256 | 0.250000 0.750000 0 257 | 0.312500 0.750000 0 258 | 0.375000 0.750000 0 259 | 0.437500 0.750000 0 260 | 0.500000 0.750000 0 261 | 0.562500 0.750000 0 262 | 0.625000 0.750000 0 263 | 0.750000 0.250000 0 264 | 0.875000 0.250000 0 265 | 0.812500 0.250000 0 266 | 0.187500 0.250000 0 267 | -------------------------------------------------------------------------------- /Resources/cv_simdialog.dlg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Daztek/EventSystem/c0055c96b81be91c99194272d6121395777578f2/Resources/cv_simdialog.dlg --------------------------------------------------------------------------------