├── .gitignore ├── .gitmodules ├── README.md ├── docs └── events.md ├── nasher.cfg └── src ├── core ├── core_c_config.nss ├── core_i_constants.nss ├── core_i_framework.nss ├── hook_nwn.nss ├── hook_nwnx.nss ├── hook_spellhook.nss └── hook_timerhook.nss ├── demo ├── _test.nss ├── bw_defaultevents.uti.json ├── core_c_config.nss ├── creaturepalcus.itp.json ├── demo_l_plugin.nss ├── dlg_demo_poet.utc.json ├── doorpalcus.itp.json ├── encounterpalcus.itp.json ├── itempalcus.itp.json ├── module.ifo.json ├── module.jrl.json ├── placeablepalcus.itp.json ├── repute.fac.json ├── soundpalcus.itp.json ├── startingarea.are.json ├── startingarea.gic.json ├── startingarea.git.json ├── storepalcus.itp.json ├── triggerpalcus.itp.json └── waypointpalcus.itp.json └── plugins ├── chat ├── chat_c_config.nss ├── chat_i_main.nss └── chat_l_plugin.nss ├── dialogs └── dlg_l_plugin.nss ├── pqj ├── pqj_i_main.nss └── pqj_l_plugin.nss └── targeting └── target_l_plugin.nss /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore packed files 2 | *.erf 3 | *.hak 4 | *.mod 5 | 6 | # Ignore the nasher directory 7 | .nasher/ 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/sm-utils"] 2 | path = lib/sm-utils 3 | url = https://github.com/squattingmonk/sm-utils 4 | branch = master 5 | [submodule "lib/sm-dialogs"] 6 | path = lib/sm-dialogs 7 | url = https://github.com/squattingmonk/sm-dialogs 8 | branch = master 9 | [submodule "lib/nwnxee"] 10 | path = lib/nwnxee 11 | url = https://github.com/nwnxee/unified 12 | branch = master 13 | shallow = true 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Core Framework 2 | 3 | This project is a framework for managing a [Neverwinter 4 | Nights](https://neverwintervault.org) module. At the most basic, it is a set of 5 | scripts to hook all events in a module. Scripts can then subscribe to the hooks 6 | and be run when the event is triggered. This allows the module builder to 7 | modularize script systems instead of combining scripts. 8 | 9 | This system is in alpha. Things will change and will break. You have been 10 | warned. 11 | 12 | ## Prerequisites 13 | - NWN:EE >= v87.8193.34 14 | - [nwnsc](https://github.com/nwneetools/nwnsc) 15 | - [neverwinter.nim](https://github.com/niv/neverwinter.nim) >= 1.5.5 16 | - [nasher](https://github.com/squattingmonk/nasher) >= 0.20.x 17 | 18 | ## Installation 19 | Get the code: 20 | ``` 21 | git clone https://github.com/squattingmonk/nwn-core-framework.git 22 | cd nwn-core-framework 23 | git submodule update --init 24 | ``` 25 | 26 | Run the build script: 27 | ``` 28 | nasher install demo erf 29 | ``` 30 | 31 | This will create the following files in your Neverwinter Nights user directory: 32 | - `modules/core_framework.mod`: a demo module showing the framework in action 33 | (currently a barebones testing ground). 34 | - `erf/core_framework.erf`: an installable erf for use in new or existing 35 | modules. 36 | 37 | Note: `sm-utils` relies on script extensions added by 38 | [nwnsc](https://github.com/nwneetools/nwnsc). This prevents error messages when 39 | compiling with `nwnsc`, but prevents compilation in the Toolset. If you want to 40 | compile the scripts in the toolset instead, you can comment out the lines 41 | beginning with `#pragma` near the bottom of the script `util_i_library.nss`. 42 | Note that `util_i_library.nss` will still not compile on its own, since it's 43 | meant to be included in other scripts that implement its functions. 44 | 45 | ## Usage 46 | - Import `core_framework.erf` into your module. 47 | - Read and customize `core_c_config.nss`. If you make changes, be sure to 48 | recompile all scripts. 49 | - Set the module's `OnModuleLoad` event script to `hook_nwn.nss`. If you set 50 | `AUTO_HOOK_MODULE_EVENTS` in `core_c_config.nss` to `FALSE`, you will need to 51 | set all other module events to `hook_nwn.nss` as well. 52 | - Set other event scripts to `hook_nwn.nss` as you wish. You can do this 53 | manually in the toolset or by script using `HookObjectEvents()` from 54 | `core_i_framework.nss`. 55 | 56 | Note: some events may be triggered before the module loads. An example is the 57 | OnAreaEnter event being triggered by NPCs placed in the toolset. If you want to 58 | capture these, you will either have to set those event scripts to `hook_nwn.nss` 59 | manually or somehow call `InitializeCoreFramework()` from `core_i_framework.nss` 60 | before they are run (e.g., using NWNX). 61 | 62 | ## Acknowledgements 63 | This system was heavily influenced by [HCR2](https://neverwintervault.org/project/nwn1/script/hcr2-nwn1-core-framework-and-systems-final-nbde-hcr2-15) 64 | and EPOlson's [Common Scripting Framework](https://neverwintervault.org/project/nwn2/script/csf-common-scripting-framework). 65 | 66 | Huge thanks to @tinygiant98 for his continued testing and contributions. 67 | -------------------------------------------------------------------------------- /docs/events.md: -------------------------------------------------------------------------------- 1 | # Core Framework Concept: Events 2 | The Core Framework handles event management for an entire module. It will 3 | source, classify, prioritize, and run scripts for any event that can be defined. 4 | This includes base NWN events (such as `OnPlayerDeath` and `OnModuleLoad`), NWNX 5 | events (such as `NWNX_ON_REMOVE_ASSOCIATE_BEFORE`), or user-defined (say, 6 | `OnPlayerRegistered`). Scripts can subscribe to these events and be run when the 7 | event is triggered. 8 | 9 | ## Event Hook Scripts 10 | The framework intercepts game events with hook scripts. The hook script 11 | determines the event that is running and executes an event queue which calls all 12 | subscribed scripts in order of [priority](#script-priorities). 13 | 14 | The hook script for the base game events is `hook_nwn.nss`; it is placed in the 15 | script slot for all object events. The hook script for NWNX events is 16 | `hook_nwnx.nss`; it does not need to be placed in an event slot. 17 | 18 | Custom events can be triggered using the `RunEvent()` function and giving it the 19 | name of the event to run. This is how the custom events `OnHour` and 20 | `OnAreaEmpty` are handled. 21 | 22 | ## Registering Event Scripts 23 | A script can subscribe to an event using the `RegisterEventScript()` function. 24 | This function takes the [object to register the script on](#script-sources), the 25 | event to subscribe to, a [library script][libraries] to execute, and the 26 | [priority](#script-priorities) for the script. 27 | 28 | Events are referred to using a string name. For the module events, these event 29 | names are the same as the game uses (i.e., `OnModuleLoad`, `OnClientEnter`, 30 | etc.). Other objects use the object type in their name to avoid ambiguity (for 31 | example, `OnAreaEnter` and `OnTriggerEnter` refer to the game's `OnEnter` event 32 | for areas and triggers, respectively). Event names are provided for all base 33 | game events for the module, AoEs, areas, doors, encounters, placeables, stores, 34 | triggers, traps, and creatures. PCs also have their own creature events that use 35 | the prefix `OnPC*` instead of `OnCreature*`. 36 | 37 | ## Script Sources 38 | Since scripts are not placed directly into an object's event script slots, the 39 | framework needs to know what scripts should be run for an event. There are 40 | several possibilities: 41 | 42 | ### Global Event Scripts 43 | Global event scripts are those which are registered to an event by a plugin. 44 | They are called for any object when its event of that name is triggered. For 45 | example, an XP plugin might register an `OnCreatureDeath` script that rewards XP 46 | to a PC that killed the creature. That script would then fire on any creature 47 | when it dies. 48 | 49 | ### Local Event Scripts 50 | Local event scripts are those which are registered to an event by a non-plugin 51 | object. Local event scripts fire only on the objects which register them. For 52 | example, a creature might register an `OnCreatureDeath` script that causes it to 53 | explode when it dies. This script will only be called on that particular 54 | creature's death. 55 | 56 | Local event scripts are usually sourced from the object executing the event, but 57 | they can come from other objects as well. Using `AddScriptSource()`, an object 58 | can be added as a source of local event scripts for another object. For example, 59 | an area can register an `OnCreatureDeath` script that causes a dead creature to 60 | rise as a zombie. If the area is added as a script source for a creature (the 61 | framework does this during the `OnAreaEnter` event, but it can also be done 62 | manually), the creature will then execute that script when it dies. 63 | 64 | ### Tag-Based Scripts 65 | Tag-based scripting has been extended to all events instead of only module-level 66 | items events. All events execute a [library script][libraries] matching 67 | `OBJECT_SELF`'s tag. This script does not need to be registered to the event and 68 | will always be run after any registered scripts. 69 | 70 | ## Script Priorities 71 | When a script is registered to an event, it is given a priority. The priority 72 | decides the order in which scripts run when the event is triggered. Priorities 73 | range from `0.0` to `10.0`. The default priority assigned to [global event 74 | scripts](#global-event-scripts) is `5.0`, while the defailt priority assigned to 75 | [local event scripts](#local-event-scripts) is `7.0`. There are also several 76 | special priorities: 77 | 78 | - `first`: The script will always run first. If multiple scripts have this 79 | priority, they will run in the order registered. 80 | - `last`: The script will always run last. If multiple scripts have this 81 | priority, they will run in the order registered. 82 | - `only`: The script will run and no others will run afterwards. If multiple 83 | scripts have this priority, only the first one registered will run. 84 | - `default`: The script will run only if no others have run. If multiple scripts 85 | have this priority, only the first one registered will run. 86 | 87 | ## Event States 88 | Each script that runs during an event can change the state of the event using 89 | `SetEventState()`. This function takes a bitmask of three possible event states: 90 | 91 | - `EVENT_STATE_OK`: This is the default event state. During this state, event 92 | scripts will continue processing in order. 93 | - `EVENT_STATE_ABORT`: This state stops remaining scripts in the event's queue 94 | from running. 95 | - `EVENT_STATE_DENIED`: The state signals to the system that special behavior 96 | should be performed to stop the event. Handling is dependent on the event (and 97 | not all events support it). For example, the `OnClientEnter` event will boot 98 | the PC, while the `OnPlayerChat` event will suppress the chat attempt. 99 | Regardless of the event type, the `DENIED` state will prevent tag-based 100 | scripts from firing after an event queue is complete. 101 | 102 | Event states allow scripts earlier in the event's queue to prevent later scripts 103 | from firing if certain criteria are met. For example, an `OnPlayerRestStarted` 104 | script might check if the PC meets requirements for resting in an area. If not, 105 | it can set the event state to `EVENT_STATE_ABORT | EVENT_STATE_DENIED` to stop 106 | remaining `OnPlayerRestStarted` scripts from running and to stop the player from 107 | resting. 108 | 109 | [libraries]: https://github.com/squattingmonk/sm-utils/blob/master/docs/libraries.md 110 | -------------------------------------------------------------------------------- /nasher.cfg: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "Core Framework" 3 | description = "An extensible event management system for Neverwinter Nights" 4 | author = "Squatting Monk " 5 | url = "https://github.com/squattingmonk/nwn-core-framework" 6 | default = "demo" 7 | 8 | [package.sources] 9 | skipCompile = "util_i_library.nss" 10 | 11 | [package.variables] 12 | core = "src/core" 13 | plugins = "src/plugins" 14 | demo = "src/demo" 15 | sm-utils = "lib/sm-utils/src" 16 | sm-dialogs = "lib/sm-dialogs/src" 17 | nwnx = "lib/nwnxee" 18 | 19 | [target] 20 | name = "demo-nwnx" 21 | file = "core_framework.mod" 22 | description = "A demo module using NWNX" 23 | 24 | [target.sources] 25 | include = "${core}/core_i_*" 26 | include = "${core}/hook_*.nss" 27 | include = "${plugins}/**/*" 28 | include = "${demo}/**/*" 29 | include = "${sm-utils}/*" 30 | include = "${sm-dialogs}/*" 31 | include = "${nwnx}/Core/NWScript/nwnx.nss" 32 | include = "${nwnx}/Plugins/Events/NWScript/nwnx_events.nss" 33 | 34 | [target] 35 | name = "demo-nwnx-slim" 36 | parent = "demo-nwnx" 37 | description = "A slimmed-down demo module using NWNX" 38 | 39 | [target.sources] 40 | filter = "*.{nss,gic,ndb}" 41 | 42 | [target] 43 | name = "demo" 44 | parent = "demo-nwnx" 45 | description = "A demo module (no NWNX required)" 46 | 47 | [target.sources] 48 | exclude = "${nwnx}/**" 49 | exclude = "${core}/hook_nwnx.nss" 50 | 51 | [target] 52 | name = "demo-slim" 53 | parent = "demo" 54 | description = "A slimmed down demo module (no NWNX required)" 55 | 56 | [target.sources] 57 | filter = "*.{nss,gic,ndb}" 58 | 59 | [target] 60 | name = "erf-nwnx" 61 | file = "core_framework.erf" 62 | description = "An importable erf using NWNX for use in new or existing modules" 63 | 64 | [target.sources] 65 | include = "${sm-utils}/*" 66 | include = "${core}/*" 67 | include = "${nwnx}/Core/NWScript/nwnx.nss" 68 | include = "${nwnx}/Plugins/Events/NWScript/nwnx_events.nss" 69 | 70 | [target] 71 | name = "erf" 72 | parent = "erf-nwnx" 73 | description = "An importable erf for use in new or existing modules (no NWNX required)" 74 | 75 | [target.sources] 76 | exclude = "${nwnx}/**" 77 | exclude = "${core}/hook_nwnx.nss" 78 | -------------------------------------------------------------------------------- /src/core/core_c_config.nss: -------------------------------------------------------------------------------- 1 | /// ---------------------------------------------------------------------------- 2 | /// @file core_c_config.nss 3 | /// @author Michael A. Sinclair (Squatting Monk) 4 | /// @author Ed Burke (tinygiant98) 5 | /// @brief Core Framework configuration settings. 6 | /// @details 7 | /// This script contains user-definable toggles and settings for the Core 8 | /// Framework. This script is freely editable by the mod builder. All below 9 | /// constants may be overridden, but do not alter the names of the constants. 10 | /// 11 | /// Remember: any changes to this file will not be reflected in the module 12 | /// unless you recompile all scripts in which this file is included (however 13 | /// remotely). 14 | /// 15 | /// ## Acknowledgment 16 | /// The scripts contained in this package are adapted from those included in 17 | /// Edward Beck's HCR2 and EPOlson's Common Scripting Framework. 18 | /// ----------------------------------------------------------------------------- 19 | 20 | #include "util_i_debug" 21 | 22 | // ----------------------------------------------------------------------------- 23 | // Debugging 24 | // ----------------------------------------------------------------------------- 25 | 26 | /// This is a maskable setting that controls where debug messages are logged. 27 | /// Any listed destinations will have debug messages sent to them. You can 28 | /// specify multiple levels using | (e.g., DEBUG_LOG_FILE | DEBUG_LOG_DM). 29 | /// 30 | /// Possible values: 31 | /// - DEBUG_LOG_NONE: all logging is disabled 32 | /// - DEBUG_LOG_FILE: debug messages are written to the log file 33 | /// - DEBUG_LOG_DM: debug messages are sent to all online DMs 34 | /// - DEBUG_LOG_PC: debug messages are sent to the first online PC 35 | /// - DEBUG_LOG_ALL: debug messages are sent to the log files, DMs, and first PC 36 | int DEBUG_LOGGING = DEBUG_LOG_ALL; 37 | 38 | /// This is the level of debug messages to generate. This can be overriden to 39 | /// debug specific objects or events (see below). 40 | /// 41 | /// You can override this level on all events using SetDebugLevel(), or on a 42 | /// specific event using SetEventDebugLevel(). These functions can set the level 43 | /// for all objects or for a specific object. 44 | /// 45 | /// Alternatively, you can set the value on a specific object in the toolset: 46 | /// - To set the debug level for all events, add a local int named DEBUG_LEVEL 47 | /// - To set the debug level for a single event, add a local int named 48 | /// DEBUG_LEVEL_* and a local int named DEBUG_EVENT_*, where * is the name of 49 | /// the event as defined in core_i_constants.nss. 50 | /// - The value of either of these settings should be a value from 1-5 51 | /// representing one of the DEBUG_LEVEL_* constants below. 52 | /// 53 | /// The value that is used is determined as follows: 54 | /// 1. If set, the object-specific debug level for the current event is used. 55 | /// 2. If set, the global debug level for the current event is used. Otherwise... 56 | /// 3. The higher of the global or the object-specific debug level is used. 57 | /// 58 | /// This priority system is intended to allow you to reduce the amount of debug 59 | /// calls from verbose events such as heartbeats or OnCreaturePerception, which 60 | /// can make it hard to scan for useful information. 61 | /// 62 | /// Possible values: 63 | /// - DEBUG_LEVEL_CRITICAL: errors severe enough to stop the script 64 | /// - DEBUG_LEVEL_ERROR: indicates the script malfunctioned in some way 65 | /// - DEBUG_LEVEL_WARNING: indicates unexpected behavior may occur 66 | /// - DEBUG_LEVEL_NOTICE: information to track the flow of functions 67 | /// - DEBUG_LEVEL_DEBUG: data dumps used for debugging 68 | const int DEFAULT_DEBUG_LEVEL = DEBUG_LEVEL_ERROR; 69 | 70 | /// This controls the level of debug messages to generate on heartbeat events. 71 | /// This can be used to prevent the excessive generation of debug messages that 72 | /// may clutter the log. You may override this on an event-by-event basis using 73 | /// SetEventDebugLevel(). 74 | /// 75 | /// Possible values: 76 | /// - DEBUG_LEVEL_NONE: use the object or module default level 77 | /// - DEBUG_LEVEL_CRITICAL: errors severe enough to stop the script 78 | /// - DEBUG_LEVEL_ERROR: indicates the script malfunctioned in some way 79 | /// - DEBUG_LEVEL_WARNING: indicates unexpected behavior may occur 80 | /// - DEBUG_LEVEL_NOTICE: information to track the flow of functions 81 | /// - DEBUG_LEVEL_DEBUG: data dumps used for debugging 82 | const int HEARTBEAT_DEBUG_LEVEL = DEBUG_LEVEL_ERROR; 83 | 84 | /// This is the level of debug messages to generate when OnCreaturePerception 85 | /// fires. This can be used to prevent the excessive generation of debug 86 | /// messages that may clutter the log. You may override this on an 87 | /// object-by-object basis using SetEventDebugLevel(). 88 | /// 89 | /// Possible values: 90 | /// - DEBUG_LEVEL_NONE: use the object or module default level 91 | /// - DEBUG_LEVEL_CRITICAL: errors severe enough to stop the script 92 | /// - DEBUG_LEVEL_ERROR: indicates the script malfunctioned in some way 93 | /// - DEBUG_LEVEL_WARNING: indicates unexpected behavior may occur 94 | /// - DEBUG_LEVEL_NOTICE: information to track the flow of functions 95 | /// - DEBUG_LEVEL_DEBUG: data dumps used for debugging 96 | const int PERCEPTION_DEBUG_LEVEL = DEBUG_LEVEL_ERROR; 97 | 98 | /// This is the level of debug messages to generate when the framework is 99 | /// initializing. To prevent excessive logging during initialization, set this 100 | /// to a lower level than DEFAULT_DEBUG_LEVEL above. Once framework 101 | /// initialization is complete, module debug level will revert to 102 | /// DEFAULT_DEBUG_LEVEL 103 | const int INITIALIZATION_DEBUG_LEVEL = DEBUG_LEVEL_DEBUG; 104 | 105 | // ----------------------------------------------------------------------------- 106 | // Library and Plugin Management 107 | // ----------------------------------------------------------------------------- 108 | 109 | /// This is a comma-separated list of glob patterns matching libraries that 110 | /// should be automatically loaded when the Core Framework is initialized. The 111 | /// libraries will be loaded in the order of the pattern they matched. Multiple 112 | /// libraries matching the same pattern will be loaded in alphabetical order. 113 | /// 114 | /// The following glob syntax is supported: 115 | /// - `*`: match zero or more characters 116 | /// - `?`: match a single character 117 | /// - `[abc]`: match any of a, b, or c 118 | /// - `[a-z]`: match any character from a-z 119 | /// Other text is matched literally, so using exact script names is okay. 120 | const string INSTALLED_LIBRARIES = "*_l_plugin"; 121 | 122 | /// This is a comma-separated list of plugins that should be activated when the 123 | /// Core Framework is initialized. If this list is empty, all plugins discovered 124 | /// in INSTALLED_LIBRARIES above will be automatically activated. If plugins 125 | /// are specified here, *only* the listed plugins will be activated. 126 | const string INSTALLED_PLUGINS = ""; 127 | 128 | // ----------------------------------------------------------------------------- 129 | // Event Management 130 | // ----------------------------------------------------------------------------- 131 | 132 | /// These settings control the order in which event hook-ins run. Event hook-ins 133 | /// get sorted by their priority: a floating point number between 0.0 and 10.0. 134 | /// While you can specify a priority for a hook in the same variable that calls 135 | /// it, you can set a default priority here to avoid having to repeatedly set 136 | /// priorities. 137 | /// 138 | /// Event hook-ins are sorted into global and local types: 139 | /// - Global event hook-ins are defined by an installed plugin. They are called 140 | /// whenever a particular event is triggered. 141 | /// - Local event hook-ins are defined on a particular object, such as a 142 | /// creature or placeable, or on the area or persistent object (such as a 143 | /// trigger or AoE) the object is in. 144 | /// By default, local scripts have priority over global scripts. You can change 145 | /// this for all scripts here or set the priorities of scripts in the object 146 | /// variables on a case-by-case basis. 147 | 148 | /// This is the default priority for global event hook-in scripts (i.e., on a 149 | /// plugin object) that do not have a priority explicitly set. It can be a 150 | /// value from 0.0 - 10.0 (where a higher priority = earlier run time). If you 151 | /// set this to a negative number, hook-in scripts with no explicit priority will 152 | /// not run (not recommended). 153 | /// Default value: 5.0 154 | const float GLOBAL_EVENT_PRIORITY = 5.0; 155 | 156 | /// This is the default priority for local event hook-in scripts (i.e., set on 157 | /// an object besides a plugin) that do not have a priority explicitly assigned. 158 | /// This can be a value from 0.0 - 10.0 (where a higher priority = earlier run 159 | /// time). If you set this to a negative number, local hook-in scripts with no 160 | /// explicit priority will not run (not recommended). It is recommended that you 161 | /// set this higher than the value of GLOBAL_EVENT_PRIORITY. This ensures local 162 | /// event scripts will run before most globally defined scripts. 163 | /// Default value: 7.0 164 | const float LOCAL_EVENT_PRIORITY = 7.0; 165 | 166 | /// This controls whether the Core handles tag-based scripting on its own. If 167 | /// this is TRUE, tag-based scripts will be called as library scripts rather 168 | /// than stand-alone scripts, allowing you to greatly reduce the number of 169 | /// tag-based scripts in the module. If you have traditional tag-based scripts, 170 | /// those will continue to work. The only reason you might want to turn this off 171 | /// is to completely disable tag-based scripting or to use a plugin to call the 172 | /// desired scripts (e.g., make a plugin for the BioWare X2 functions, which 173 | /// handle tag-based scripting on their own). 174 | /// Default value: TRUE 175 | const int ENABLE_TAGBASED_SCRIPTS = TRUE; 176 | 177 | /// If TRUE, this will cause all event handlers for the module to be set to 178 | /// "hook_nwn" when the Core Framework is initialized. Any existing event 179 | /// scripts will be set as local event scripts and will still fire when the 180 | /// event is triggered. 181 | const int AUTO_HOOK_MODULE_EVENTS = TRUE; 182 | 183 | /// If TRUE, this will cause all event handlers for all areas in the module to 184 | /// be set to "hook_nwn" when the Core Framework is initialized. Any existing 185 | /// event scripts will be set as local event scripts and will still fire when 186 | /// the event is triggered. 187 | /// @note You can skip auto-hooking an individual area by setting a local int 188 | /// named `SKIP_AUTO_HOOK` to TRUE on it. 189 | /// @note Areas spawned by script after the Core Framework is initialized will 190 | /// not have the handlers set. 191 | const int AUTO_HOOK_AREA_EVENTS = TRUE; 192 | 193 | /// This controls whether the OnHeartbeat event is hooked when automatically 194 | /// hooking area events during initialization. Has no effect if 195 | /// AUTO_HOOK_AREA_EVENTS is FALSE. 196 | const int AUTO_HOOK_AREA_HEARTBEAT_EVENT = FALSE; 197 | 198 | /// This is a bitmasked value matching object types that should have their event 199 | /// handlers changed to "hook_nwn" when the Core Framework is initialized. Any 200 | /// existing event scripts will be set as local event scripts and will still 201 | /// fire when the event is triggered. You can add multiple types using the `|` 202 | /// operator (e.g., OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE). To hook all 203 | /// eligible objects, set this to OBJECT_TYPE_ALL. To disable hooking for all 204 | /// objects, set this to 0. 205 | /// @note You can skip auto-hooking an individual object by setting a local int 206 | /// named `SKIP_AUTO_HOOK` to TRUE on it. 207 | /// @note Objects spawned by script after the Core Framework is initialized will 208 | /// not have the handlers set. 209 | int AUTO_HOOK_OBJECT_EVENTS = OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE; 210 | 211 | /// This controls whether the OnHeartbeat event is hooked when automatically 212 | /// hooking objects during initialization. It is a bitmasked value matching the 213 | /// types that should have their heartbeat events hooked. To enable heartbeat 214 | /// hooking for all eligible objects, set this to OBJECT_TYPE_ALL. To disable 215 | /// heartbeat hooking for all objects, set this to 0. 216 | int AUTO_HOOK_OBJECT_HEARTBEAT_EVENT = 0; 217 | 218 | /// If TRUE, this will cause all of a PC's event scripts to be set to "hook_nwn" 219 | /// OnClientEnter. Existing event scripts (usually "default") are not preserved. 220 | const int AUTO_HOOK_PC_EVENTS = TRUE; 221 | 222 | /// This controls whether the OnHeartbeat event is hooked when automatically 223 | /// hooking PC events OnClientEnter. If AUTO_HOOK_PC_EVENTS is FALSE, this will 224 | /// have no effect. 225 | const int AUTO_HOOK_PC_HEARTBEAT_EVENT = FALSE; 226 | 227 | // ----------------------------------------------------------------------------- 228 | // Custom Events 229 | // ----------------------------------------------------------------------------- 230 | 231 | /// This toggles whether to allow the OnHour event. If this is TRUE, the OnHour 232 | /// event will execute each time the hour changes. 233 | const int ENABLE_ON_HOUR_EVENT = TRUE; 234 | 235 | /// This toggles whether the OnAreaEmpty event runs. If this is TRUE, the 236 | /// OnAreaEmpty event will run on an area ON_AREA_EMPTY_EVENT_DELAY seconds 237 | /// after the last PC exists the area. This is a good event for area cleanup 238 | /// scripts. 239 | const int ENABLE_ON_AREA_EMPTY_EVENT = TRUE; 240 | 241 | /// This is the number of seconds after an area is emptied of players to run the 242 | /// OnAreaEmpty scripts for that area. 243 | /// Default value: 180.0 (3 real-life minutes) 244 | const float ON_AREA_EMPTY_EVENT_DELAY = 180.0; 245 | 246 | // ----------------------------------------------------------------------------- 247 | // Miscellaneous 248 | // ----------------------------------------------------------------------------- 249 | 250 | /// This is the script that will run before the framework initializes the first 251 | /// time. An empty string means no script will run. 252 | const string ON_MODULE_PRELOAD = ""; 253 | 254 | /// When using AOE hook scripts, NPCs can be added to the AOE roster for easier 255 | /// access during scripting. To only allow PC objects on the AOE rosters, set 256 | /// this to FALSE. 257 | const int INCLUDE_NPC_IN_AOE_ROSTER = TRUE; 258 | 259 | /// This is the welcome message that will be sent to all players and DMs that 260 | /// log into the module. 261 | const string WELCOME_MESSAGE = "Welcome to the Core Framework."; 262 | -------------------------------------------------------------------------------- /src/core/core_i_constants.nss: -------------------------------------------------------------------------------- 1 | /// ---------------------------------------------------------------------------- 2 | /// @file core_i_constants.nss 3 | /// @author Michael A. Sinclair (Squatting Monk) 4 | /// @brief Constants commonly used throughout the Core and associated systems. 5 | /// ---------------------------------------------------------------------------- 6 | 7 | #include "util_i_datapoint" 8 | 9 | // ----------------------------------------------------------------------------- 10 | // Blueprints 11 | // ----------------------------------------------------------------------------- 12 | 13 | // Data structures 14 | const string CORE_EVENTS = "Core Events"; 15 | const string CORE_PLUGINS = "Core Plugins"; 16 | 17 | // Script names 18 | const string CORE_HOOK_NWN = "hook_nwn"; 19 | const string CORE_HOOK_NWNX = "hook_nwnx"; 20 | const string CORE_HOOK_SPELLS = "hook_spellhook"; 21 | const string CORE_HOOK_TIMERS = "hook_timerhook"; 22 | 23 | // ----------------------------------------------------------------------------- 24 | // Global Variables 25 | // ----------------------------------------------------------------------------- 26 | 27 | // If these objects do not exist, they will be initialized OnModuleLoad. 28 | object PLUGINS = GetDatapoint(CORE_PLUGINS); 29 | object EVENTS = GetDatapoint(CORE_EVENTS); 30 | 31 | // ----------------------------------------------------------------------------- 32 | // Framework Variables 33 | // ----------------------------------------------------------------------------- 34 | 35 | const string CORE_INITIALIZED = "CORE_INITIALIZED"; 36 | 37 | // Set on an object to prevent auto-hooking during Core initialization. 38 | const string SKIP_AUTO_HOOK = "SKIP_AUTO_HOOK"; 39 | 40 | // ----- Plugin Management ----------------------------------------------------- 41 | 42 | // Local variable names used for plugin objects. 43 | const string PLUGIN_ID = "*ID"; 44 | const string PLUGIN_LIBRARIES = "*Libraries"; 45 | const string PLUGIN_STATUS = "*Status"; 46 | 47 | // Acceptable values for the plugin's activation status. 48 | const int PLUGIN_STATUS_MISSING = -1; 49 | const int PLUGIN_STATUS_OFF = 0; 50 | const int PLUGIN_STATUS_ON = 1; 51 | 52 | // The last plugin to run 53 | const string PLUGIN_LAST = "PLUGIN_LAST"; 54 | 55 | // ----- Event Management ------------------------------------------------------ 56 | 57 | // Used to distinguish `EVENT_SCRIPT_*` constants 58 | const int EVENT_TYPE_MODULE = 3; 59 | const int EVENT_TYPE_AREA = 4; 60 | const int EVENT_TYPE_CREATURE = 5; 61 | const int EVENT_TYPE_TRIGGER = 7; 62 | const int EVENT_TYPE_PLACEABLE = 9; 63 | const int EVENT_TYPE_DOOR = 10; 64 | const int EVENT_TYPE_AREAOFEFFECT = 11; 65 | const int EVENT_TYPE_ENCOUNTER = 13; 66 | const int EVENT_TYPE_STORE = 14; 67 | 68 | const string EVENT_NAME = "EVENT_NAME"; // Name of the event the script should run on. 69 | const string EVENT_SOURCE = "EVENT_SOURCE"; // List of sources for location hooks 70 | const string EVENT_PLUGIN = "EVENT_PLUGIN"; // List of plugins installed 71 | const string EVENT_CURRENT_PLUGIN = "EVENT_CURRENT_PLUGIN"; // Name of the plugin owning the current event script 72 | const string EVENT_SOURCE_BLACKLIST = "EVENT_SOURCE_BLACKLIST"; // List of blacklisted plugins or objects 73 | const string EVENT_TRIGGERED = "EVENT_TRIGGERED"; // The object triggering the event 74 | const string EVENT_LAST = "EVENT_LAST"; // The last event to run 75 | const string EVENT_DEBUG = "EVENT_DEBUG"; // The event's debug level 76 | 77 | const string EVENT_STATE = "EVENT_STATE"; // State of the event queue 78 | const int EVENT_STATE_OK = 0x00; // normal (default) 79 | const int EVENT_STATE_ABORT = 0x01; // stops further event queue processing 80 | const int EVENT_STATE_DENIED = 0x02; // request denied 81 | 82 | const string EVENT_PRIORITY = "EVENT_PRIORITY"; // List of event script priorities 83 | const float EVENT_PRIORITY_FIRST = 9999.0; // The script is always first 84 | const float EVENT_PRIORITY_LAST = -9999.0; // The script is always last 85 | const float EVENT_PRIORITY_ONLY = 11111.0; // The script will be the only one to execute 86 | const float EVENT_PRIORITY_DEFAULT = -11111.0; // The script will only execute if no other scripts do 87 | 88 | // ----- Timer Management ------------------------------------------------------ 89 | 90 | const string TIMER_ON_AREA_EMPTY = "TIMER_ON_AREA_EMPTY"; // Timer variable name for OnAreaExit Timer 91 | 92 | // ----- Player Management ----------------------------------------------------- 93 | 94 | const string PC_CD_KEY = "PC_CD_KEY"; 95 | const string PC_PLAYER_NAME = "PC_PLAYER_NAME"; 96 | const string PLAYER_ROSTER = "PLAYER_ROSTER"; 97 | const string DM_ROSTER = "DM_ROSTER"; 98 | const string LOGIN_BOOT = "LOGIN_BOOT"; 99 | const string LOGIN_DEATH = "LOGIN_DEATH"; 100 | const string AREA_ROSTER = "AREA_ROSTER"; 101 | const string AOE_ROSTER = "AOE_ROSTER"; 102 | const string IS_PC = "IS_PC"; 103 | const string IS_DM = "IS_DM"; 104 | 105 | // ----- Miscellaneous --------------------------------------------------------- 106 | 107 | const string CURRENT_HOUR = "CURRENT_HOUR"; 108 | 109 | // ----------------------------------------------------------------------------- 110 | // Event Names 111 | // ----------------------------------------------------------------------------- 112 | 113 | // ----- Module Events --------------------------------------------------------- 114 | 115 | const string MODULE_EVENT_ON_ACQUIRE_ITEM = "OnAcquireItem"; 116 | const string MODULE_EVENT_ON_ACTIVATE_ITEM = "OnActivateItem"; 117 | const string MODULE_EVENT_ON_CLIENT_ENTER = "OnClientEnter"; 118 | const string MODULE_EVENT_ON_CLIENT_LEAVE = "OnClientLeave"; 119 | const string MODULE_EVENT_ON_CUTSCENE_ABORT = "OnCutSceneAbort"; 120 | const string MODULE_EVENT_ON_HEARTBEAT = "OnHeartbeat"; 121 | const string MODULE_EVENT_ON_MODULE_LOAD = "OnModuleLoad"; 122 | const string MODULE_EVENT_ON_MODULE_START = "OnModuleStart"; 123 | const string MODULE_EVENT_ON_NUI = "OnNUI"; 124 | const string MODULE_EVENT_ON_PLAYER_CHAT = "OnPlayerChat"; 125 | const string MODULE_EVENT_ON_PLAYER_DEATH = "OnPlayerDeath"; 126 | const string MODULE_EVENT_ON_PLAYER_DYING = "OnPlayerDying"; 127 | const string MODULE_EVENT_ON_PLAYER_EQUIP_ITEM = "OnPlayerEquipItem"; 128 | const string MODULE_EVENT_ON_PLAYER_GUI = "OnPlayerGUI"; 129 | const string MODULE_EVENT_ON_PLAYER_LEVEL_UP = "OnPlayerLevelUp"; 130 | const string MODULE_EVENT_ON_PLAYER_RESPAWN = "OnPlayerReSpawn"; 131 | const string MODULE_EVENT_ON_PLAYER_REST = "OnPlayerRest"; 132 | const string MODULE_EVENT_ON_PLAYER_REST_STARTED = "OnPlayerRestStarted"; 133 | const string MODULE_EVENT_ON_PLAYER_REST_CANCELLED = "OnPlayerRestCancelled"; 134 | const string MODULE_EVENT_ON_PLAYER_REST_FINISHED = "OnPlayerRestFinished"; 135 | const string MODULE_EVENT_ON_PLAYER_TARGET = "OnPlayerTarget"; 136 | const string MODULE_EVENT_ON_PLAYER_TILE_ACTION = "OnPlayerTileAction"; 137 | const string MODULE_EVENT_ON_PLAYER_UNEQUIP_ITEM = "OnPlayerUnEquipItem"; 138 | const string MODULE_EVENT_ON_UNACQUIRE_ITEM = "OnUnAcquireItem"; 139 | const string MODULE_EVENT_ON_USER_DEFINED = "OnUserDefined"; 140 | 141 | // These are pseudo-events called by the Core Framework 142 | const string MODULE_EVENT_ON_SPELLHOOK = "OnSpellhook"; 143 | const string MODULE_EVENT_ON_HOUR = "OnHour"; 144 | 145 | // ----- Area Events ----------------------------------------------------------- 146 | 147 | const string AREA_EVENT_ON_ENTER = "OnAreaEnter"; 148 | const string AREA_EVENT_ON_EXIT = "OnAreaExit"; 149 | const string AREA_EVENT_ON_HEARTBEAT = "OnAreaHeartbeat"; 150 | const string AREA_EVENT_ON_USER_DEFINED = "OnAreaUserDefined"; 151 | 152 | // These are pseudo-events called by the Core Framework 153 | const string AREA_EVENT_ON_EMPTY = "OnAreaEmpty"; 154 | 155 | // ----- Area of Effect Events ------------------------------------------------- 156 | 157 | const string AOE_EVENT_ON_ENTER = "OnAoEEnter"; 158 | const string AOE_EVENT_ON_EXIT = "OnAoEExit"; 159 | const string AOE_EVENT_ON_HEARTBEAT = "OnAoEHeartbeat"; 160 | const string AOE_EVENT_ON_USER_DEFINED = "OnAoEUserDefined"; 161 | 162 | // These are pseudo-events called by the Core Framework 163 | const string AOE_EVENT_ON_EMPTY = "OnAoEEmpty"; 164 | 165 | // ----- Creature Events ------------------------------------------------------- 166 | 167 | const string CREATURE_EVENT_ON_BLOCKED = "OnCreatureBlocked"; 168 | const string CREATURE_EVENT_ON_COMBAT_ROUND_END = "OnCreatureCombatRoundEnd"; 169 | const string CREATURE_EVENT_ON_CONVERSATION = "OnCreatureConversation"; 170 | const string CREATURE_EVENT_ON_DAMAGED = "OnCreatureDamaged"; 171 | const string CREATURE_EVENT_ON_DEATH = "OnCreatureDeath"; 172 | const string CREATURE_EVENT_ON_DISTURBED = "OnCreatureDisturbed"; 173 | const string CREATURE_EVENT_ON_HEARTBEAT = "OnCreatureHeartbeat"; 174 | const string CREATURE_EVENT_ON_PERCEPTION = "OnCreaturePerception"; 175 | const string CREATURE_EVENT_ON_PHYSICAL_ATTACKED = "OnCreaturePhysicalAttacked"; 176 | const string CREATURE_EVENT_ON_RESTED = "OnCreatureRested"; 177 | const string CREATURE_EVENT_ON_SPAWN = "OnCreatureSpawn"; 178 | const string CREATURE_EVENT_ON_SPELL_CAST_AT = "OnCreatureSpellCastAt"; 179 | const string CREATURE_EVENT_ON_USER_DEFINED = "OnCreatureUserDefined"; 180 | 181 | // PC versions of the above. All work except for OnPCRested and OnPCSpawn. See 182 | // https://nwnlexicon.com/index.php?title=SetEventScript#Remarks for details. 183 | const string PC_EVENT_ON_BLOCKED = "OnPCBlocked"; 184 | const string PC_EVENT_ON_COMBAT_ROUND_END = "OnPCCombatRoundEnd"; 185 | const string PC_EVENT_ON_CONVERSATION = "OnPCConversation"; 186 | const string PC_EVENT_ON_DAMAGED = "OnPCDamaged"; 187 | const string PC_EVENT_ON_DEATH = "OnPCDeath"; 188 | const string PC_EVENT_ON_DISTURBED = "OnPCDisturbed"; 189 | const string PC_EVENT_ON_HEARTBEAT = "OnPCHeartbeat"; 190 | const string PC_EVENT_ON_PERCEPTION = "OnPCPerception"; 191 | const string PC_EVENT_ON_PHYSICAL_ATTACKED = "OnPCPhysicalAttacked"; 192 | const string PC_EVENT_ON_RESTED = "OnPCRested"; 193 | const string PC_EVENT_ON_SPAWN = "OnPCSpawn"; 194 | const string PC_EVENT_ON_SPELL_CAST_AT = "OnPCSpellCastAt"; 195 | const string PC_EVENT_ON_USER_DEFINED = "OnPCUserDefined"; 196 | 197 | // ----- Door Events ----------------------------------------------------------- 198 | 199 | const string DOOR_EVENT_ON_AREA_TRANSITION_CLICK = "OnDoorAreaTransitionClick"; 200 | const string DOOR_EVENT_ON_CLOSE = "OnDoorClose"; 201 | const string DOOR_EVENT_ON_CONVERSATION = "OnDoorConversation"; 202 | const string DOOR_EVENT_ON_DAMAGED = "OnDoorDamaged"; 203 | const string DOOR_EVENT_ON_DEATH = "OnDoorDeath"; 204 | const string DOOR_EVENT_ON_FAIL_TO_OPEN = "OnDoorFailToOpen"; 205 | const string DOOR_EVENT_ON_HEARTBEAT = "OnDoorHeartbeat"; 206 | const string DOOR_EVENT_ON_LOCK = "OnDoorLock"; 207 | const string DOOR_EVENT_ON_OPEN = "OnDoorOpen"; 208 | const string DOOR_EVENT_ON_PHYSICAL_ATTACKED = "OnDoorPhysicalAttacked"; 209 | const string DOOR_EVENT_ON_SPELL_CAST_AT = "OnDoorSpellCastAt"; 210 | const string DOOR_EVENT_ON_UNLOCK = "OnDoorUnLock"; 211 | const string DOOR_EVENT_ON_USER_DEFINED = "OnDoorUserDefined"; 212 | 213 | // ----- Encounter Events ------------------------------------------------------ 214 | 215 | const string ENCOUNTER_EVENT_ON_ENTER = "OnEncounterEnter"; 216 | const string ENCOUNTER_EVENT_ON_EXHAUSTED = "OnEncounterExhausted"; 217 | const string ENCOUNTER_EVENT_ON_EXIT = "OnEncounterExit"; 218 | const string ENCOUNTER_EVENT_ON_HEARTBEAT = "OnEncounterHeartbeat"; 219 | const string ENCOUNTER_EVENT_ON_USER_DEFINED = "OnEncounterUserDefined"; 220 | 221 | // ----- Placeable Events ------------------------------------------------------ 222 | 223 | const string PLACEABLE_EVENT_ON_CLICK = "OnPlaceableClick"; 224 | const string PLACEABLE_EVENT_ON_CLOSE = "OnPlaceableClose"; 225 | const string PLACEABLE_EVENT_ON_CONVERSATION = "OnPlaceableConversation"; 226 | const string PLACEABLE_EVENT_ON_DAMAGED = "OnPlaceableDamaged"; 227 | const string PLACEABLE_EVENT_ON_DEATH = "OnPlaceableDeath"; 228 | const string PLACEABLE_EVENT_ON_DISTURBED = "OnPlaceableDisturbed"; 229 | const string PLACEABLE_EVENT_ON_HEARTBEAT = "OnPlaceableHeartbeat"; 230 | const string PLACEABLE_EVENT_ON_LOCK = "OnPlaceableLock"; 231 | const string PLACEABLE_EVENT_ON_PHYSICAL_ATTACKED = "OnPlaceablePhysicalAttacked"; 232 | const string PLACEABLE_EVENT_ON_OPEN = "OnPlaceableOpen"; 233 | const string PLACEABLE_EVENT_ON_SPELL_CAST_AT = "OnPlaceableSpellCastAt"; 234 | const string PLACEABLE_EVENT_ON_UNLOCK = "OnPlaceableUnLock"; 235 | const string PLACEABLE_EVENT_ON_USED = "OnPlaceableUsed"; 236 | const string PLACEABLE_EVENT_ON_USER_DEFINED = "OnPlaceableUserDefined"; 237 | 238 | // ----- Store Events ---------------------------------------------------------- 239 | 240 | const string STORE_EVENT_ON_OPEN = "OnStoreOpen"; 241 | const string STORE_EVENT_ON_CLOSE = "OnStoreClose"; 242 | 243 | // ----- Trap Events ----------------------------------------------------------- 244 | 245 | const string TRAP_EVENT_ON_DISARM = "OnTrapDisarm"; 246 | const string TRAP_EVENT_ON_TRIGGERED = "OnTrapTriggered"; 247 | 248 | // ----- Trigger Events -------------------------------------------------------- 249 | 250 | const string TRIGGER_EVENT_ON_CLICK = "OnTriggerClick"; 251 | const string TRIGGER_EVENT_ON_ENTER = "OnTriggerEnter"; 252 | const string TRIGGER_EVENT_ON_EXIT = "OnTriggerExit"; 253 | const string TRIGGER_EVENT_ON_HEARTBEAT = "OnTriggerHeartbeat"; 254 | const string TRIGGER_EVENT_ON_USER_DEFINED = "OnTriggerUserDefined"; 255 | 256 | // ----- Plugin Events --------------------------------------------------------- 257 | 258 | // These are pseudo-events called by the Core Framework. 259 | const string PLUGIN_EVENT_ON_ACTIVATE = "OnPluginActivate"; 260 | const string PLUGIN_EVENT_ON_DEACTIVATE = "OnPluginDeactivate"; 261 | -------------------------------------------------------------------------------- /src/core/hook_nwnx.nss: -------------------------------------------------------------------------------- 1 | /// ---------------------------------------------------------------------------- 2 | /// @file hook_nwnx.nss 3 | /// @author Michael A. Sinclair (Squatting Monk) 4 | /// @brief NWNX event hook-in script. Runs event queues for events generated by 5 | /// nwnx_events. Does not need to be placed in a slot. 6 | /// ---------------------------------------------------------------------------- 7 | 8 | #include "core_i_framework" 9 | #include "nwnx_events" 10 | 11 | void main() 12 | { 13 | string sEvent = GetScriptParam(EVENT_NAME); 14 | if (sEvent != "") 15 | NWNX_Events_SubscribeEvent(sEvent, CORE_HOOK_NWNX); 16 | else 17 | RunEvent(NWNX_Events_GetCurrentEvent()); 18 | } 19 | -------------------------------------------------------------------------------- /src/core/hook_spellhook.nss: -------------------------------------------------------------------------------- 1 | /// ---------------------------------------------------------------------------- 2 | /// @file hook_spellhook.nss 3 | /// @author Michael A. Sinclair (Squatting Monk) 4 | /// @brief OnSpellhook event script. 5 | /// ---------------------------------------------------------------------------- 6 | 7 | #include "core_i_framework" 8 | #include "x2_inc_switches" 9 | 10 | void main() 11 | { 12 | int nState = RunEvent(MODULE_EVENT_ON_SPELLHOOK); 13 | 14 | // The DENIED state stops the spell from executing 15 | if (nState & EVENT_STATE_DENIED) 16 | SetModuleOverrideSpellScriptFinished(); 17 | else 18 | { 19 | // Handle the special case of casting a spell at an item 20 | object oItem = GetSpellTargetObject(); 21 | 22 | if (GetObjectType(oItem) == OBJECT_TYPE_ITEM) 23 | { 24 | string sTag = GetTag(oItem); 25 | SetUserDefinedItemEventNumber(X2_ITEM_EVENT_SPELLCAST_AT); 26 | RunLibraryScript(sTag); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/core/hook_timerhook.nss: -------------------------------------------------------------------------------- 1 | /// ---------------------------------------------------------------------------- 2 | /// @file hook_timerhook.nss 3 | /// @author Michael A. Sinclair (Squatting Monk) 4 | /// @brief Hook script that handles timers as Core Framework events. 5 | /// ---------------------------------------------------------------------------- 6 | 7 | #include "core_i_framework" 8 | 9 | void main() 10 | { 11 | string sEvent = GetScriptParam(TIMER_ACTION); 12 | string sSource = GetScriptParam(TIMER_SOURCE); 13 | object oSource = StringToObject(sSource); 14 | RunEvent(sEvent, oSource); 15 | } 16 | -------------------------------------------------------------------------------- /src/demo/_test.nss: -------------------------------------------------------------------------------- 1 | #include "pqj_i_main" 2 | #include "core_i_framework" 3 | 4 | void main() 5 | { 6 | object oPC = GetLastUsedBy(); 7 | int nState = pqj_GetQuestState("test", oPC); 8 | if (nState > 1) 9 | pqj_RemoveJournalQuestEntry("test", oPC); 10 | else 11 | pqj_AddJournalQuestEntry("test", nState + 1, oPC); 12 | 13 | int nTimer = CreateTimer(oPC, "TestTimer", 6.0f, 4); 14 | StartTimer(nTimer); 15 | DelayCommand(12.0, StopTimer(nTimer)); 16 | DelayCommand(24.0, KillTimer(nTimer)); 17 | } 18 | -------------------------------------------------------------------------------- /src/demo/bw_defaultevents.uti.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "UTI ", 3 | "AddCost": { 4 | "type": "dword", 5 | "value": 0 6 | }, 7 | "BaseItem": { 8 | "type": "int", 9 | "value": 24 10 | }, 11 | "Charges": { 12 | "type": "byte", 13 | "value": 0 14 | }, 15 | "Comment": { 16 | "type": "cexostring", 17 | "value": "This is a template for a data item used by the Core Framework." 18 | }, 19 | "Cost": { 20 | "type": "dword", 21 | "value": 0 22 | }, 23 | "Cursed": { 24 | "type": "byte", 25 | "value": 0 26 | }, 27 | "DescIdentified": { 28 | "type": "cexolocstring", 29 | "value": { 30 | "0": "This plugin supplies the default BioWare events for the module and creature object types." 31 | } 32 | }, 33 | "Description": { 34 | "type": "cexolocstring", 35 | "value": {} 36 | }, 37 | "Identified": { 38 | "type": "byte", 39 | "value": 1 40 | }, 41 | "LocalizedName": { 42 | "type": "cexolocstring", 43 | "value": { 44 | "0": "[Plugin] Default BioWare Events" 45 | } 46 | }, 47 | "ModelPart1": { 48 | "type": "byte", 49 | "value": 1 50 | }, 51 | "PaletteID": { 52 | "type": "byte", 53 | "value": 0 54 | }, 55 | "Plot": { 56 | "type": "byte", 57 | "value": 0 58 | }, 59 | "PropertiesList": { 60 | "type": "list", 61 | "value": [] 62 | }, 63 | "StackSize": { 64 | "type": "word", 65 | "value": 1 66 | }, 67 | "Stolen": { 68 | "type": "byte", 69 | "value": 1 70 | }, 71 | "Tag": { 72 | "type": "cexostring", 73 | "value": "bw_defaultevents" 74 | }, 75 | "TemplateResRef": { 76 | "type": "resref", 77 | "value": "bw_defaultevents" 78 | }, 79 | "VarTable": { 80 | "type": "list", 81 | "value": [ 82 | { 83 | "__struct_id": 0, 84 | "Name": { 85 | "type": "cexostring", 86 | "value": "OnAcquireItem" 87 | }, 88 | "Type": { 89 | "type": "dword", 90 | "value": 3 91 | }, 92 | "Value": { 93 | "type": "cexostring", 94 | "value": "x2_mod_def_aqu" 95 | } 96 | }, 97 | { 98 | "__struct_id": 0, 99 | "Name": { 100 | "type": "cexostring", 101 | "value": "OnActivateItem" 102 | }, 103 | "Type": { 104 | "type": "dword", 105 | "value": 3 106 | }, 107 | "Value": { 108 | "type": "cexostring", 109 | "value": "x2_mod_def_act" 110 | } 111 | }, 112 | { 113 | "__struct_id": 0, 114 | "Name": { 115 | "type": "cexostring", 116 | "value": "OnClientEnter" 117 | }, 118 | "Type": { 119 | "type": "dword", 120 | "value": 3 121 | }, 122 | "Value": { 123 | "type": "cexostring", 124 | "value": "x3_mod_def_enter" 125 | } 126 | }, 127 | { 128 | "__struct_id": 0, 129 | "Name": { 130 | "type": "cexostring", 131 | "value": "OnModuleLoad" 132 | }, 133 | "Type": { 134 | "type": "dword", 135 | "value": 3 136 | }, 137 | "Value": { 138 | "type": "cexostring", 139 | "value": "x2_mod_def_load" 140 | } 141 | }, 142 | { 143 | "__struct_id": 0, 144 | "Name": { 145 | "type": "cexostring", 146 | "value": "OnPlayerDeath" 147 | }, 148 | "Type": { 149 | "type": "dword", 150 | "value": 3 151 | }, 152 | "Value": { 153 | "type": "cexostring", 154 | "value": "nw_o0_death" 155 | } 156 | }, 157 | { 158 | "__struct_id": 0, 159 | "Name": { 160 | "type": "cexostring", 161 | "value": "OnPlayerDying" 162 | }, 163 | "Type": { 164 | "type": "dword", 165 | "value": 3 166 | }, 167 | "Value": { 168 | "type": "cexostring", 169 | "value": "nw_o0_dying" 170 | } 171 | }, 172 | { 173 | "__struct_id": 0, 174 | "Name": { 175 | "type": "cexostring", 176 | "value": "OnPlayerEquipItem" 177 | }, 178 | "Type": { 179 | "type": "dword", 180 | "value": 3 181 | }, 182 | "Value": { 183 | "type": "cexostring", 184 | "value": "x2_mod_def_equ" 185 | } 186 | }, 187 | { 188 | "__struct_id": 0, 189 | "Name": { 190 | "type": "cexostring", 191 | "value": "OnPlayerRespawn" 192 | }, 193 | "Type": { 194 | "type": "dword", 195 | "value": 3 196 | }, 197 | "Value": { 198 | "type": "cexostring", 199 | "value": "nw_o0_respawn" 200 | } 201 | }, 202 | { 203 | "__struct_id": 0, 204 | "Name": { 205 | "type": "cexostring", 206 | "value": "OnPlayerRest" 207 | }, 208 | "Type": { 209 | "type": "dword", 210 | "value": 3 211 | }, 212 | "Value": { 213 | "type": "cexostring", 214 | "value": "x2_mod_def_rest" 215 | } 216 | }, 217 | { 218 | "__struct_id": 0, 219 | "Name": { 220 | "type": "cexostring", 221 | "value": "OnPlayerUnEquipItem" 222 | }, 223 | "Type": { 224 | "type": "dword", 225 | "value": 3 226 | }, 227 | "Value": { 228 | "type": "cexostring", 229 | "value": "x2_mod_def_unequ" 230 | } 231 | }, 232 | { 233 | "__struct_id": 0, 234 | "Name": { 235 | "type": "cexostring", 236 | "value": "OnUnAcquireItem" 237 | }, 238 | "Type": { 239 | "type": "dword", 240 | "value": 3 241 | }, 242 | "Value": { 243 | "type": "cexostring", 244 | "value": "x2_mod_def_unaqu" 245 | } 246 | }, 247 | { 248 | "__struct_id": 0, 249 | "Name": { 250 | "type": "cexostring", 251 | "value": "OnCreatureBlocked" 252 | }, 253 | "Type": { 254 | "type": "dword", 255 | "value": 3 256 | }, 257 | "Value": { 258 | "type": "cexostring", 259 | "value": "nw_c2_defaulte" 260 | } 261 | }, 262 | { 263 | "__struct_id": 0, 264 | "Name": { 265 | "type": "cexostring", 266 | "value": "OnCreatureCombatRoundEnd" 267 | }, 268 | "Type": { 269 | "type": "dword", 270 | "value": 3 271 | }, 272 | "Value": { 273 | "type": "cexostring", 274 | "value": "nw_c2_default3" 275 | } 276 | }, 277 | { 278 | "__struct_id": 0, 279 | "Name": { 280 | "type": "cexostring", 281 | "value": "OnCreatureConversation" 282 | }, 283 | "Type": { 284 | "type": "dword", 285 | "value": 3 286 | }, 287 | "Value": { 288 | "type": "cexostring", 289 | "value": "nw_c2_default4,nw_g0_conversat:default" 290 | } 291 | }, 292 | { 293 | "__struct_id": 0, 294 | "Name": { 295 | "type": "cexostring", 296 | "value": "OnPCConversation" 297 | }, 298 | "Type": { 299 | "type": "dword", 300 | "value": 3 301 | }, 302 | "Value": { 303 | "type": "cexostring", 304 | "value": "nw_g0_conversat:default" 305 | } 306 | }, 307 | { 308 | "__struct_id": 0, 309 | "Name": { 310 | "type": "cexostring", 311 | "value": "OnCreatureDamaged" 312 | }, 313 | "Type": { 314 | "type": "dword", 315 | "value": 3 316 | }, 317 | "Value": { 318 | "type": "cexostring", 319 | "value": "nw_c2_default6" 320 | } 321 | }, 322 | { 323 | "__struct_id": 0, 324 | "Name": { 325 | "type": "cexostring", 326 | "value": "OnCreatureDeath" 327 | }, 328 | "Type": { 329 | "type": "dword", 330 | "value": 3 331 | }, 332 | "Value": { 333 | "type": "cexostring", 334 | "value": "nw_c2_default7" 335 | } 336 | }, 337 | { 338 | "__struct_id": 0, 339 | "Name": { 340 | "type": "cexostring", 341 | "value": "OnCreatureDisturbed" 342 | }, 343 | "Type": { 344 | "type": "dword", 345 | "value": 3 346 | }, 347 | "Value": { 348 | "type": "cexostring", 349 | "value": "nw_c2_default8" 350 | } 351 | }, 352 | { 353 | "__struct_id": 0, 354 | "Name": { 355 | "type": "cexostring", 356 | "value": "OnCreatureHeartbeat" 357 | }, 358 | "Type": { 359 | "type": "dword", 360 | "value": 3 361 | }, 362 | "Value": { 363 | "type": "cexostring", 364 | "value": "nw_c2_default1" 365 | } 366 | }, 367 | { 368 | "__struct_id": 0, 369 | "Name": { 370 | "type": "cexostring", 371 | "value": "OnCreaturePerception" 372 | }, 373 | "Type": { 374 | "type": "dword", 375 | "value": 3 376 | }, 377 | "Value": { 378 | "type": "cexostring", 379 | "value": "nw_c2_default2" 380 | } 381 | }, 382 | { 383 | "__struct_id": 0, 384 | "Name": { 385 | "type": "cexostring", 386 | "value": "OnCreaturePhysicalAttacked" 387 | }, 388 | "Type": { 389 | "type": "dword", 390 | "value": 3 391 | }, 392 | "Value": { 393 | "type": "cexostring", 394 | "value": "nw_c2_default5" 395 | } 396 | }, 397 | { 398 | "__struct_id": 0, 399 | "Name": { 400 | "type": "cexostring", 401 | "value": "OnCreatureRested" 402 | }, 403 | "Type": { 404 | "type": "dword", 405 | "value": 3 406 | }, 407 | "Value": { 408 | "type": "cexostring", 409 | "value": "nw_c2_defaulta" 410 | } 411 | }, 412 | { 413 | "__struct_id": 0, 414 | "Name": { 415 | "type": "cexostring", 416 | "value": "OnCreatureSpawn" 417 | }, 418 | "Type": { 419 | "type": "dword", 420 | "value": 3 421 | }, 422 | "Value": { 423 | "type": "cexostring", 424 | "value": "nw_c2_default9" 425 | } 426 | }, 427 | { 428 | "__struct_id": 0, 429 | "Name": { 430 | "type": "cexostring", 431 | "value": "OnCreatureSpellCastAt" 432 | }, 433 | "Type": { 434 | "type": "dword", 435 | "value": 3 436 | }, 437 | "Value": { 438 | "type": "cexostring", 439 | "value": "nw_c2_defaultb" 440 | } 441 | }, 442 | { 443 | "__struct_id": 0, 444 | "Name": { 445 | "type": "cexostring", 446 | "value": "OnCreatureUserDefined" 447 | }, 448 | "Type": { 449 | "type": "dword", 450 | "value": 3 451 | }, 452 | "Value": { 453 | "type": "cexostring", 454 | "value": "nw_c2_defaultd" 455 | } 456 | }, 457 | { 458 | "__struct_id": 0, 459 | "Name": { 460 | "type": "cexostring", 461 | "value": "OnPlaceableConversation" 462 | }, 463 | "Type": { 464 | "type": "dword", 465 | "value": 3 466 | }, 467 | "Value": { 468 | "type": "cexostring", 469 | "value": "nw_g0_conversat:default" 470 | } 471 | }, 472 | { 473 | "__struct_id": 0, 474 | "Name": { 475 | "type": "cexostring", 476 | "value": "OnDoorConversation" 477 | }, 478 | "Type": { 479 | "type": "dword", 480 | "value": 3 481 | }, 482 | "Value": { 483 | "type": "cexostring", 484 | "value": "nw_g0_conversat:default" 485 | } 486 | }, 487 | { 488 | "__struct_id": 0, 489 | "Name": { 490 | "type": "cexostring", 491 | "value": "OnDoorAreaTransitionClick" 492 | }, 493 | "Type": { 494 | "type": "dword", 495 | "value": 3 496 | }, 497 | "Value": { 498 | "type": "cexostring", 499 | "value": "nw_g0_transition:default" 500 | } 501 | }, 502 | { 503 | "__struct_id": 0, 504 | "Name": { 505 | "type": "cexostring", 506 | "value": "OnTriggerClick" 507 | }, 508 | "Type": { 509 | "type": "dword", 510 | "value": 3 511 | }, 512 | "Value": { 513 | "type": "cexostring", 514 | "value": "nw_g0_transition:default" 515 | } 516 | } 517 | ] 518 | } 519 | } 520 | -------------------------------------------------------------------------------- /src/demo/core_c_config.nss: -------------------------------------------------------------------------------- 1 | /// ---------------------------------------------------------------------------- 2 | /// @file core_c_config.nss 3 | /// @author Michael A. Sinclair (Squatting Monk) 4 | /// @author Ed Burke (tinygiant98) 5 | /// @brief Core Framework configuration settings. 6 | /// @details 7 | /// This script contains user-definable toggles and settings for the Core 8 | /// Framework. This script is freely editable by the mod builder. All below 9 | /// constants may be overridden, but do not alter the names of the constants. 10 | /// 11 | /// Remember: any changes to this file will not be reflected in the module 12 | /// unless you recompile all scripts in which this file is included (however 13 | /// remotely). 14 | /// 15 | /// ## Acknowledgment 16 | /// The scripts contained in this package are adapted from those included in 17 | /// Edward Beck's HCR2 and EPOlson's Common Scripting Framework. 18 | /// ----------------------------------------------------------------------------- 19 | 20 | #include "util_i_debug" 21 | 22 | // ----------------------------------------------------------------------------- 23 | // Debugging 24 | // ----------------------------------------------------------------------------- 25 | 26 | /// This is a maskable setting that controls where debug messages are logged. 27 | /// Any listed destinations will have debug messages sent to them. You can 28 | /// specify multiple levels using | (e.g., DEBUG_LOG_FILE | DEBUG_LOG_DM). 29 | /// 30 | /// Possible values: 31 | /// - DEBUG_LOG_NONE: all logging is disabled 32 | /// - DEBUG_LOG_FILE: debug messages are written to the log file 33 | /// - DEBUG_LOG_DM: debug messages are sent to all online DMs 34 | /// - DEBUG_LOG_PC: debug messages are sent to the first online PC 35 | /// - DEBUG_LOG_ALL: debug messages are sent to the log files, DMs, and first PC 36 | int DEBUG_LOGGING = DEBUG_LOG_ALL; 37 | 38 | /// This is the level of debug messages to generate. This can be overriden to 39 | /// debug specific objects or events (see below). 40 | /// 41 | /// You can override this level on all events using SetDebugLevel(), or on a 42 | /// specific event using SetEventDebugLevel(). These functions can set the level 43 | /// for all objects or for a specific object. 44 | /// 45 | /// Alternatively, you can set the value on a specific object in the toolset: 46 | /// - To set the debug level for all events, add a local int named DEBUG_LEVEL 47 | /// - To set the debug level for a single event, add a local int named 48 | /// DEBUG_LEVEL_* and a local int named DEBUG_EVENT_*, where * is the name of 49 | /// the event as defined in core_i_constants.nss. 50 | /// - The value of either of these settings should be a value from 1-5 51 | /// representing one of the DEBUG_LEVEL_* constants below. 52 | /// 53 | /// The value that is used is determined as follows: 54 | /// 1. If set, the object-specific debug level for the current event is used. 55 | /// 2. If set, the global debug level for the current event is used. Otherwise... 56 | /// 3. The higher of the global or the object-specific debug level is used. 57 | /// 58 | /// This priority system is intended to allow you to reduce the amount of debug 59 | /// calls from verbose events such as heartbeats or OnCreaturePerception, which 60 | /// can make it hard to scan for useful information. 61 | /// 62 | /// Possible values: 63 | /// - DEBUG_LEVEL_CRITICAL: errors severe enough to stop the script 64 | /// - DEBUG_LEVEL_ERROR: indicates the script malfunctioned in some way 65 | /// - DEBUG_LEVEL_WARNING: indicates unexpected behavior may occur 66 | /// - DEBUG_LEVEL_NOTICE: information to track the flow of functions 67 | /// - DEBUG_LEVEL_DEBUG: data dumps used for debugging 68 | const int DEFAULT_DEBUG_LEVEL = DEBUG_LEVEL_ERROR; 69 | 70 | /// This controls the level of debug messages to generate on heartbeat events. 71 | /// This can be used to prevent the excessive generation of debug messages that 72 | /// may clutter the log. You may override this on an event-by-event basis using 73 | /// SetEventDebugLevel(). 74 | /// 75 | /// Possible values: 76 | /// - DEBUG_LEVEL_NONE: use the object or module default level 77 | /// - DEBUG_LEVEL_CRITICAL: errors severe enough to stop the script 78 | /// - DEBUG_LEVEL_ERROR: indicates the script malfunctioned in some way 79 | /// - DEBUG_LEVEL_WARNING: indicates unexpected behavior may occur 80 | /// - DEBUG_LEVEL_NOTICE: information to track the flow of functions 81 | /// - DEBUG_LEVEL_DEBUG: data dumps used for debugging 82 | const int HEARTBEAT_DEBUG_LEVEL = DEBUG_LEVEL_ERROR; 83 | 84 | /// This is the level of debug messages to generate when OnCreaturePerception 85 | /// fires. This can be used to prevent the excessive generation of debug 86 | /// messages that may clutter the log. You may override this on an 87 | /// object-by-object basis using SetEventDebugLevel(). 88 | /// 89 | /// Possible values: 90 | /// - DEBUG_LEVEL_NONE: use the object or module default level 91 | /// - DEBUG_LEVEL_CRITICAL: errors severe enough to stop the script 92 | /// - DEBUG_LEVEL_ERROR: indicates the script malfunctioned in some way 93 | /// - DEBUG_LEVEL_WARNING: indicates unexpected behavior may occur 94 | /// - DEBUG_LEVEL_NOTICE: information to track the flow of functions 95 | /// - DEBUG_LEVEL_DEBUG: data dumps used for debugging 96 | const int PERCEPTION_DEBUG_LEVEL = DEBUG_LEVEL_ERROR; 97 | 98 | /// This is the level of debug messages to generate when the framework is 99 | /// initializing. To prevent excessive logging during initialization, set this 100 | /// to a lower level than DEFAULT_DEBUG_LEVEL above. Once framework 101 | /// initialization is complete, module debug level will revert to 102 | /// DEFAULT_DEBUG_LEVEL 103 | const int INITIALIZATION_DEBUG_LEVEL = DEBUG_LEVEL_DEBUG; 104 | 105 | // ----------------------------------------------------------------------------- 106 | // Library and Plugin Management 107 | // ----------------------------------------------------------------------------- 108 | 109 | /// This is a comma-separated list of glob patterns matching libraries that 110 | /// should be automatically loaded when the Core Framework is initialized. The 111 | /// libraries will be loaded in the order of the pattern they matched. Multiple 112 | /// libraries matching the same pattern will be loaded in alphabetical order. 113 | /// 114 | /// The following glob syntax is supported: 115 | /// - `*`: match zero or more characters 116 | /// - `?`: match a single character 117 | /// - `[abc]`: match any of a, b, or c 118 | /// - `[a-z]`: match any character from a-z 119 | /// Other text is matched literally, so using exact script names is okay. 120 | const string INSTALLED_LIBRARIES = "*_l_plugin"; 121 | 122 | /// This is a comma-separated list of plugins that should be activated when the 123 | /// Core Framework is initialized. 124 | const string INSTALLED_PLUGINS = "bw_defaultevents, core_demo, dlg, pqj, chat"; 125 | 126 | // ----------------------------------------------------------------------------- 127 | // Event Management 128 | // ----------------------------------------------------------------------------- 129 | 130 | /// These settings control the order in which event hook-ins run. Event hook-ins 131 | /// get sorted by their priority: a floating point number between 0.0 and 10.0. 132 | /// While you can specify a priority for a hook in the same variable that calls 133 | /// it, you can set a default priority here to avoid having to repeatedly set 134 | /// priorities. 135 | /// 136 | /// Event hook-ins are sorted into global and local types: 137 | /// - Global event hook-ins are defined by an installed plugin. They are called 138 | /// whenever a particular event is triggered. 139 | /// - Local event hook-ins are defined on a particular object, such as a 140 | /// creature or placeable, or on the area or persistent object (such as a 141 | /// trigger or AoE) the object is in. 142 | /// By default, local scripts have priority over global scripts. You can change 143 | /// this for all scripts here or set the priorities of scripts in the object 144 | /// variables on a case-by-case basis. 145 | 146 | /// This is the default priority for global event hook-in scripts (i.e., on a 147 | /// plugin object) that do not have a priority explicitly set. It can be a 148 | /// value from 0.0 - 10.0 (where a higher priority = earlier run time). If you 149 | /// set this to a negative number, hook-in scripts with no explicit priority will 150 | /// not run (not recommended). 151 | /// Default value: 5.0 152 | const float GLOBAL_EVENT_PRIORITY = 5.0; 153 | 154 | /// This is the default priority for local event hook-in scripts (i.e., set on 155 | /// an object besides a plugin) that do not have a priority explicitly assigned. 156 | /// This can be a value from 0.0 - 10.0 (where a higher priority = earlier run 157 | /// time). If you set this to a negative number, local hook-in scripts with no 158 | /// explicit priority will not run (not recommended). It is recommended that you 159 | /// set this higher than the value of GLOBAL_EVENT_PRIORITY. This ensures local 160 | /// event scripts will run before most globally defined scripts. 161 | /// Default value: 7.0 162 | const float LOCAL_EVENT_PRIORITY = 7.0; 163 | 164 | /// This controls whether the Core handles tag-based scripting on its own. If 165 | /// this is TRUE, tag-based scripts will be called as library scripts rather 166 | /// than stand-alone scripts, allowing you to greatly reduce the number of 167 | /// tag-based scripts in the module. If you have traditional tag-based scripts, 168 | /// those will continue to work. The only reason you might want to turn this off 169 | /// is to completely disable tag-based scripting or to use a plugin to call the 170 | /// desired scripts (e.g., make a plugin for the BioWare X2 functions, which 171 | /// handle tag-based scripting on their own). 172 | /// Default value: TRUE 173 | const int ENABLE_TAGBASED_SCRIPTS = TRUE; 174 | 175 | /// If TRUE, this will cause all event handlers for the module to be set to 176 | /// "hook_nwn" when the Core Framework is initialized. Any existing event 177 | /// scripts will be set as local event scripts and will still fire when the 178 | /// event is triggered. 179 | const int AUTO_HOOK_MODULE_EVENTS = TRUE; 180 | 181 | /// If TRUE, this will cause all event handlers for all areas in the module to 182 | /// be set to "hook_nwn" when the Core Framework is initialized. Any existing 183 | /// event scripts will be set as local event scripts and will still fire when 184 | /// the event is triggered. 185 | /// @note You can skip auto-hooking an individual area by setting a local int 186 | /// named `SKIP_AUTO_HOOK` to TRUE on it. 187 | /// @note Areas spawned by script after the Core Framework is initialized will 188 | /// not have the handlers set. 189 | const int AUTO_HOOK_AREA_EVENTS = TRUE; 190 | 191 | /// This controls whether the OnHeartbeat event is hooked when automatically 192 | /// hooking area events during initialization. Has no effect if 193 | /// AUTO_HOOK_AREA_EVENTS is FALSE. 194 | const int AUTO_HOOK_AREA_HEARTBEAT_EVENT = FALSE; 195 | 196 | /// This is a bitmasked value matching object types that should have their event 197 | /// handlers changed to "hook_nwn" when the Core Framework is initialized. Any 198 | /// existing event scripts will be set as local event scripts and will still 199 | /// fire when the event is triggered. You can add multiple types using the `|` 200 | /// operator (e.g., OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE). To hook all 201 | /// eligible objects, set this to OBJECT_TYPE_ALL. To disable hooking for all 202 | /// objects, set this to 0. 203 | /// @note You can skip auto-hooking an individual object by setting a local int 204 | /// named `SKIP_AUTO_HOOK` to TRUE on it. 205 | /// @note Objects spawned by script after the Core Framework is initialized will 206 | /// not have the handlers set. 207 | int AUTO_HOOK_OBJECT_EVENTS = OBJECT_TYPE_CREATURE | OBJECT_TYPE_PLACEABLE; 208 | 209 | /// This controls whether the OnHeartbeat event is hooked when automatically 210 | /// hooking objects during initialization. It is a bitmasked value matching the 211 | /// types that should have their heartbeat events hooked. To enable heartbeat 212 | /// hooking for all eligible objects, set this to OBJECT_TYPE_ALL. To disable 213 | /// heartbeat hooking for all objects, set this to 0. 214 | int AUTO_HOOK_OBJECT_HEARTBEAT_EVENT = 0; 215 | 216 | /// If TRUE, this will cause all of a PC's event scripts to be set to "hook_nwn" 217 | /// OnClientEnter. Existing event scripts (usually "default") are not preserved. 218 | const int AUTO_HOOK_PC_EVENTS = TRUE; 219 | 220 | /// This controls whether the OnHeartbeat event is hooked when automatically 221 | /// hooking PC events OnClientEnter. If AUTO_HOOK_PC_EVENTS is FALSE, this will 222 | /// have no effect. 223 | const int AUTO_HOOK_PC_HEARTBEAT_EVENT = FALSE; 224 | 225 | // ----------------------------------------------------------------------------- 226 | // Custom Events 227 | // ----------------------------------------------------------------------------- 228 | 229 | /// This toggles whether to allow the OnHour event. If this is TRUE, the OnHour 230 | /// event will execute each time the hour changes. 231 | const int ENABLE_ON_HOUR_EVENT = TRUE; 232 | 233 | /// This toggles whether the OnAreaEmpty event runs. If this is TRUE, the 234 | /// OnAreaEmpty event will run on an area ON_AREA_EMPTY_EVENT_DELAY seconds 235 | /// after the last PC exists the area. This is a good event for area cleanup 236 | /// scripts. 237 | const int ENABLE_ON_AREA_EMPTY_EVENT = TRUE; 238 | 239 | /// This is the number of seconds after an area is emptied of players to run the 240 | /// OnAreaEmpty scripts for that area. 241 | /// Default value: 180.0 (3 real-life minutes) 242 | const float ON_AREA_EMPTY_EVENT_DELAY = 180.0; 243 | 244 | // ----------------------------------------------------------------------------- 245 | // Miscellaneous 246 | // ----------------------------------------------------------------------------- 247 | 248 | /// This is the script that will run before the framework initializes the first 249 | /// time. An empty string means no script will run. 250 | const string ON_MODULE_PRELOAD = ""; 251 | 252 | /// When using AOE hook scripts, NPCs can be added to the AOE roster for easier 253 | /// access during scripting. To only allow PC objects on the AOE rosters, set 254 | /// this to FALSE. 255 | const int INCLUDE_NPC_IN_AOE_ROSTER = TRUE; 256 | 257 | /// This is the welcome message that will be sent to all players and DMs that 258 | /// log into the module. 259 | const string WELCOME_MESSAGE = "Welcome to the Core Framework."; 260 | -------------------------------------------------------------------------------- /src/demo/creaturepalcus.itp.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "ITP ", 3 | "MAIN": { 4 | "type": "list", 5 | "value": [ 6 | { 7 | "__struct_id": 0, 8 | "LIST": { 9 | "type": "list", 10 | "value": [ 11 | { 12 | "__struct_id": 0, 13 | "ID": { 14 | "type": "byte", 15 | "value": 48 16 | }, 17 | "STRREF": { 18 | "type": "dword", 19 | "value": 63235 20 | } 21 | }, 22 | { 23 | "__struct_id": 0, 24 | "LIST": { 25 | "type": "list", 26 | "value": [ 27 | { 28 | "__struct_id": 0, 29 | "ID": { 30 | "type": "byte", 31 | "value": 5 32 | }, 33 | "STRREF": { 34 | "type": "dword", 35 | "value": 6695 36 | } 37 | }, 38 | { 39 | "__struct_id": 0, 40 | "ID": { 41 | "type": "byte", 42 | "value": 6 43 | }, 44 | "STRREF": { 45 | "type": "dword", 46 | "value": 6696 47 | } 48 | }, 49 | { 50 | "__struct_id": 0, 51 | "ID": { 52 | "type": "byte", 53 | "value": 7 54 | }, 55 | "STRREF": { 56 | "type": "dword", 57 | "value": 6697 58 | } 59 | }, 60 | { 61 | "__struct_id": 0, 62 | "ID": { 63 | "type": "byte", 64 | "value": 8 65 | }, 66 | "STRREF": { 67 | "type": "dword", 68 | "value": 6698 69 | } 70 | }, 71 | { 72 | "__struct_id": 0, 73 | "ID": { 74 | "type": "byte", 75 | "value": 9 76 | }, 77 | "STRREF": { 78 | "type": "dword", 79 | "value": 201 80 | } 81 | } 82 | ] 83 | }, 84 | "STRREF": { 85 | "type": "dword", 86 | "value": 6694 87 | } 88 | }, 89 | { 90 | "__struct_id": 0, 91 | "ID": { 92 | "type": "byte", 93 | "value": 20 94 | }, 95 | "STRREF": { 96 | "type": "dword", 97 | "value": 6712 98 | } 99 | }, 100 | { 101 | "__struct_id": 0, 102 | "ID": { 103 | "type": "byte", 104 | "value": 21 105 | }, 106 | "STRREF": { 107 | "type": "dword", 108 | "value": 6713 109 | } 110 | }, 111 | { 112 | "__struct_id": 0, 113 | "ID": { 114 | "type": "byte", 115 | "value": 22 116 | }, 117 | "STRREF": { 118 | "type": "dword", 119 | "value": 6714 120 | } 121 | }, 122 | { 123 | "__struct_id": 0, 124 | "LIST": { 125 | "type": "list", 126 | "value": [ 127 | { 128 | "__struct_id": 0, 129 | "ID": { 130 | "type": "byte", 131 | "value": 34 132 | }, 133 | "STRREF": { 134 | "type": "dword", 135 | "value": 6727 136 | } 137 | }, 138 | { 139 | "__struct_id": 0, 140 | "ID": { 141 | "type": "byte", 142 | "value": 35 143 | }, 144 | "STRREF": { 145 | "type": "dword", 146 | "value": 6728 147 | } 148 | }, 149 | { 150 | "__struct_id": 0, 151 | "ID": { 152 | "type": "byte", 153 | "value": 36 154 | }, 155 | "STRREF": { 156 | "type": "dword", 157 | "value": 6729 158 | } 159 | }, 160 | { 161 | "__struct_id": 0, 162 | "ID": { 163 | "type": "byte", 164 | "value": 37 165 | }, 166 | "STRREF": { 167 | "type": "dword", 168 | "value": 6730 169 | } 170 | } 171 | ] 172 | }, 173 | "STRREF": { 174 | "type": "dword", 175 | "value": 541 176 | } 177 | }, 178 | { 179 | "__struct_id": 0, 180 | "LIST": { 181 | "type": "list", 182 | "value": [ 183 | { 184 | "__struct_id": 0, 185 | "ID": { 186 | "type": "byte", 187 | "value": 14 188 | }, 189 | "STRREF": { 190 | "type": "dword", 191 | "value": 6706 192 | } 193 | }, 194 | { 195 | "__struct_id": 0, 196 | "ID": { 197 | "type": "byte", 198 | "value": 15 199 | }, 200 | "STRREF": { 201 | "type": "dword", 202 | "value": 6707 203 | } 204 | }, 205 | { 206 | "__struct_id": 0, 207 | "ID": { 208 | "type": "byte", 209 | "value": 16 210 | }, 211 | "STRREF": { 212 | "type": "dword", 213 | "value": 6708 214 | } 215 | }, 216 | { 217 | "__struct_id": 0, 218 | "ID": { 219 | "type": "byte", 220 | "value": 17 221 | }, 222 | "STRREF": { 223 | "type": "dword", 224 | "value": 6709 225 | } 226 | }, 227 | { 228 | "__struct_id": 0, 229 | "ID": { 230 | "type": "byte", 231 | "value": 18 232 | }, 233 | "STRREF": { 234 | "type": "dword", 235 | "value": 6710 236 | } 237 | }, 238 | { 239 | "__struct_id": 0, 240 | "ID": { 241 | "type": "byte", 242 | "value": 19 243 | }, 244 | "STRREF": { 245 | "type": "dword", 246 | "value": 537 247 | } 248 | }, 249 | { 250 | "__struct_id": 0, 251 | "ID": { 252 | "type": "byte", 253 | "value": 50 254 | }, 255 | "STRREF": { 256 | "type": "dword", 257 | "value": 201 258 | } 259 | } 260 | ] 261 | }, 262 | "STRREF": { 263 | "type": "dword", 264 | "value": 6705 265 | } 266 | }, 267 | { 268 | "__struct_id": 0, 269 | "LIST": { 270 | "type": "list", 271 | "value": [ 272 | { 273 | "__struct_id": 0, 274 | "ID": { 275 | "type": "byte", 276 | "value": 10 277 | }, 278 | "STRREF": { 279 | "type": "dword", 280 | "value": 6701 281 | } 282 | }, 283 | { 284 | "__struct_id": 0, 285 | "ID": { 286 | "type": "byte", 287 | "value": 11 288 | }, 289 | "STRREF": { 290 | "type": "dword", 291 | "value": 6702 292 | } 293 | } 294 | ] 295 | }, 296 | "STRREF": { 297 | "type": "dword", 298 | "value": 6700 299 | } 300 | }, 301 | { 302 | "__struct_id": 0, 303 | "ID": { 304 | "type": "byte", 305 | "value": 49 306 | }, 307 | "STRREF": { 308 | "type": "dword", 309 | "value": 63246 310 | } 311 | }, 312 | { 313 | "__struct_id": 0, 314 | "ID": { 315 | "type": "byte", 316 | "value": 13 317 | }, 318 | "STRREF": { 319 | "type": "dword", 320 | "value": 1592 321 | } 322 | }, 323 | { 324 | "__struct_id": 0, 325 | "LIST": { 326 | "type": "list", 327 | "value": [ 328 | { 329 | "__struct_id": 0, 330 | "ID": { 331 | "type": "byte", 332 | "value": 23 333 | }, 334 | "STRREF": { 335 | "type": "dword", 336 | "value": 6716 337 | } 338 | }, 339 | { 340 | "__struct_id": 0, 341 | "ID": { 342 | "type": "byte", 343 | "value": 24 344 | }, 345 | "STRREF": { 346 | "type": "dword", 347 | "value": 6717 348 | } 349 | }, 350 | { 351 | "__struct_id": 0, 352 | "ID": { 353 | "type": "byte", 354 | "value": 25 355 | }, 356 | "STRREF": { 357 | "type": "dword", 358 | "value": 6718 359 | } 360 | }, 361 | { 362 | "__struct_id": 0, 363 | "ID": { 364 | "type": "byte", 365 | "value": 47 366 | }, 367 | "STRREF": { 368 | "type": "dword", 369 | "value": 6699 370 | } 371 | }, 372 | { 373 | "__struct_id": 0, 374 | "ID": { 375 | "type": "byte", 376 | "value": 26 377 | }, 378 | "STRREF": { 379 | "type": "dword", 380 | "value": 6719 381 | } 382 | } 383 | ] 384 | }, 385 | "STRREF": { 386 | "type": "dword", 387 | "value": 6715 388 | } 389 | }, 390 | { 391 | "__struct_id": 0, 392 | "ID": { 393 | "type": "byte", 394 | "value": 12 395 | }, 396 | "STRREF": { 397 | "type": "dword", 398 | "value": 6703 399 | } 400 | }, 401 | { 402 | "__struct_id": 0, 403 | "LIST": { 404 | "type": "list", 405 | "value": [ 406 | { 407 | "__struct_id": 0, 408 | "ID": { 409 | "type": "byte", 410 | "value": 27 411 | }, 412 | "STRREF": { 413 | "type": "dword", 414 | "value": 2058 415 | } 416 | }, 417 | { 418 | "__struct_id": 0, 419 | "ID": { 420 | "type": "byte", 421 | "value": 28 422 | }, 423 | "STRREF": { 424 | "type": "dword", 425 | "value": 6722 426 | } 427 | }, 428 | { 429 | "__struct_id": 0, 430 | "ID": { 431 | "type": "byte", 432 | "value": 29 433 | }, 434 | "STRREF": { 435 | "type": "dword", 436 | "value": 201 437 | } 438 | }, 439 | { 440 | "__struct_id": 0, 441 | "ID": { 442 | "type": "byte", 443 | "value": 30 444 | }, 445 | "STRREF": { 446 | "type": "dword", 447 | "value": 2116 448 | } 449 | }, 450 | { 451 | "__struct_id": 0, 452 | "ID": { 453 | "type": "byte", 454 | "value": 31 455 | }, 456 | "STRREF": { 457 | "type": "dword", 458 | "value": 6723 459 | } 460 | }, 461 | { 462 | "__struct_id": 0, 463 | "ID": { 464 | "type": "byte", 465 | "value": 32 466 | }, 467 | "STRREF": { 468 | "type": "dword", 469 | "value": 2155 470 | } 471 | }, 472 | { 473 | "__struct_id": 0, 474 | "ID": { 475 | "type": "byte", 476 | "value": 33 477 | }, 478 | "STRREF": { 479 | "type": "dword", 480 | "value": 6725 481 | } 482 | } 483 | ] 484 | }, 485 | "STRREF": { 486 | "type": "dword", 487 | "value": 547 488 | } 489 | } 490 | ] 491 | }, 492 | "STRREF": { 493 | "type": "dword", 494 | "value": 6693 495 | } 496 | }, 497 | { 498 | "__struct_id": 0, 499 | "LIST": { 500 | "type": "list", 501 | "value": [ 502 | { 503 | "__struct_id": 0, 504 | "ID": { 505 | "type": "byte", 506 | "value": 38 507 | }, 508 | "STRREF": { 509 | "type": "dword", 510 | "value": 23 511 | } 512 | }, 513 | { 514 | "__struct_id": 0, 515 | "ID": { 516 | "type": "byte", 517 | "value": 39 518 | }, 519 | "STRREF": { 520 | "type": "dword", 521 | "value": 25 522 | } 523 | }, 524 | { 525 | "__struct_id": 0, 526 | "ID": { 527 | "type": "byte", 528 | "value": 40 529 | }, 530 | "STRREF": { 531 | "type": "dword", 532 | "value": 27 533 | } 534 | }, 535 | { 536 | "__struct_id": 0, 537 | "ID": { 538 | "type": "byte", 539 | "value": 42 540 | }, 541 | "STRREF": { 542 | "type": "dword", 543 | "value": 31 544 | } 545 | }, 546 | { 547 | "__struct_id": 0, 548 | "ID": { 549 | "type": "byte", 550 | "value": 41 551 | }, 552 | "STRREF": { 553 | "type": "dword", 554 | "value": 29 555 | } 556 | }, 557 | { 558 | "__struct_id": 0, 559 | "ID": { 560 | "type": "byte", 561 | "value": 43 562 | }, 563 | "STRREF": { 564 | "type": "dword", 565 | "value": 33 566 | } 567 | }, 568 | { 569 | "__struct_id": 0, 570 | "ID": { 571 | "type": "byte", 572 | "value": 44 573 | }, 574 | "LIST": { 575 | "type": "list", 576 | "value": [ 577 | { 578 | "__struct_id": 0, 579 | "CR": { 580 | "type": "float", 581 | "value": 0.5 582 | }, 583 | "FACTION": { 584 | "type": "cexostring", 585 | "value": "Commoner" 586 | }, 587 | "NAME": { 588 | "type": "cexostring", 589 | "value": "Poet" 590 | }, 591 | "RESREF": { 592 | "type": "resref", 593 | "value": "dlg_demo_poet" 594 | } 595 | } 596 | ] 597 | }, 598 | "STRREF": { 599 | "type": "dword", 600 | "value": 35 601 | } 602 | }, 603 | { 604 | "__struct_id": 0, 605 | "ID": { 606 | "type": "byte", 607 | "value": 45 608 | }, 609 | "STRREF": { 610 | "type": "dword", 611 | "value": 201 612 | } 613 | } 614 | ] 615 | }, 616 | "STRREF": { 617 | "type": "dword", 618 | "value": 6731 619 | } 620 | }, 621 | { 622 | "__struct_id": 0, 623 | "LIST": { 624 | "type": "list", 625 | "value": [ 626 | { 627 | "__struct_id": 0, 628 | "ID": { 629 | "type": "byte", 630 | "value": 0 631 | }, 632 | "STRREF": { 633 | "type": "dword", 634 | "value": 6688 635 | } 636 | }, 637 | { 638 | "__struct_id": 0, 639 | "ID": { 640 | "type": "byte", 641 | "value": 1 642 | }, 643 | "STRREF": { 644 | "type": "dword", 645 | "value": 6689 646 | } 647 | }, 648 | { 649 | "__struct_id": 0, 650 | "ID": { 651 | "type": "byte", 652 | "value": 2 653 | }, 654 | "STRREF": { 655 | "type": "dword", 656 | "value": 6690 657 | } 658 | }, 659 | { 660 | "__struct_id": 0, 661 | "ID": { 662 | "type": "byte", 663 | "value": 3 664 | }, 665 | "STRREF": { 666 | "type": "dword", 667 | "value": 6691 668 | } 669 | }, 670 | { 671 | "__struct_id": 0, 672 | "ID": { 673 | "type": "byte", 674 | "value": 4 675 | }, 676 | "STRREF": { 677 | "type": "dword", 678 | "value": 6692 679 | } 680 | } 681 | ] 682 | }, 683 | "STRREF": { 684 | "type": "dword", 685 | "value": 6687 686 | } 687 | }, 688 | { 689 | "__struct_id": 0, 690 | "ID": { 691 | "type": "byte", 692 | "value": 46 693 | }, 694 | "STRREF": { 695 | "type": "dword", 696 | "value": 6732 697 | } 698 | } 699 | ] 700 | } 701 | } 702 | -------------------------------------------------------------------------------- /src/demo/demo_l_plugin.nss: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------- 2 | // File: demo_l_plugin.nss 3 | // System: Core Framework Demo (library script) 4 | // URL: https://github.com/squattingmonk/nwn-core-framework 5 | // Authors: Michael A. Sinclair (Squatting Monk) 6 | // ----------------------------------------------------------------------------- 7 | // This library script contains scripts to hook in to Core Framework events. 8 | // ----------------------------------------------------------------------------- 9 | 10 | #include "util_i_color" 11 | #include "util_i_library" 12 | #include "core_i_framework" 13 | #include "chat_i_main" 14 | 15 | // ----------------------------------------------------------------------------- 16 | // VerifyEvent 17 | // ----------------------------------------------------------------------------- 18 | // This is a simple script that sends a message to the PC triggering an event. 19 | // It can be used to verify that an event is firing as expected. 20 | // ----------------------------------------------------------------------------- 21 | 22 | void VerifyEvent(object oPC) 23 | { 24 | SendMessageToPC(oPC, GetCurrentEvent() + " fired!"); 25 | } 26 | 27 | // ----------------------------------------------------------------------------- 28 | // PrintColors 29 | // ----------------------------------------------------------------------------- 30 | // Prints a list of color strings for the calling PC. Used to test util_i_color. 31 | // ----------------------------------------------------------------------------- 32 | 33 | void PrintColor(object oPC, string sColor, int nColor) 34 | { 35 | SendMessageToPC(oPC, HexColorString(sColor + ": " + IntToHexString(nColor), nColor)); 36 | } 37 | 38 | void PrintHexColor(object oPC, int nColor) 39 | { 40 | string sText = "The quick brown fox jumps over the lazy dog"; 41 | string sMessage = IntToHexString(nColor) + ": " + sText; 42 | SendMessageToPC(oPC, HexColorString(sMessage, nColor)); 43 | } 44 | 45 | void PrintColors(object oPC) 46 | { 47 | PrintColor(oPC, "Black", COLOR_BLACK); 48 | PrintColor(oPC, "Blue", COLOR_BLUE); 49 | PrintColor(oPC, "Dark Blue", COLOR_BLUE_DARK); 50 | PrintColor(oPC, "Light Blue", COLOR_BLUE_LIGHT); 51 | PrintColor(oPC, "Brown", COLOR_BROWN); 52 | PrintColor(oPC, "Light Brown", COLOR_BROWN_LIGHT); 53 | PrintColor(oPC, "Gold", COLOR_GOLD); 54 | PrintColor(oPC, "Gray", COLOR_GRAY); 55 | PrintColor(oPC, "Dark Gray", COLOR_GRAY_DARK); 56 | PrintColor(oPC, "Light Gray", COLOR_GRAY_LIGHT); 57 | PrintColor(oPC, "Green", COLOR_GREEN); 58 | PrintColor(oPC, "Dark Green", COLOR_GREEN_DARK); 59 | PrintColor(oPC, "Light Green", COLOR_GREEN_LIGHT); 60 | PrintColor(oPC, "Orange", COLOR_ORANGE); 61 | PrintColor(oPC, "Dark Orange", COLOR_ORANGE_DARK); 62 | PrintColor(oPC, "Light Orange", COLOR_ORANGE_LIGHT); 63 | PrintColor(oPC, "Red", COLOR_RED); 64 | PrintColor(oPC, "Dark Red", COLOR_RED_DARK); 65 | PrintColor(oPC, "Light Red", COLOR_RED_LIGHT); 66 | PrintColor(oPC, "Pink", COLOR_PINK); 67 | PrintColor(oPC, "Purple", COLOR_PURPLE); 68 | PrintColor(oPC, "Turquoise", COLOR_TURQUOISE); 69 | PrintColor(oPC, "Violet", COLOR_VIOLET); 70 | PrintColor(oPC, "Light Violet", COLOR_VIOLET_LIGHT); 71 | PrintColor(oPC, "Dark Violet", COLOR_VIOLET_DARK); 72 | PrintColor(oPC, "White", COLOR_WHITE); 73 | PrintColor(oPC, "Yellow", COLOR_YELLOW); 74 | PrintColor(oPC, "Dark Yellow", COLOR_YELLOW_DARK); 75 | PrintColor(oPC, "Light Yellow", COLOR_YELLOW_LIGHT); 76 | 77 | PrintHexColor(oPC, 0x0099fe); 78 | PrintHexColor(oPC, 0x3dc93d); 79 | 80 | struct HSV hsv = HexToHSV(0xff0000); 81 | PrintHexColor(oPC, HSVToHex(hsv)); 82 | SendMessageToPC(oPC, "H: " + FloatToString(hsv.h) + 83 | " S: " + FloatToString(hsv.s) + 84 | " V: " + FloatToString(hsv.v)); 85 | hsv.v /= 2.0; 86 | hsv.s = 0.0; 87 | PrintHexColor(oPC, HSVToHex(hsv)); 88 | } 89 | 90 | // ----------------------------------------------------------------------------- 91 | // Library Dispatch 92 | // ----------------------------------------------------------------------------- 93 | 94 | void OnLibraryLoad() 95 | { 96 | if (!GetIfPluginExists("core_demo")) 97 | { 98 | object oPlugin = CreatePlugin("core_demo"); 99 | SetName(oPlugin, "[Plugin] Core Framework Demo"); 100 | SetDescription(oPlugin, 101 | "This plugin provides some simple demos of the Core Framework."); 102 | SetDebugPrefix(GetName(oPlugin), oPlugin); 103 | 104 | RegisterEventScript(oPlugin, PLACEABLE_EVENT_ON_USED, "VerifyEvent"); 105 | RegisterEventScript(oPlugin, "CHAT_!colors", "PrintColors"); 106 | RegisterEventScript(oPlugin, "TestTimer", "VerifyEvent"); 107 | } 108 | 109 | // This plugin is created from a blueprint 110 | if (!GetIfPluginExists("bw_defaultevents")) 111 | { 112 | object oPlugin = CreatePlugin("bw_defaultevents"); 113 | SetDebugPrefix(GetName(oPlugin), oPlugin); 114 | } 115 | 116 | RegisterLibraryScript("VerifyEvent", 1); 117 | RegisterLibraryScript("PrintColors", 2); 118 | } 119 | 120 | void OnLibraryScript(string sScript, int nEntry) 121 | { 122 | object oPC = GetEventTriggeredBy(); 123 | switch (nEntry) 124 | { 125 | case 1: VerifyEvent(oPC); break; 126 | case 2: PrintColors(oPC); break; 127 | default: 128 | CriticalError("Library function " + sScript + " not found"); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/demo/dlg_demo_poet.utc.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "UTC ", 3 | "Appearance_Head": { 4 | "type": "byte", 5 | "value": 155 6 | }, 7 | "Appearance_Type": { 8 | "type": "word", 9 | "value": 6 10 | }, 11 | "ArmorPart_RFoot": { 12 | "type": "byte", 13 | "value": 1 14 | }, 15 | "BodyBag": { 16 | "type": "byte", 17 | "value": 0 18 | }, 19 | "BodyPart_Belt": { 20 | "type": "byte", 21 | "value": 0 22 | }, 23 | "BodyPart_LBicep": { 24 | "type": "byte", 25 | "value": 1 26 | }, 27 | "BodyPart_LFArm": { 28 | "type": "byte", 29 | "value": 1 30 | }, 31 | "BodyPart_LFoot": { 32 | "type": "byte", 33 | "value": 1 34 | }, 35 | "BodyPart_LHand": { 36 | "type": "byte", 37 | "value": 1 38 | }, 39 | "BodyPart_LShin": { 40 | "type": "byte", 41 | "value": 1 42 | }, 43 | "BodyPart_LShoul": { 44 | "type": "byte", 45 | "value": 0 46 | }, 47 | "BodyPart_LThigh": { 48 | "type": "byte", 49 | "value": 1 50 | }, 51 | "BodyPart_Neck": { 52 | "type": "byte", 53 | "value": 1 54 | }, 55 | "BodyPart_Pelvis": { 56 | "type": "byte", 57 | "value": 1 58 | }, 59 | "BodyPart_RBicep": { 60 | "type": "byte", 61 | "value": 1 62 | }, 63 | "BodyPart_RFArm": { 64 | "type": "byte", 65 | "value": 1 66 | }, 67 | "BodyPart_RHand": { 68 | "type": "byte", 69 | "value": 1 70 | }, 71 | "BodyPart_RShin": { 72 | "type": "byte", 73 | "value": 1 74 | }, 75 | "BodyPart_RShoul": { 76 | "type": "byte", 77 | "value": 0 78 | }, 79 | "BodyPart_RThigh": { 80 | "type": "byte", 81 | "value": 1 82 | }, 83 | "BodyPart_Torso": { 84 | "type": "byte", 85 | "value": 1 86 | }, 87 | "Cha": { 88 | "type": "byte", 89 | "value": 15 90 | }, 91 | "ChallengeRating": { 92 | "type": "float", 93 | "value": 0.5 94 | }, 95 | "ClassList": { 96 | "type": "list", 97 | "value": [ 98 | { 99 | "__struct_id": 2, 100 | "Class": { 101 | "type": "int", 102 | "value": 1 103 | }, 104 | "ClassLevel": { 105 | "type": "short", 106 | "value": 1 107 | }, 108 | "KnownList0": { 109 | "type": "list", 110 | "value": [ 111 | { 112 | "__struct_id": 3, 113 | "Spell": { 114 | "type": "word", 115 | "value": 33 116 | }, 117 | "SpellFlags": { 118 | "type": "byte", 119 | "value": 1 120 | }, 121 | "SpellMetaMagic": { 122 | "type": "byte", 123 | "value": 0 124 | } 125 | }, 126 | { 127 | "__struct_id": 3, 128 | "Spell": { 129 | "type": "word", 130 | "value": 37 131 | }, 132 | "SpellFlags": { 133 | "type": "byte", 134 | "value": 1 135 | }, 136 | "SpellMetaMagic": { 137 | "type": "byte", 138 | "value": 0 139 | } 140 | }, 141 | { 142 | "__struct_id": 3, 143 | "Spell": { 144 | "type": "word", 145 | "value": 100 146 | }, 147 | "SpellFlags": { 148 | "type": "byte", 149 | "value": 1 150 | }, 151 | "SpellMetaMagic": { 152 | "type": "byte", 153 | "value": 0 154 | } 155 | }, 156 | { 157 | "__struct_id": 3, 158 | "Spell": { 159 | "type": "word", 160 | "value": 151 161 | }, 162 | "SpellFlags": { 163 | "type": "byte", 164 | "value": 1 165 | }, 166 | "SpellMetaMagic": { 167 | "type": "byte", 168 | "value": 0 169 | } 170 | } 171 | ] 172 | } 173 | } 174 | ] 175 | }, 176 | "Color_Hair": { 177 | "type": "byte", 178 | "value": 1 179 | }, 180 | "Color_Skin": { 181 | "type": "byte", 182 | "value": 1 183 | }, 184 | "Color_Tattoo1": { 185 | "type": "byte", 186 | "value": 1 187 | }, 188 | "Color_Tattoo2": { 189 | "type": "byte", 190 | "value": 1 191 | }, 192 | "Comment": { 193 | "type": "cexostring", 194 | "value": "" 195 | }, 196 | "Con": { 197 | "type": "byte", 198 | "value": 14 199 | }, 200 | "Conversation": { 201 | "type": "resref", 202 | "value": "dlg_convzoom" 203 | }, 204 | "CRAdjust": { 205 | "type": "int", 206 | "value": 0 207 | }, 208 | "CurrentHitPoints": { 209 | "type": "short", 210 | "value": 6 211 | }, 212 | "DecayTime": { 213 | "type": "dword", 214 | "value": 5000 215 | }, 216 | "Deity": { 217 | "type": "cexostring", 218 | "value": "" 219 | }, 220 | "Description": { 221 | "type": "cexolocstring", 222 | "value": {} 223 | }, 224 | "Dex": { 225 | "type": "byte", 226 | "value": 14 227 | }, 228 | "Disarmable": { 229 | "type": "byte", 230 | "value": 1 231 | }, 232 | "Equip_ItemList": { 233 | "type": "list", 234 | "value": [ 235 | { 236 | "__struct_id": 2, 237 | "EquippedRes": { 238 | "type": "resref", 239 | "value": "nw_cloth024" 240 | } 241 | } 242 | ] 243 | }, 244 | "FactionID": { 245 | "type": "word", 246 | "value": 2 247 | }, 248 | "FeatList": { 249 | "type": "list", 250 | "value": [ 251 | { 252 | "__struct_id": 1, 253 | "Feat": { 254 | "type": "word", 255 | "value": 3 256 | } 257 | }, 258 | { 259 | "__struct_id": 1, 260 | "Feat": { 261 | "type": "word", 262 | "value": 4 263 | } 264 | }, 265 | { 266 | "__struct_id": 1, 267 | "Feat": { 268 | "type": "word", 269 | "value": 257 270 | } 271 | }, 272 | { 273 | "__struct_id": 1, 274 | "Feat": { 275 | "type": "word", 276 | "value": 197 277 | } 278 | }, 279 | { 280 | "__struct_id": 1, 281 | "Feat": { 282 | "type": "word", 283 | "value": 871 284 | } 285 | }, 286 | { 287 | "__struct_id": 1, 288 | "Feat": { 289 | "type": "word", 290 | "value": 423 291 | } 292 | }, 293 | { 294 | "__struct_id": 1, 295 | "Feat": { 296 | "type": "word", 297 | "value": 1089 298 | } 299 | }, 300 | { 301 | "__struct_id": 1, 302 | "Feat": { 303 | "type": "word", 304 | "value": 258 305 | } 306 | }, 307 | { 308 | "__struct_id": 1, 309 | "Feat": { 310 | "type": "word", 311 | "value": 32 312 | } 313 | }, 314 | { 315 | "__struct_id": 1, 316 | "Feat": { 317 | "type": "word", 318 | "value": 46 319 | } 320 | } 321 | ] 322 | }, 323 | "FirstName": { 324 | "type": "cexolocstring", 325 | "value": { 326 | "0": "Poet" 327 | } 328 | }, 329 | "fortbonus": { 330 | "type": "short", 331 | "value": 0 332 | }, 333 | "Gender": { 334 | "type": "byte", 335 | "value": 0 336 | }, 337 | "GoodEvil": { 338 | "type": "byte", 339 | "value": 50 340 | }, 341 | "HitPoints": { 342 | "type": "short", 343 | "value": 6 344 | }, 345 | "Int": { 346 | "type": "byte", 347 | "value": 12 348 | }, 349 | "Interruptable": { 350 | "type": "byte", 351 | "value": 1 352 | }, 353 | "IsImmortal": { 354 | "type": "byte", 355 | "value": 0 356 | }, 357 | "IsPC": { 358 | "type": "byte", 359 | "value": 0 360 | }, 361 | "LastName": { 362 | "type": "cexolocstring", 363 | "value": { 364 | "0": "" 365 | } 366 | }, 367 | "LawfulChaotic": { 368 | "type": "byte", 369 | "value": 50 370 | }, 371 | "Lootable": { 372 | "type": "byte", 373 | "value": 0 374 | }, 375 | "MaxHitPoints": { 376 | "type": "short", 377 | "value": 8 378 | }, 379 | "NaturalAC": { 380 | "type": "byte", 381 | "value": 0 382 | }, 383 | "NoPermDeath": { 384 | "type": "byte", 385 | "value": 1 386 | }, 387 | "PaletteID": { 388 | "type": "byte", 389 | "value": 44 390 | }, 391 | "PerceptionRange": { 392 | "type": "byte", 393 | "value": 11 394 | }, 395 | "Phenotype": { 396 | "type": "int", 397 | "value": 0 398 | }, 399 | "Plot": { 400 | "type": "byte", 401 | "value": 0 402 | }, 403 | "PortraitId": { 404 | "type": "word", 405 | "value": 1029 406 | }, 407 | "Race": { 408 | "type": "byte", 409 | "value": 6 410 | }, 411 | "refbonus": { 412 | "type": "short", 413 | "value": 0 414 | }, 415 | "ScriptAttacked": { 416 | "type": "resref", 417 | "value": "" 418 | }, 419 | "ScriptDamaged": { 420 | "type": "resref", 421 | "value": "" 422 | }, 423 | "ScriptDeath": { 424 | "type": "resref", 425 | "value": "" 426 | }, 427 | "ScriptDialogue": { 428 | "type": "resref", 429 | "value": "" 430 | }, 431 | "ScriptDisturbed": { 432 | "type": "resref", 433 | "value": "" 434 | }, 435 | "ScriptEndRound": { 436 | "type": "resref", 437 | "value": "" 438 | }, 439 | "ScriptHeartbeat": { 440 | "type": "resref", 441 | "value": "" 442 | }, 443 | "ScriptOnBlocked": { 444 | "type": "resref", 445 | "value": "" 446 | }, 447 | "ScriptOnNotice": { 448 | "type": "resref", 449 | "value": "" 450 | }, 451 | "ScriptRested": { 452 | "type": "resref", 453 | "value": "" 454 | }, 455 | "ScriptSpawn": { 456 | "type": "resref", 457 | "value": "" 458 | }, 459 | "ScriptSpellAt": { 460 | "type": "resref", 461 | "value": "" 462 | }, 463 | "ScriptUserDefine": { 464 | "type": "resref", 465 | "value": "" 466 | }, 467 | "SkillList": { 468 | "type": "list", 469 | "value": [ 470 | { 471 | "__struct_id": 0, 472 | "Rank": { 473 | "type": "byte", 474 | "value": 0 475 | } 476 | }, 477 | { 478 | "__struct_id": 0, 479 | "Rank": { 480 | "type": "byte", 481 | "value": 2 482 | } 483 | }, 484 | { 485 | "__struct_id": 0, 486 | "Rank": { 487 | "type": "byte", 488 | "value": 0 489 | } 490 | }, 491 | { 492 | "__struct_id": 0, 493 | "Rank": { 494 | "type": "byte", 495 | "value": 1 496 | } 497 | }, 498 | { 499 | "__struct_id": 0, 500 | "Rank": { 501 | "type": "byte", 502 | "value": 1 503 | } 504 | }, 505 | { 506 | "__struct_id": 0, 507 | "Rank": { 508 | "type": "byte", 509 | "value": 1 510 | } 511 | }, 512 | { 513 | "__struct_id": 0, 514 | "Rank": { 515 | "type": "byte", 516 | "value": 1 517 | } 518 | }, 519 | { 520 | "__struct_id": 0, 521 | "Rank": { 522 | "type": "byte", 523 | "value": 2 524 | } 525 | }, 526 | { 527 | "__struct_id": 0, 528 | "Rank": { 529 | "type": "byte", 530 | "value": 1 531 | } 532 | }, 533 | { 534 | "__struct_id": 0, 535 | "Rank": { 536 | "type": "byte", 537 | "value": 0 538 | } 539 | }, 540 | { 541 | "__struct_id": 0, 542 | "Rank": { 543 | "type": "byte", 544 | "value": 1 545 | } 546 | }, 547 | { 548 | "__struct_id": 0, 549 | "Rank": { 550 | "type": "byte", 551 | "value": 2 552 | } 553 | }, 554 | { 555 | "__struct_id": 0, 556 | "Rank": { 557 | "type": "byte", 558 | "value": 2 559 | } 560 | }, 561 | { 562 | "__struct_id": 0, 563 | "Rank": { 564 | "type": "byte", 565 | "value": 1 566 | } 567 | }, 568 | { 569 | "__struct_id": 0, 570 | "Rank": { 571 | "type": "byte", 572 | "value": 0 573 | } 574 | }, 575 | { 576 | "__struct_id": 0, 577 | "Rank": { 578 | "type": "byte", 579 | "value": 0 580 | } 581 | }, 582 | { 583 | "__struct_id": 0, 584 | "Rank": { 585 | "type": "byte", 586 | "value": 2 587 | } 588 | }, 589 | { 590 | "__struct_id": 0, 591 | "Rank": { 592 | "type": "byte", 593 | "value": 0 594 | } 595 | }, 596 | { 597 | "__struct_id": 0, 598 | "Rank": { 599 | "type": "byte", 600 | "value": 1 601 | } 602 | }, 603 | { 604 | "__struct_id": 0, 605 | "Rank": { 606 | "type": "byte", 607 | "value": 2 608 | } 609 | }, 610 | { 611 | "__struct_id": 0, 612 | "Rank": { 613 | "type": "byte", 614 | "value": 1 615 | } 616 | }, 617 | { 618 | "__struct_id": 0, 619 | "Rank": { 620 | "type": "byte", 621 | "value": 1 622 | } 623 | }, 624 | { 625 | "__struct_id": 0, 626 | "Rank": { 627 | "type": "byte", 628 | "value": 1 629 | } 630 | }, 631 | { 632 | "__struct_id": 0, 633 | "Rank": { 634 | "type": "byte", 635 | "value": 1 636 | } 637 | }, 638 | { 639 | "__struct_id": 0, 640 | "Rank": { 641 | "type": "byte", 642 | "value": 0 643 | } 644 | }, 645 | { 646 | "__struct_id": 0, 647 | "Rank": { 648 | "type": "byte", 649 | "value": 0 650 | } 651 | }, 652 | { 653 | "__struct_id": 0, 654 | "Rank": { 655 | "type": "byte", 656 | "value": 0 657 | } 658 | }, 659 | { 660 | "__struct_id": 0, 661 | "Rank": { 662 | "type": "byte", 663 | "value": 0 664 | } 665 | } 666 | ] 667 | }, 668 | "SoundSetFile": { 669 | "type": "word", 670 | "value": 65535 671 | }, 672 | "SpecAbilityList": { 673 | "type": "list", 674 | "value": [] 675 | }, 676 | "StartingPackage": { 677 | "type": "byte", 678 | "value": 1 679 | }, 680 | "Str": { 681 | "type": "byte", 682 | "value": 12 683 | }, 684 | "Subrace": { 685 | "type": "cexostring", 686 | "value": "" 687 | }, 688 | "Tag": { 689 | "type": "cexostring", 690 | "value": "Poet" 691 | }, 692 | "Tail_New": { 693 | "type": "dword", 694 | "value": 0 695 | }, 696 | "TemplateList": { 697 | "type": "list", 698 | "value": [] 699 | }, 700 | "TemplateResRef": { 701 | "type": "resref", 702 | "value": "dlg_demo_poet" 703 | }, 704 | "VarTable": { 705 | "type": "list", 706 | "value": [ 707 | { 708 | "__struct_id": 0, 709 | "Name": { 710 | "type": "cexostring", 711 | "value": "*Dialog" 712 | }, 713 | "Type": { 714 | "type": "dword", 715 | "value": 3 716 | }, 717 | "Value": { 718 | "type": "cexostring", 719 | "value": "PoetDialog" 720 | } 721 | } 722 | ] 723 | }, 724 | "WalkRate": { 725 | "type": "int", 726 | "value": 4 727 | }, 728 | "willbonus": { 729 | "type": "short", 730 | "value": 0 731 | }, 732 | "Wings_New": { 733 | "type": "dword", 734 | "value": 0 735 | }, 736 | "Wis": { 737 | "type": "byte", 738 | "value": 10 739 | } 740 | } 741 | -------------------------------------------------------------------------------- /src/demo/doorpalcus.itp.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "ITP ", 3 | "MAIN": { 4 | "type": "list", 5 | "value": [ 6 | { 7 | "__struct_id": 0, 8 | "LIST": { 9 | "type": "list", 10 | "value": [ 11 | { 12 | "__struct_id": 0, 13 | "ID": { 14 | "type": "byte", 15 | "value": 0 16 | }, 17 | "STRREF": { 18 | "type": "dword", 19 | "value": 6688 20 | } 21 | }, 22 | { 23 | "__struct_id": 0, 24 | "ID": { 25 | "type": "byte", 26 | "value": 1 27 | }, 28 | "STRREF": { 29 | "type": "dword", 30 | "value": 6689 31 | } 32 | }, 33 | { 34 | "__struct_id": 0, 35 | "ID": { 36 | "type": "byte", 37 | "value": 2 38 | }, 39 | "STRREF": { 40 | "type": "dword", 41 | "value": 6690 42 | } 43 | }, 44 | { 45 | "__struct_id": 0, 46 | "ID": { 47 | "type": "byte", 48 | "value": 3 49 | }, 50 | "STRREF": { 51 | "type": "dword", 52 | "value": 6691 53 | } 54 | }, 55 | { 56 | "__struct_id": 0, 57 | "ID": { 58 | "type": "byte", 59 | "value": 4 60 | }, 61 | "STRREF": { 62 | "type": "dword", 63 | "value": 6692 64 | } 65 | } 66 | ] 67 | }, 68 | "STRREF": { 69 | "type": "dword", 70 | "value": 6687 71 | } 72 | }, 73 | { 74 | "__struct_id": 0, 75 | "ID": { 76 | "type": "byte", 77 | "value": 5 78 | }, 79 | "STRREF": { 80 | "type": "dword", 81 | "value": 6734 82 | } 83 | }, 84 | { 85 | "__struct_id": 0, 86 | "LIST": { 87 | "type": "list", 88 | "value": [ 89 | { 90 | "__struct_id": 0, 91 | "ID": { 92 | "type": "byte", 93 | "value": 6 94 | }, 95 | "STRREF": { 96 | "type": "dword", 97 | "value": 6736 98 | } 99 | }, 100 | { 101 | "__struct_id": 0, 102 | "ID": { 103 | "type": "byte", 104 | "value": 9 105 | }, 106 | "STRREF": { 107 | "type": "dword", 108 | "value": 201 109 | } 110 | }, 111 | { 112 | "__struct_id": 0, 113 | "ID": { 114 | "type": "byte", 115 | "value": 7 116 | }, 117 | "STRREF": { 118 | "type": "dword", 119 | "value": 6737 120 | } 121 | }, 122 | { 123 | "__struct_id": 0, 124 | "ID": { 125 | "type": "byte", 126 | "value": 8 127 | }, 128 | "STRREF": { 129 | "type": "dword", 130 | "value": 6738 131 | } 132 | } 133 | ] 134 | }, 135 | "STRREF": { 136 | "type": "dword", 137 | "value": 6735 138 | } 139 | } 140 | ] 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/demo/encounterpalcus.itp.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "ITP ", 3 | "MAIN": { 4 | "type": "list", 5 | "value": [ 6 | { 7 | "__struct_id": 0, 8 | "ID": { 9 | "type": "byte", 10 | "value": 8 11 | }, 12 | "STRREF": { 13 | "type": "dword", 14 | "value": 5546 15 | } 16 | }, 17 | { 18 | "__struct_id": 0, 19 | "ID": { 20 | "type": "byte", 21 | "value": 9 22 | }, 23 | "STRREF": { 24 | "type": "dword", 25 | "value": 5547 26 | } 27 | }, 28 | { 29 | "__struct_id": 0, 30 | "ID": { 31 | "type": "byte", 32 | "value": 6 33 | }, 34 | "STRREF": { 35 | "type": "dword", 36 | "value": 4817 37 | } 38 | }, 39 | { 40 | "__struct_id": 0, 41 | "ID": { 42 | "type": "byte", 43 | "value": 7 44 | }, 45 | "STRREF": { 46 | "type": "dword", 47 | "value": 5545 48 | } 49 | }, 50 | { 51 | "__struct_id": 0, 52 | "LIST": { 53 | "type": "list", 54 | "value": [ 55 | { 56 | "__struct_id": 0, 57 | "ID": { 58 | "type": "byte", 59 | "value": 0 60 | }, 61 | "STRREF": { 62 | "type": "dword", 63 | "value": 6688 64 | } 65 | }, 66 | { 67 | "__struct_id": 0, 68 | "ID": { 69 | "type": "byte", 70 | "value": 1 71 | }, 72 | "STRREF": { 73 | "type": "dword", 74 | "value": 6689 75 | } 76 | }, 77 | { 78 | "__struct_id": 0, 79 | "ID": { 80 | "type": "byte", 81 | "value": 2 82 | }, 83 | "STRREF": { 84 | "type": "dword", 85 | "value": 6690 86 | } 87 | }, 88 | { 89 | "__struct_id": 0, 90 | "ID": { 91 | "type": "byte", 92 | "value": 3 93 | }, 94 | "STRREF": { 95 | "type": "dword", 96 | "value": 6691 97 | } 98 | }, 99 | { 100 | "__struct_id": 0, 101 | "ID": { 102 | "type": "byte", 103 | "value": 4 104 | }, 105 | "STRREF": { 106 | "type": "dword", 107 | "value": 6692 108 | } 109 | } 110 | ] 111 | }, 112 | "STRREF": { 113 | "type": "dword", 114 | "value": 6687 115 | } 116 | }, 117 | { 118 | "__struct_id": 0, 119 | "ID": { 120 | "type": "byte", 121 | "value": 5 122 | }, 123 | "STRREF": { 124 | "type": "dword", 125 | "value": 5543 126 | } 127 | } 128 | ] 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/demo/itempalcus.itp.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "ITP ", 3 | "MAIN": { 4 | "type": "list", 5 | "value": [ 6 | { 7 | "__struct_id": 0, 8 | "LIST": { 9 | "type": "list", 10 | "value": [ 11 | { 12 | "__struct_id": 0, 13 | "ID": { 14 | "type": "byte", 15 | "value": 5 16 | }, 17 | "STRREF": { 18 | "type": "dword", 19 | "value": 186 20 | } 21 | }, 22 | { 23 | "__struct_id": 0, 24 | "ID": { 25 | "type": "byte", 26 | "value": 8 27 | }, 28 | "STRREF": { 29 | "type": "dword", 30 | "value": 4818 31 | } 32 | }, 33 | { 34 | "__struct_id": 0, 35 | "ID": { 36 | "type": "byte", 37 | "value": 9 38 | }, 39 | "STRREF": { 40 | "type": "dword", 41 | "value": 6739 42 | } 43 | }, 44 | { 45 | "__struct_id": 0, 46 | "ID": { 47 | "type": "byte", 48 | "value": 6 49 | }, 50 | "STRREF": { 51 | "type": "dword", 52 | "value": 4815 53 | } 54 | }, 55 | { 56 | "__struct_id": 0, 57 | "ID": { 58 | "type": "byte", 59 | "value": 7 60 | }, 61 | "STRREF": { 62 | "type": "dword", 63 | "value": 6669 64 | } 65 | }, 66 | { 67 | "__struct_id": 0, 68 | "ID": { 69 | "type": "byte", 70 | "value": 58 71 | }, 72 | "STRREF": { 73 | "type": "dword", 74 | "value": 6813 75 | } 76 | }, 77 | { 78 | "__struct_id": 0, 79 | "LIST": { 80 | "type": "list", 81 | "value": [ 82 | { 83 | "__struct_id": 0, 84 | "ID": { 85 | "type": "byte", 86 | "value": 11 87 | }, 88 | "STRREF": { 89 | "type": "dword", 90 | "value": 6822 91 | } 92 | }, 93 | { 94 | "__struct_id": 0, 95 | "ID": { 96 | "type": "byte", 97 | "value": 10 98 | }, 99 | "STRREF": { 100 | "type": "dword", 101 | "value": 6741 102 | } 103 | }, 104 | { 105 | "__struct_id": 0, 106 | "ID": { 107 | "type": "byte", 108 | "value": 12 109 | }, 110 | "STRREF": { 111 | "type": "dword", 112 | "value": 6742 113 | } 114 | } 115 | ] 116 | }, 117 | "STRREF": { 118 | "type": "dword", 119 | "value": 6740 120 | } 121 | } 122 | ] 123 | }, 124 | "STRREF": { 125 | "type": "dword", 126 | "value": 335 127 | } 128 | }, 129 | { 130 | "__struct_id": 0, 131 | "LIST": { 132 | "type": "list", 133 | "value": [ 134 | { 135 | "__struct_id": 0, 136 | "ID": { 137 | "type": "byte", 138 | "value": 55 139 | }, 140 | "STRREF": { 141 | "type": "dword", 142 | "value": 6810 143 | } 144 | }, 145 | { 146 | "__struct_id": 0, 147 | "ID": { 148 | "type": "byte", 149 | "value": 13 150 | }, 151 | "STRREF": { 152 | "type": "dword", 153 | "value": 6744 154 | } 155 | }, 156 | { 157 | "__struct_id": 0, 158 | "ID": { 159 | "type": "byte", 160 | "value": 63 161 | }, 162 | "STRREF": { 163 | "type": "dword", 164 | "value": 6831 165 | } 166 | }, 167 | { 168 | "__struct_id": 0, 169 | "ID": { 170 | "type": "byte", 171 | "value": 59 172 | }, 173 | "STRREF": { 174 | "type": "dword", 175 | "value": 6814 176 | } 177 | }, 178 | { 179 | "__struct_id": 0, 180 | "ID": { 181 | "type": "byte", 182 | "value": 14 183 | }, 184 | "STRREF": { 185 | "type": "dword", 186 | "value": 6809 187 | } 188 | }, 189 | { 190 | "__struct_id": 0, 191 | "ID": { 192 | "type": "byte", 193 | "value": 56 194 | }, 195 | "STRREF": { 196 | "type": "dword", 197 | "value": 6811 198 | } 199 | } 200 | ] 201 | }, 202 | "STRREF": { 203 | "type": "dword", 204 | "value": 6743 205 | } 206 | }, 207 | { 208 | "__struct_id": 0, 209 | "LIST": { 210 | "type": "list", 211 | "value": [ 212 | { 213 | "__struct_id": 0, 214 | "ID": { 215 | "type": "byte", 216 | "value": 60 217 | }, 218 | "STRREF": { 219 | "type": "dword", 220 | "value": 6815 221 | } 222 | }, 223 | { 224 | "__struct_id": 0, 225 | "LIST": { 226 | "type": "list", 227 | "value": [ 228 | { 229 | "__struct_id": 0, 230 | "ID": { 231 | "type": "byte", 232 | "value": 16 233 | }, 234 | "STRREF": { 235 | "type": "dword", 236 | "value": 6745 237 | } 238 | }, 239 | { 240 | "__struct_id": 0, 241 | "ID": { 242 | "type": "byte", 243 | "value": 15 244 | }, 245 | "STRREF": { 246 | "type": "dword", 247 | "value": 1520 248 | } 249 | }, 250 | { 251 | "__struct_id": 0, 252 | "ID": { 253 | "type": "byte", 254 | "value": 17 255 | }, 256 | "STRREF": { 257 | "type": "dword", 258 | "value": 6746 259 | } 260 | }, 261 | { 262 | "__struct_id": 0, 263 | "ID": { 264 | "type": "byte", 265 | "value": 18 266 | }, 267 | "STRREF": { 268 | "type": "dword", 269 | "value": 6747 270 | } 271 | }, 272 | { 273 | "__struct_id": 0, 274 | "ID": { 275 | "type": "byte", 276 | "value": 19 277 | }, 278 | "STRREF": { 279 | "type": "dword", 280 | "value": 1530 281 | } 282 | } 283 | ] 284 | }, 285 | "STRREF": { 286 | "type": "dword", 287 | "value": 186 288 | } 289 | }, 290 | { 291 | "__struct_id": 0, 292 | "ID": { 293 | "type": "byte", 294 | "value": 64 295 | }, 296 | "STRREF": { 297 | "type": "dword", 298 | "value": 83602 299 | } 300 | }, 301 | { 302 | "__struct_id": 0, 303 | "ID": { 304 | "type": "byte", 305 | "value": 57 306 | }, 307 | "STRREF": { 308 | "type": "dword", 309 | "value": 6812 310 | } 311 | }, 312 | { 313 | "__struct_id": 0, 314 | "LIST": { 315 | "type": "list", 316 | "value": [ 317 | { 318 | "__struct_id": 0, 319 | "ID": { 320 | "type": "byte", 321 | "value": 21 322 | }, 323 | "STRREF": { 324 | "type": "dword", 325 | "value": 6750 326 | } 327 | }, 328 | { 329 | "__struct_id": 0, 330 | "ID": { 331 | "type": "byte", 332 | "value": 22 333 | }, 334 | "STRREF": { 335 | "type": "dword", 336 | "value": 6751 337 | } 338 | } 339 | ] 340 | }, 341 | "STRREF": { 342 | "type": "dword", 343 | "value": 6749 344 | } 345 | }, 346 | { 347 | "__struct_id": 0, 348 | "ID": { 349 | "type": "byte", 350 | "value": 20 351 | }, 352 | "STRREF": { 353 | "type": "dword", 354 | "value": 6748 355 | } 356 | }, 357 | { 358 | "__struct_id": 0, 359 | "ID": { 360 | "type": "byte", 361 | "value": 23 362 | }, 363 | "STRREF": { 364 | "type": "dword", 365 | "value": 6699 366 | } 367 | }, 368 | { 369 | "__struct_id": 0, 370 | "ID": { 371 | "type": "byte", 372 | "value": 24 373 | }, 374 | "STRREF": { 375 | "type": "dword", 376 | "value": 6753 377 | } 378 | }, 379 | { 380 | "__struct_id": 0, 381 | "ID": { 382 | "type": "byte", 383 | "value": 26 384 | }, 385 | "STRREF": { 386 | "type": "dword", 387 | "value": 6754 388 | } 389 | } 390 | ] 391 | }, 392 | "STRREF": { 393 | "type": "dword", 394 | "value": 1592 395 | } 396 | }, 397 | { 398 | "__struct_id": 0, 399 | "ID": { 400 | "type": "byte", 401 | "value": 54 402 | }, 403 | "STRREF": { 404 | "type": "dword", 405 | "value": 6808 406 | } 407 | }, 408 | { 409 | "__struct_id": 0, 410 | "LIST": { 411 | "type": "list", 412 | "value": [ 413 | { 414 | "__struct_id": 0, 415 | "ID": { 416 | "type": "byte", 417 | "value": 0 418 | }, 419 | "LIST": { 420 | "type": "list", 421 | "value": [ 422 | { 423 | "__struct_id": 0, 424 | "NAME": { 425 | "type": "cexostring", 426 | "value": "[Plugin] Default BioWare Events" 427 | }, 428 | "RESREF": { 429 | "type": "resref", 430 | "value": "bw_defaultevents" 431 | } 432 | } 433 | ] 434 | }, 435 | "STRREF": { 436 | "type": "dword", 437 | "value": 6688 438 | } 439 | }, 440 | { 441 | "__struct_id": 0, 442 | "ID": { 443 | "type": "byte", 444 | "value": 1 445 | }, 446 | "STRREF": { 447 | "type": "dword", 448 | "value": 6689 449 | } 450 | }, 451 | { 452 | "__struct_id": 0, 453 | "ID": { 454 | "type": "byte", 455 | "value": 2 456 | }, 457 | "STRREF": { 458 | "type": "dword", 459 | "value": 6690 460 | } 461 | }, 462 | { 463 | "__struct_id": 0, 464 | "ID": { 465 | "type": "byte", 466 | "value": 3 467 | }, 468 | "STRREF": { 469 | "type": "dword", 470 | "value": 6691 471 | } 472 | }, 473 | { 474 | "__struct_id": 0, 475 | "ID": { 476 | "type": "byte", 477 | "value": 4 478 | }, 479 | "STRREF": { 480 | "type": "dword", 481 | "value": 6692 482 | } 483 | } 484 | ] 485 | }, 486 | "STRREF": { 487 | "type": "dword", 488 | "value": 6687 489 | } 490 | }, 491 | { 492 | "__struct_id": 0, 493 | "ID": { 494 | "type": "byte", 495 | "value": 53 496 | }, 497 | "STRREF": { 498 | "type": "dword", 499 | "value": 6732 500 | } 501 | }, 502 | { 503 | "__struct_id": 0, 504 | "LIST": { 505 | "type": "list", 506 | "value": [ 507 | { 508 | "__struct_id": 0, 509 | "LIST": { 510 | "type": "list", 511 | "value": [ 512 | { 513 | "__struct_id": 0, 514 | "ID": { 515 | "type": "byte", 516 | "value": 27 517 | }, 518 | "STRREF": { 519 | "type": "dword", 520 | "value": 6757 521 | } 522 | }, 523 | { 524 | "__struct_id": 0, 525 | "ID": { 526 | "type": "byte", 527 | "value": 28 528 | }, 529 | "STRREF": { 530 | "type": "dword", 531 | "value": 6758 532 | } 533 | }, 534 | { 535 | "__struct_id": 0, 536 | "ID": { 537 | "type": "byte", 538 | "value": 29 539 | }, 540 | "STRREF": { 541 | "type": "dword", 542 | "value": 6759 543 | } 544 | } 545 | ] 546 | }, 547 | "STRREF": { 548 | "type": "dword", 549 | "value": 6756 550 | } 551 | }, 552 | { 553 | "__struct_id": 0, 554 | "LIST": { 555 | "type": "list", 556 | "value": [ 557 | { 558 | "__struct_id": 0, 559 | "ID": { 560 | "type": "byte", 561 | "value": 32 562 | }, 563 | "STRREF": { 564 | "type": "dword", 565 | "value": 6762 566 | } 567 | }, 568 | { 569 | "__struct_id": 0, 570 | "ID": { 571 | "type": "byte", 572 | "value": 30 573 | }, 574 | "STRREF": { 575 | "type": "dword", 576 | "value": 6760 577 | } 578 | }, 579 | { 580 | "__struct_id": 0, 581 | "ID": { 582 | "type": "byte", 583 | "value": 31 584 | }, 585 | "STRREF": { 586 | "type": "dword", 587 | "value": 6761 588 | } 589 | } 590 | ] 591 | }, 592 | "STRREF": { 593 | "type": "dword", 594 | "value": 490 595 | } 596 | }, 597 | { 598 | "__struct_id": 0, 599 | "LIST": { 600 | "type": "list", 601 | "value": [ 602 | { 603 | "__struct_id": 0, 604 | "ID": { 605 | "type": "byte", 606 | "value": 33 607 | }, 608 | "STRREF": { 609 | "type": "dword", 610 | "value": 6764 611 | } 612 | }, 613 | { 614 | "__struct_id": 0, 615 | "ID": { 616 | "type": "byte", 617 | "value": 34 618 | }, 619 | "STRREF": { 620 | "type": "dword", 621 | "value": 6765 622 | } 623 | }, 624 | { 625 | "__struct_id": 0, 626 | "ID": { 627 | "type": "byte", 628 | "value": 35 629 | }, 630 | "STRREF": { 631 | "type": "dword", 632 | "value": 6766 633 | } 634 | }, 635 | { 636 | "__struct_id": 0, 637 | "ID": { 638 | "type": "byte", 639 | "value": 36 640 | }, 641 | "STRREF": { 642 | "type": "dword", 643 | "value": 6767 644 | } 645 | }, 646 | { 647 | "__struct_id": 0, 648 | "ID": { 649 | "type": "byte", 650 | "value": 37 651 | }, 652 | "STRREF": { 653 | "type": "dword", 654 | "value": 6699 655 | } 656 | }, 657 | { 658 | "__struct_id": 0, 659 | "ID": { 660 | "type": "byte", 661 | "value": 38 662 | }, 663 | "STRREF": { 664 | "type": "dword", 665 | "value": 6768 666 | } 667 | } 668 | ] 669 | }, 670 | "STRREF": { 671 | "type": "dword", 672 | "value": 6763 673 | } 674 | }, 675 | { 676 | "__struct_id": 0, 677 | "LIST": { 678 | "type": "list", 679 | "value": [ 680 | { 681 | "__struct_id": 0, 682 | "ID": { 683 | "type": "byte", 684 | "value": 39 685 | }, 686 | "STRREF": { 687 | "type": "dword", 688 | "value": 6769 689 | } 690 | }, 691 | { 692 | "__struct_id": 0, 693 | "ID": { 694 | "type": "byte", 695 | "value": 40 696 | }, 697 | "STRREF": { 698 | "type": "dword", 699 | "value": 6770 700 | } 701 | }, 702 | { 703 | "__struct_id": 0, 704 | "ID": { 705 | "type": "byte", 706 | "value": 41 707 | }, 708 | "STRREF": { 709 | "type": "dword", 710 | "value": 6771 711 | } 712 | }, 713 | { 714 | "__struct_id": 0, 715 | "ID": { 716 | "type": "byte", 717 | "value": 42 718 | }, 719 | "STRREF": { 720 | "type": "dword", 721 | "value": 6772 722 | } 723 | }, 724 | { 725 | "__struct_id": 0, 726 | "ID": { 727 | "type": "byte", 728 | "value": 61 729 | }, 730 | "STRREF": { 731 | "type": "dword", 732 | "value": 6817 733 | } 734 | } 735 | ] 736 | }, 737 | "STRREF": { 738 | "type": "dword", 739 | "value": 491 740 | } 741 | }, 742 | { 743 | "__struct_id": 0, 744 | "ID": { 745 | "type": "byte", 746 | "value": 46 747 | }, 748 | "STRREF": { 749 | "type": "dword", 750 | "value": 6775 751 | } 752 | }, 753 | { 754 | "__struct_id": 0, 755 | "ID": { 756 | "type": "byte", 757 | "value": 47 758 | }, 759 | "STRREF": { 760 | "type": "dword", 761 | "value": 6776 762 | } 763 | }, 764 | { 765 | "__struct_id": 0, 766 | "LIST": { 767 | "type": "list", 768 | "value": [ 769 | { 770 | "__struct_id": 0, 771 | "ID": { 772 | "type": "byte", 773 | "value": 48 774 | }, 775 | "STRREF": { 776 | "type": "dword", 777 | "value": 6778 778 | } 779 | }, 780 | { 781 | "__struct_id": 0, 782 | "ID": { 783 | "type": "byte", 784 | "value": 49 785 | }, 786 | "STRREF": { 787 | "type": "dword", 788 | "value": 6779 789 | } 790 | }, 791 | { 792 | "__struct_id": 0, 793 | "ID": { 794 | "type": "byte", 795 | "value": 50 796 | }, 797 | "STRREF": { 798 | "type": "dword", 799 | "value": 6780 800 | } 801 | } 802 | ] 803 | }, 804 | "STRREF": { 805 | "type": "dword", 806 | "value": 6777 807 | } 808 | }, 809 | { 810 | "__struct_id": 0, 811 | "ID": { 812 | "type": "byte", 813 | "value": 51 814 | }, 815 | "STRREF": { 816 | "type": "dword", 817 | "value": 489 818 | } 819 | }, 820 | { 821 | "__struct_id": 0, 822 | "LIST": { 823 | "type": "list", 824 | "value": [ 825 | { 826 | "__struct_id": 0, 827 | "ID": { 828 | "type": "byte", 829 | "value": 43 830 | }, 831 | "STRREF": { 832 | "type": "dword", 833 | "value": 6774 834 | } 835 | }, 836 | { 837 | "__struct_id": 0, 838 | "ID": { 839 | "type": "byte", 840 | "value": 44 841 | }, 842 | "STRREF": { 843 | "type": "dword", 844 | "value": 6819 845 | } 846 | }, 847 | { 848 | "__struct_id": 0, 849 | "ID": { 850 | "type": "byte", 851 | "value": 45 852 | }, 853 | "STRREF": { 854 | "type": "dword", 855 | "value": 6820 856 | } 857 | }, 858 | { 859 | "__struct_id": 0, 860 | "ID": { 861 | "type": "byte", 862 | "value": 62 863 | }, 864 | "STRREF": { 865 | "type": "dword", 866 | "value": 6821 867 | } 868 | } 869 | ] 870 | }, 871 | "STRREF": { 872 | "type": "dword", 873 | "value": 6818 874 | } 875 | }, 876 | { 877 | "__struct_id": 0, 878 | "ID": { 879 | "type": "byte", 880 | "value": 52 881 | }, 882 | "STRREF": { 883 | "type": "dword", 884 | "value": 494 885 | } 886 | } 887 | ] 888 | }, 889 | "STRREF": { 890 | "type": "dword", 891 | "value": 500 892 | } 893 | } 894 | ] 895 | } 896 | } 897 | -------------------------------------------------------------------------------- /src/demo/module.ifo.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "IFO ", 3 | "Expansion_Pack": { 4 | "type": "word", 5 | "value": 3 6 | }, 7 | "Mod_Area_list": { 8 | "type": "list", 9 | "value": [ 10 | { 11 | "__struct_id": 6, 12 | "Area_Name": { 13 | "type": "resref", 14 | "value": "startingarea" 15 | } 16 | } 17 | ] 18 | }, 19 | "Mod_Creator_ID": { 20 | "type": "int", 21 | "value": 2 22 | }, 23 | "Mod_CustomTlk": { 24 | "type": "cexostring", 25 | "value": "" 26 | }, 27 | "Mod_CutSceneList": { 28 | "type": "list", 29 | "value": [] 30 | }, 31 | "Mod_DawnHour": { 32 | "type": "byte", 33 | "value": 6 34 | }, 35 | "Mod_Description": { 36 | "type": "cexolocstring", 37 | "value": { 38 | "0": "" 39 | } 40 | }, 41 | "Mod_DuskHour": { 42 | "type": "byte", 43 | "value": 18 44 | }, 45 | "Mod_Entry_Area": { 46 | "type": "resref", 47 | "value": "startingarea" 48 | }, 49 | "Mod_Entry_Dir_X": { 50 | "type": "float", 51 | "value": 0.0 52 | }, 53 | "Mod_Entry_Dir_Y": { 54 | "type": "float", 55 | "value": 1.0 56 | }, 57 | "Mod_Entry_X": { 58 | "type": "float", 59 | "value": 10.0 60 | }, 61 | "Mod_Entry_Y": { 62 | "type": "float", 63 | "value": 10.0 64 | }, 65 | "Mod_Entry_Z": { 66 | "type": "float", 67 | "value": 0.0 68 | }, 69 | "Mod_Expan_List": { 70 | "type": "list", 71 | "value": [] 72 | }, 73 | "Mod_GVar_List": { 74 | "type": "list", 75 | "value": [] 76 | }, 77 | "Mod_HakList": { 78 | "type": "list", 79 | "value": [] 80 | }, 81 | "Mod_IsSaveGame": { 82 | "type": "byte", 83 | "value": 0 84 | }, 85 | "Mod_MinGameVer": { 86 | "type": "cexostring", 87 | "value": "1.83" 88 | }, 89 | "Mod_MinPerHour": { 90 | "type": "byte", 91 | "value": 2 92 | }, 93 | "Mod_Name": { 94 | "type": "cexolocstring", 95 | "value": { 96 | "0": "core_framework" 97 | } 98 | }, 99 | "Mod_OnAcquirItem": { 100 | "type": "resref", 101 | "value": "" 102 | }, 103 | "Mod_OnActvtItem": { 104 | "type": "resref", 105 | "value": "" 106 | }, 107 | "Mod_OnClientEntr": { 108 | "type": "resref", 109 | "value": "" 110 | }, 111 | "Mod_OnClientLeav": { 112 | "type": "resref", 113 | "value": "" 114 | }, 115 | "Mod_OnCutsnAbort": { 116 | "type": "resref", 117 | "value": "" 118 | }, 119 | "Mod_OnHeartbeat": { 120 | "type": "resref", 121 | "value": "" 122 | }, 123 | "Mod_OnModLoad": { 124 | "type": "resref", 125 | "value": "hook_nwn" 126 | }, 127 | "Mod_OnModStart": { 128 | "type": "resref", 129 | "value": "" 130 | }, 131 | "Mod_OnPlrChat": { 132 | "type": "resref", 133 | "value": "" 134 | }, 135 | "Mod_OnPlrDeath": { 136 | "type": "resref", 137 | "value": "" 138 | }, 139 | "Mod_OnPlrDying": { 140 | "type": "resref", 141 | "value": "" 142 | }, 143 | "Mod_OnPlrEqItm": { 144 | "type": "resref", 145 | "value": "" 146 | }, 147 | "Mod_OnPlrLvlUp": { 148 | "type": "resref", 149 | "value": "" 150 | }, 151 | "Mod_OnPlrRest": { 152 | "type": "resref", 153 | "value": "" 154 | }, 155 | "Mod_OnPlrUnEqItm": { 156 | "type": "resref", 157 | "value": "" 158 | }, 159 | "Mod_OnSpawnBtnDn": { 160 | "type": "resref", 161 | "value": "" 162 | }, 163 | "Mod_OnUnAqreItem": { 164 | "type": "resref", 165 | "value": "" 166 | }, 167 | "Mod_OnUsrDefined": { 168 | "type": "resref", 169 | "value": "" 170 | }, 171 | "Mod_StartDay": { 172 | "type": "byte", 173 | "value": 1 174 | }, 175 | "Mod_StartHour": { 176 | "type": "byte", 177 | "value": 13 178 | }, 179 | "Mod_StartMonth": { 180 | "type": "byte", 181 | "value": 6 182 | }, 183 | "Mod_StartMovie": { 184 | "type": "resref", 185 | "value": "" 186 | }, 187 | "Mod_StartYear": { 188 | "type": "dword", 189 | "value": 1372 190 | }, 191 | "Mod_Tag": { 192 | "type": "cexostring", 193 | "value": "MODULE" 194 | }, 195 | "Mod_Version": { 196 | "type": "dword", 197 | "value": 3 198 | }, 199 | "Mod_XPScale": { 200 | "type": "byte", 201 | "value": 10 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /src/demo/module.jrl.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "JRL ", 3 | "Categories": { 4 | "type": "list", 5 | "value": [ 6 | { 7 | "__struct_id": 0, 8 | "Comment": { 9 | "type": "cexostring", 10 | "value": "" 11 | }, 12 | "EntryList": { 13 | "type": "list", 14 | "value": [ 15 | { 16 | "__struct_id": 0, 17 | "End": { 18 | "type": "word", 19 | "value": 0 20 | }, 21 | "ID": { 22 | "type": "dword", 23 | "value": 1 24 | }, 25 | "Text": { 26 | "type": "cexolocstring", 27 | "value": { 28 | "0": "Test entry 1" 29 | } 30 | } 31 | }, 32 | { 33 | "__struct_id": 1, 34 | "End": { 35 | "type": "word", 36 | "value": 0 37 | }, 38 | "ID": { 39 | "type": "dword", 40 | "value": 2 41 | }, 42 | "Text": { 43 | "type": "cexolocstring", 44 | "value": { 45 | "0": "Test entry 2" 46 | } 47 | } 48 | } 49 | ] 50 | }, 51 | "Name": { 52 | "type": "cexolocstring", 53 | "value": { 54 | "0": "PQJ Test Entry" 55 | } 56 | }, 57 | "Picture": { 58 | "type": "word", 59 | "value": 65535 60 | }, 61 | "Priority": { 62 | "type": "dword", 63 | "value": 4 64 | }, 65 | "Tag": { 66 | "type": "cexostring", 67 | "value": "test" 68 | }, 69 | "XP": { 70 | "type": "dword", 71 | "value": 0 72 | } 73 | } 74 | ] 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/demo/placeablepalcus.itp.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "ITP ", 3 | "MAIN": { 4 | "type": "list", 5 | "value": [ 6 | { 7 | "__struct_id": 0, 8 | "ID": { 9 | "type": "byte", 10 | "value": 7 11 | }, 12 | "STRREF": { 13 | "type": "dword", 14 | "value": 6783 15 | } 16 | }, 17 | { 18 | "__struct_id": 0, 19 | "ID": { 20 | "type": "byte", 21 | "value": 22 22 | }, 23 | "STRREF": { 24 | "type": "dword", 25 | "value": 111663 26 | } 27 | }, 28 | { 29 | "__struct_id": 0, 30 | "ID": { 31 | "type": "byte", 32 | "value": 6 33 | }, 34 | "STRREF": { 35 | "type": "dword", 36 | "value": 6782 37 | } 38 | }, 39 | { 40 | "__struct_id": 0, 41 | "ID": { 42 | "type": "byte", 43 | "value": 8 44 | }, 45 | "STRREF": { 46 | "type": "dword", 47 | "value": 6784 48 | } 49 | }, 50 | { 51 | "__struct_id": 0, 52 | "ID": { 53 | "type": "byte", 54 | "value": 9 55 | }, 56 | "STRREF": { 57 | "type": "dword", 58 | "value": 1592 59 | } 60 | }, 61 | { 62 | "__struct_id": 0, 63 | "ID": { 64 | "type": "byte", 65 | "value": 10 66 | }, 67 | "STRREF": { 68 | "type": "dword", 69 | "value": 6785 70 | } 71 | }, 72 | { 73 | "__struct_id": 0, 74 | "ID": { 75 | "type": "byte", 76 | "value": 11 77 | }, 78 | "STRREF": { 79 | "type": "dword", 80 | "value": 6786 81 | } 82 | }, 83 | { 84 | "__struct_id": 0, 85 | "ID": { 86 | "type": "byte", 87 | "value": 12 88 | }, 89 | "STRREF": { 90 | "type": "dword", 91 | "value": 6787 92 | } 93 | }, 94 | { 95 | "__struct_id": 0, 96 | "ID": { 97 | "type": "byte", 98 | "value": 14 99 | }, 100 | "STRREF": { 101 | "type": "dword", 102 | "value": 9122 103 | } 104 | }, 105 | { 106 | "__struct_id": 0, 107 | "ID": { 108 | "type": "byte", 109 | "value": 15 110 | }, 111 | "STRREF": { 112 | "type": "dword", 113 | "value": 9128 114 | } 115 | }, 116 | { 117 | "__struct_id": 0, 118 | "LIST": { 119 | "type": "list", 120 | "value": [ 121 | { 122 | "__struct_id": 0, 123 | "ID": { 124 | "type": "byte", 125 | "value": 0 126 | }, 127 | "STRREF": { 128 | "type": "dword", 129 | "value": 6688 130 | } 131 | }, 132 | { 133 | "__struct_id": 0, 134 | "ID": { 135 | "type": "byte", 136 | "value": 1 137 | }, 138 | "STRREF": { 139 | "type": "dword", 140 | "value": 6689 141 | } 142 | }, 143 | { 144 | "__struct_id": 0, 145 | "ID": { 146 | "type": "byte", 147 | "value": 2 148 | }, 149 | "STRREF": { 150 | "type": "dword", 151 | "value": 6690 152 | } 153 | }, 154 | { 155 | "__struct_id": 0, 156 | "ID": { 157 | "type": "byte", 158 | "value": 3 159 | }, 160 | "STRREF": { 161 | "type": "dword", 162 | "value": 6691 163 | } 164 | }, 165 | { 166 | "__struct_id": 0, 167 | "ID": { 168 | "type": "byte", 169 | "value": 4 170 | }, 171 | "STRREF": { 172 | "type": "dword", 173 | "value": 6692 174 | } 175 | } 176 | ] 177 | }, 178 | "STRREF": { 179 | "type": "dword", 180 | "value": 6687 181 | } 182 | }, 183 | { 184 | "__struct_id": 0, 185 | "ID": { 186 | "type": "byte", 187 | "value": 13 188 | }, 189 | "STRREF": { 190 | "type": "dword", 191 | "value": 6788 192 | } 193 | }, 194 | { 195 | "__struct_id": 0, 196 | "ID": { 197 | "type": "byte", 198 | "value": 16 199 | }, 200 | "LIST": { 201 | "type": "list", 202 | "value": [ 203 | { 204 | "__struct_id": 0, 205 | "ID": { 206 | "type": "byte", 207 | "value": 17 208 | }, 209 | "STRREF": { 210 | "type": "dword", 211 | "value": 62485 212 | } 213 | }, 214 | { 215 | "__struct_id": 0, 216 | "ID": { 217 | "type": "byte", 218 | "value": 19 219 | }, 220 | "STRREF": { 221 | "type": "dword", 222 | "value": 5836 223 | } 224 | }, 225 | { 226 | "__struct_id": 0, 227 | "ID": { 228 | "type": "byte", 229 | "value": 21 230 | }, 231 | "STRREF": { 232 | "type": "dword", 233 | "value": 67585 234 | } 235 | }, 236 | { 237 | "__struct_id": 0, 238 | "ID": { 239 | "type": "byte", 240 | "value": 20 241 | }, 242 | "STRREF": { 243 | "type": "dword", 244 | "value": 53151 245 | } 246 | }, 247 | { 248 | "__struct_id": 0, 249 | "ID": { 250 | "type": "byte", 251 | "value": 18 252 | }, 253 | "STRREF": { 254 | "type": "dword", 255 | "value": 67132 256 | } 257 | } 258 | ] 259 | }, 260 | "STRREF": { 261 | "type": "dword", 262 | "value": 66490 263 | } 264 | }, 265 | { 266 | "__struct_id": 0, 267 | "ID": { 268 | "type": "byte", 269 | "value": 5 270 | }, 271 | "STRREF": { 272 | "type": "dword", 273 | "value": 6781 274 | } 275 | } 276 | ] 277 | } 278 | } 279 | -------------------------------------------------------------------------------- /src/demo/repute.fac.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "FAC ", 3 | "FactionList": { 4 | "type": "list", 5 | "value": [ 6 | { 7 | "__struct_id": 0, 8 | "FactionGlobal": { 9 | "type": "word", 10 | "value": 1 11 | }, 12 | "FactionName": { 13 | "type": "cexostring", 14 | "value": "PC" 15 | }, 16 | "FactionParentID": { 17 | "type": "dword", 18 | "value": 4294967295 19 | } 20 | }, 21 | { 22 | "__struct_id": 1, 23 | "FactionGlobal": { 24 | "type": "word", 25 | "value": 1 26 | }, 27 | "FactionName": { 28 | "type": "cexostring", 29 | "value": "Hostile" 30 | }, 31 | "FactionParentID": { 32 | "type": "dword", 33 | "value": 4294967295 34 | } 35 | }, 36 | { 37 | "__struct_id": 2, 38 | "FactionGlobal": { 39 | "type": "word", 40 | "value": 1 41 | }, 42 | "FactionName": { 43 | "type": "cexostring", 44 | "value": "Commoner" 45 | }, 46 | "FactionParentID": { 47 | "type": "dword", 48 | "value": 4294967295 49 | } 50 | }, 51 | { 52 | "__struct_id": 3, 53 | "FactionGlobal": { 54 | "type": "word", 55 | "value": 1 56 | }, 57 | "FactionName": { 58 | "type": "cexostring", 59 | "value": "Merchant" 60 | }, 61 | "FactionParentID": { 62 | "type": "dword", 63 | "value": 4294967295 64 | } 65 | }, 66 | { 67 | "__struct_id": 4, 68 | "FactionGlobal": { 69 | "type": "word", 70 | "value": 1 71 | }, 72 | "FactionName": { 73 | "type": "cexostring", 74 | "value": "Defender" 75 | }, 76 | "FactionParentID": { 77 | "type": "dword", 78 | "value": 4294967295 79 | } 80 | } 81 | ] 82 | }, 83 | "RepList": { 84 | "type": "list", 85 | "value": [ 86 | { 87 | "__struct_id": 0, 88 | "FactionID1": { 89 | "type": "dword", 90 | "value": 0 91 | }, 92 | "FactionID2": { 93 | "type": "dword", 94 | "value": 1 95 | }, 96 | "FactionRep": { 97 | "type": "dword", 98 | "value": 0 99 | } 100 | }, 101 | { 102 | "__struct_id": 1, 103 | "FactionID1": { 104 | "type": "dword", 105 | "value": 0 106 | }, 107 | "FactionID2": { 108 | "type": "dword", 109 | "value": 2 110 | }, 111 | "FactionRep": { 112 | "type": "dword", 113 | "value": 50 114 | } 115 | }, 116 | { 117 | "__struct_id": 2, 118 | "FactionID1": { 119 | "type": "dword", 120 | "value": 0 121 | }, 122 | "FactionID2": { 123 | "type": "dword", 124 | "value": 3 125 | }, 126 | "FactionRep": { 127 | "type": "dword", 128 | "value": 50 129 | } 130 | }, 131 | { 132 | "__struct_id": 3, 133 | "FactionID1": { 134 | "type": "dword", 135 | "value": 0 136 | }, 137 | "FactionID2": { 138 | "type": "dword", 139 | "value": 4 140 | }, 141 | "FactionRep": { 142 | "type": "dword", 143 | "value": 50 144 | } 145 | }, 146 | { 147 | "__struct_id": 4, 148 | "FactionID1": { 149 | "type": "dword", 150 | "value": 1 151 | }, 152 | "FactionID2": { 153 | "type": "dword", 154 | "value": 1 155 | }, 156 | "FactionRep": { 157 | "type": "dword", 158 | "value": 100 159 | } 160 | }, 161 | { 162 | "__struct_id": 5, 163 | "FactionID1": { 164 | "type": "dword", 165 | "value": 1 166 | }, 167 | "FactionID2": { 168 | "type": "dword", 169 | "value": 2 170 | }, 171 | "FactionRep": { 172 | "type": "dword", 173 | "value": 0 174 | } 175 | }, 176 | { 177 | "__struct_id": 6, 178 | "FactionID1": { 179 | "type": "dword", 180 | "value": 1 181 | }, 182 | "FactionID2": { 183 | "type": "dword", 184 | "value": 3 185 | }, 186 | "FactionRep": { 187 | "type": "dword", 188 | "value": 0 189 | } 190 | }, 191 | { 192 | "__struct_id": 7, 193 | "FactionID1": { 194 | "type": "dword", 195 | "value": 1 196 | }, 197 | "FactionID2": { 198 | "type": "dword", 199 | "value": 4 200 | }, 201 | "FactionRep": { 202 | "type": "dword", 203 | "value": 0 204 | } 205 | }, 206 | { 207 | "__struct_id": 8, 208 | "FactionID1": { 209 | "type": "dword", 210 | "value": 2 211 | }, 212 | "FactionID2": { 213 | "type": "dword", 214 | "value": 1 215 | }, 216 | "FactionRep": { 217 | "type": "dword", 218 | "value": 0 219 | } 220 | }, 221 | { 222 | "__struct_id": 9, 223 | "FactionID1": { 224 | "type": "dword", 225 | "value": 2 226 | }, 227 | "FactionID2": { 228 | "type": "dword", 229 | "value": 2 230 | }, 231 | "FactionRep": { 232 | "type": "dword", 233 | "value": 100 234 | } 235 | }, 236 | { 237 | "__struct_id": 10, 238 | "FactionID1": { 239 | "type": "dword", 240 | "value": 2 241 | }, 242 | "FactionID2": { 243 | "type": "dword", 244 | "value": 3 245 | }, 246 | "FactionRep": { 247 | "type": "dword", 248 | "value": 50 249 | } 250 | }, 251 | { 252 | "__struct_id": 11, 253 | "FactionID1": { 254 | "type": "dword", 255 | "value": 2 256 | }, 257 | "FactionID2": { 258 | "type": "dword", 259 | "value": 4 260 | }, 261 | "FactionRep": { 262 | "type": "dword", 263 | "value": 100 264 | } 265 | }, 266 | { 267 | "__struct_id": 12, 268 | "FactionID1": { 269 | "type": "dword", 270 | "value": 3 271 | }, 272 | "FactionID2": { 273 | "type": "dword", 274 | "value": 1 275 | }, 276 | "FactionRep": { 277 | "type": "dword", 278 | "value": 0 279 | } 280 | }, 281 | { 282 | "__struct_id": 13, 283 | "FactionID1": { 284 | "type": "dword", 285 | "value": 3 286 | }, 287 | "FactionID2": { 288 | "type": "dword", 289 | "value": 2 290 | }, 291 | "FactionRep": { 292 | "type": "dword", 293 | "value": 50 294 | } 295 | }, 296 | { 297 | "__struct_id": 14, 298 | "FactionID1": { 299 | "type": "dword", 300 | "value": 3 301 | }, 302 | "FactionID2": { 303 | "type": "dword", 304 | "value": 3 305 | }, 306 | "FactionRep": { 307 | "type": "dword", 308 | "value": 100 309 | } 310 | }, 311 | { 312 | "__struct_id": 15, 313 | "FactionID1": { 314 | "type": "dword", 315 | "value": 3 316 | }, 317 | "FactionID2": { 318 | "type": "dword", 319 | "value": 4 320 | }, 321 | "FactionRep": { 322 | "type": "dword", 323 | "value": 100 324 | } 325 | }, 326 | { 327 | "__struct_id": 16, 328 | "FactionID1": { 329 | "type": "dword", 330 | "value": 4 331 | }, 332 | "FactionID2": { 333 | "type": "dword", 334 | "value": 1 335 | }, 336 | "FactionRep": { 337 | "type": "dword", 338 | "value": 0 339 | } 340 | }, 341 | { 342 | "__struct_id": 17, 343 | "FactionID1": { 344 | "type": "dword", 345 | "value": 4 346 | }, 347 | "FactionID2": { 348 | "type": "dword", 349 | "value": 2 350 | }, 351 | "FactionRep": { 352 | "type": "dword", 353 | "value": 50 354 | } 355 | }, 356 | { 357 | "__struct_id": 18, 358 | "FactionID1": { 359 | "type": "dword", 360 | "value": 4 361 | }, 362 | "FactionID2": { 363 | "type": "dword", 364 | "value": 3 365 | }, 366 | "FactionRep": { 367 | "type": "dword", 368 | "value": 100 369 | } 370 | }, 371 | { 372 | "__struct_id": 19, 373 | "FactionID1": { 374 | "type": "dword", 375 | "value": 4 376 | }, 377 | "FactionID2": { 378 | "type": "dword", 379 | "value": 4 380 | }, 381 | "FactionRep": { 382 | "type": "dword", 383 | "value": 100 384 | } 385 | } 386 | ] 387 | } 388 | } 389 | -------------------------------------------------------------------------------- /src/demo/soundpalcus.itp.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "ITP ", 3 | "MAIN": { 4 | "type": "list", 5 | "value": [ 6 | { 7 | "__struct_id": 0, 8 | "ID": { 9 | "type": "byte", 10 | "value": 6 11 | }, 12 | "STRREF": { 13 | "type": "dword", 14 | "value": 6694 15 | } 16 | }, 17 | { 18 | "__struct_id": 0, 19 | "ID": { 20 | "type": "byte", 21 | "value": 13 22 | }, 23 | "STRREF": { 24 | "type": "dword", 25 | "value": 63289 26 | } 27 | }, 28 | { 29 | "__struct_id": 0, 30 | "ID": { 31 | "type": "byte", 32 | "value": 12 33 | }, 34 | "STRREF": { 35 | "type": "dword", 36 | "value": 62487 37 | } 38 | }, 39 | { 40 | "__struct_id": 0, 41 | "ID": { 42 | "type": "byte", 43 | "value": 7 44 | }, 45 | "STRREF": { 46 | "type": "dword", 47 | "value": 62483 48 | } 49 | }, 50 | { 51 | "__struct_id": 0, 52 | "ID": { 53 | "type": "byte", 54 | "value": 5 55 | }, 56 | "STRREF": { 57 | "type": "dword", 58 | "value": 62482 59 | } 60 | }, 61 | { 62 | "__struct_id": 0, 63 | "LIST": { 64 | "type": "list", 65 | "value": [ 66 | { 67 | "__struct_id": 0, 68 | "ID": { 69 | "type": "byte", 70 | "value": 0 71 | }, 72 | "STRREF": { 73 | "type": "dword", 74 | "value": 6688 75 | } 76 | }, 77 | { 78 | "__struct_id": 0, 79 | "ID": { 80 | "type": "byte", 81 | "value": 1 82 | }, 83 | "STRREF": { 84 | "type": "dword", 85 | "value": 6689 86 | } 87 | }, 88 | { 89 | "__struct_id": 0, 90 | "ID": { 91 | "type": "byte", 92 | "value": 2 93 | }, 94 | "STRREF": { 95 | "type": "dword", 96 | "value": 6690 97 | } 98 | }, 99 | { 100 | "__struct_id": 0, 101 | "ID": { 102 | "type": "byte", 103 | "value": 3 104 | }, 105 | "STRREF": { 106 | "type": "dword", 107 | "value": 6691 108 | } 109 | }, 110 | { 111 | "__struct_id": 0, 112 | "ID": { 113 | "type": "byte", 114 | "value": 4 115 | }, 116 | "STRREF": { 117 | "type": "dword", 118 | "value": 6692 119 | } 120 | } 121 | ] 122 | }, 123 | "STRREF": { 124 | "type": "dword", 125 | "value": 6687 126 | } 127 | }, 128 | { 129 | "__struct_id": 0, 130 | "ID": { 131 | "type": "byte", 132 | "value": 8 133 | }, 134 | "STRREF": { 135 | "type": "dword", 136 | "value": 62484 137 | } 138 | } 139 | ] 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/demo/startingarea.are.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "ARE ", 3 | "ChanceLightning": { 4 | "type": "int", 5 | "value": 0 6 | }, 7 | "ChanceRain": { 8 | "type": "int", 9 | "value": 0 10 | }, 11 | "ChanceSnow": { 12 | "type": "int", 13 | "value": 0 14 | }, 15 | "Comments": { 16 | "type": "cexostring", 17 | "value": "" 18 | }, 19 | "Creator_ID": { 20 | "type": "int", 21 | "value": -1 22 | }, 23 | "DayNightCycle": { 24 | "type": "byte", 25 | "value": 1 26 | }, 27 | "Expansion_List": { 28 | "type": "list", 29 | "value": [] 30 | }, 31 | "Flags": { 32 | "type": "dword", 33 | "value": 4 34 | }, 35 | "FogClipDist": { 36 | "type": "float", 37 | "value": 45.0 38 | }, 39 | "Height": { 40 | "type": "int", 41 | "value": 2 42 | }, 43 | "ID": { 44 | "type": "int", 45 | "value": -1 46 | }, 47 | "IsNight": { 48 | "type": "byte", 49 | "value": 0 50 | }, 51 | "LightingScheme": { 52 | "type": "byte", 53 | "value": 0 54 | }, 55 | "LoadScreenID": { 56 | "type": "word", 57 | "value": 0 58 | }, 59 | "ModListenCheck": { 60 | "type": "int", 61 | "value": 0 62 | }, 63 | "ModSpotCheck": { 64 | "type": "int", 65 | "value": 0 66 | }, 67 | "MoonAmbientColor": { 68 | "type": "dword", 69 | "value": 0 70 | }, 71 | "MoonDiffuseColor": { 72 | "type": "dword", 73 | "value": 13132900 74 | }, 75 | "MoonFogAmount": { 76 | "type": "byte", 77 | "value": 0 78 | }, 79 | "MoonFogColor": { 80 | "type": "dword", 81 | "value": 6566450 82 | }, 83 | "MoonShadows": { 84 | "type": "byte", 85 | "value": 1 86 | }, 87 | "Name": { 88 | "type": "cexolocstring", 89 | "value": { 90 | "0": "Starting Area" 91 | } 92 | }, 93 | "NoRest": { 94 | "type": "byte", 95 | "value": 0 96 | }, 97 | "OnEnter": { 98 | "type": "resref", 99 | "value": "hook_nwn" 100 | }, 101 | "OnExit": { 102 | "type": "resref", 103 | "value": "" 104 | }, 105 | "OnHeartbeat": { 106 | "type": "resref", 107 | "value": "" 108 | }, 109 | "OnUserDefined": { 110 | "type": "resref", 111 | "value": "" 112 | }, 113 | "PlayerVsPlayer": { 114 | "type": "byte", 115 | "value": 3 116 | }, 117 | "ResRef": { 118 | "type": "resref", 119 | "value": "startingarea" 120 | }, 121 | "ShadowOpacity": { 122 | "type": "byte", 123 | "value": 50 124 | }, 125 | "SkyBox": { 126 | "type": "byte", 127 | "value": 0 128 | }, 129 | "SunAmbientColor": { 130 | "type": "dword", 131 | "value": 6566450 132 | }, 133 | "SunDiffuseColor": { 134 | "type": "dword", 135 | "value": 16777215 136 | }, 137 | "SunFogAmount": { 138 | "type": "byte", 139 | "value": 0 140 | }, 141 | "SunFogColor": { 142 | "type": "dword", 143 | "value": 9535080 144 | }, 145 | "SunShadows": { 146 | "type": "byte", 147 | "value": 1 148 | }, 149 | "Tag": { 150 | "type": "cexostring", 151 | "value": "StartingArea" 152 | }, 153 | "Tile_List": { 154 | "type": "list", 155 | "value": [ 156 | { 157 | "__struct_id": 1, 158 | "Tile_AnimLoop1": { 159 | "type": "byte", 160 | "value": 1 161 | }, 162 | "Tile_AnimLoop2": { 163 | "type": "byte", 164 | "value": 1 165 | }, 166 | "Tile_AnimLoop3": { 167 | "type": "byte", 168 | "value": 1 169 | }, 170 | "Tile_Height": { 171 | "type": "int", 172 | "value": 0 173 | }, 174 | "Tile_ID": { 175 | "type": "int", 176 | "value": 12 177 | }, 178 | "Tile_MainLight1": { 179 | "type": "byte", 180 | "value": 0 181 | }, 182 | "Tile_MainLight2": { 183 | "type": "byte", 184 | "value": 0 185 | }, 186 | "Tile_Orientation": { 187 | "type": "int", 188 | "value": 3 189 | }, 190 | "Tile_SrcLight1": { 191 | "type": "byte", 192 | "value": 0 193 | }, 194 | "Tile_SrcLight2": { 195 | "type": "byte", 196 | "value": 0 197 | } 198 | }, 199 | { 200 | "__struct_id": 1, 201 | "Tile_AnimLoop1": { 202 | "type": "byte", 203 | "value": 1 204 | }, 205 | "Tile_AnimLoop2": { 206 | "type": "byte", 207 | "value": 1 208 | }, 209 | "Tile_AnimLoop3": { 210 | "type": "byte", 211 | "value": 1 212 | }, 213 | "Tile_Height": { 214 | "type": "int", 215 | "value": 0 216 | }, 217 | "Tile_ID": { 218 | "type": "int", 219 | "value": 12 220 | }, 221 | "Tile_MainLight1": { 222 | "type": "byte", 223 | "value": 0 224 | }, 225 | "Tile_MainLight2": { 226 | "type": "byte", 227 | "value": 0 228 | }, 229 | "Tile_Orientation": { 230 | "type": "int", 231 | "value": 0 232 | }, 233 | "Tile_SrcLight1": { 234 | "type": "byte", 235 | "value": 0 236 | }, 237 | "Tile_SrcLight2": { 238 | "type": "byte", 239 | "value": 0 240 | } 241 | }, 242 | { 243 | "__struct_id": 1, 244 | "Tile_AnimLoop1": { 245 | "type": "byte", 246 | "value": 1 247 | }, 248 | "Tile_AnimLoop2": { 249 | "type": "byte", 250 | "value": 1 251 | }, 252 | "Tile_AnimLoop3": { 253 | "type": "byte", 254 | "value": 1 255 | }, 256 | "Tile_Height": { 257 | "type": "int", 258 | "value": 0 259 | }, 260 | "Tile_ID": { 261 | "type": "int", 262 | "value": 12 263 | }, 264 | "Tile_MainLight1": { 265 | "type": "byte", 266 | "value": 0 267 | }, 268 | "Tile_MainLight2": { 269 | "type": "byte", 270 | "value": 0 271 | }, 272 | "Tile_Orientation": { 273 | "type": "int", 274 | "value": 3 275 | }, 276 | "Tile_SrcLight1": { 277 | "type": "byte", 278 | "value": 0 279 | }, 280 | "Tile_SrcLight2": { 281 | "type": "byte", 282 | "value": 0 283 | } 284 | }, 285 | { 286 | "__struct_id": 1, 287 | "Tile_AnimLoop1": { 288 | "type": "byte", 289 | "value": 1 290 | }, 291 | "Tile_AnimLoop2": { 292 | "type": "byte", 293 | "value": 1 294 | }, 295 | "Tile_AnimLoop3": { 296 | "type": "byte", 297 | "value": 1 298 | }, 299 | "Tile_Height": { 300 | "type": "int", 301 | "value": 0 302 | }, 303 | "Tile_ID": { 304 | "type": "int", 305 | "value": 12 306 | }, 307 | "Tile_MainLight1": { 308 | "type": "byte", 309 | "value": 0 310 | }, 311 | "Tile_MainLight2": { 312 | "type": "byte", 313 | "value": 0 314 | }, 315 | "Tile_Orientation": { 316 | "type": "int", 317 | "value": 3 318 | }, 319 | "Tile_SrcLight1": { 320 | "type": "byte", 321 | "value": 0 322 | }, 323 | "Tile_SrcLight2": { 324 | "type": "byte", 325 | "value": 0 326 | } 327 | } 328 | ] 329 | }, 330 | "Tileset": { 331 | "type": "resref", 332 | "value": "tms01" 333 | }, 334 | "Width": { 335 | "type": "int", 336 | "value": 2 337 | }, 338 | "WindPower": { 339 | "type": "int", 340 | "value": 0 341 | } 342 | } 343 | -------------------------------------------------------------------------------- /src/demo/startingarea.gic.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "GIC ", 3 | "Creature List": { 4 | "type": "list", 5 | "value": [ 6 | { 7 | "__struct_id": 4, 8 | "Comment": { 9 | "type": "cexostring", 10 | "value": "" 11 | } 12 | }, 13 | { 14 | "__struct_id": 4, 15 | "Comment": { 16 | "type": "cexostring", 17 | "value": "" 18 | } 19 | } 20 | ] 21 | }, 22 | "Door List": { 23 | "type": "list", 24 | "value": [] 25 | }, 26 | "Encounter List": { 27 | "type": "list", 28 | "value": [] 29 | }, 30 | "List": { 31 | "type": "list", 32 | "value": [] 33 | }, 34 | "Placeable List": { 35 | "type": "list", 36 | "value": [ 37 | { 38 | "__struct_id": 9, 39 | "Comment": { 40 | "type": "cexostring", 41 | "value": "" 42 | } 43 | }, 44 | { 45 | "__struct_id": 9, 46 | "Comment": { 47 | "type": "cexostring", 48 | "value": "" 49 | } 50 | }, 51 | { 52 | "__struct_id": 9, 53 | "Comment": { 54 | "type": "cexostring", 55 | "value": "" 56 | } 57 | } 58 | ] 59 | }, 60 | "SoundList": { 61 | "type": "list", 62 | "value": [] 63 | }, 64 | "StoreList": { 65 | "type": "list", 66 | "value": [] 67 | }, 68 | "TriggerList": { 69 | "type": "list", 70 | "value": [] 71 | }, 72 | "WaypointList": { 73 | "type": "list", 74 | "value": [] 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/demo/storepalcus.itp.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "ITP ", 3 | "MAIN": { 4 | "type": "list", 5 | "value": [ 6 | { 7 | "__struct_id": 0, 8 | "ID": { 9 | "type": "byte", 10 | "value": 5 11 | }, 12 | "STRREF": { 13 | "type": "dword", 14 | "value": 6789 15 | } 16 | }, 17 | { 18 | "__struct_id": 0, 19 | "LIST": { 20 | "type": "list", 21 | "value": [ 22 | { 23 | "__struct_id": 0, 24 | "ID": { 25 | "type": "byte", 26 | "value": 0 27 | }, 28 | "STRREF": { 29 | "type": "dword", 30 | "value": 6688 31 | } 32 | }, 33 | { 34 | "__struct_id": 0, 35 | "ID": { 36 | "type": "byte", 37 | "value": 1 38 | }, 39 | "STRREF": { 40 | "type": "dword", 41 | "value": 6689 42 | } 43 | }, 44 | { 45 | "__struct_id": 0, 46 | "ID": { 47 | "type": "byte", 48 | "value": 2 49 | }, 50 | "STRREF": { 51 | "type": "dword", 52 | "value": 6690 53 | } 54 | }, 55 | { 56 | "__struct_id": 0, 57 | "ID": { 58 | "type": "byte", 59 | "value": 3 60 | }, 61 | "STRREF": { 62 | "type": "dword", 63 | "value": 6691 64 | } 65 | }, 66 | { 67 | "__struct_id": 0, 68 | "ID": { 69 | "type": "byte", 70 | "value": 4 71 | }, 72 | "STRREF": { 73 | "type": "dword", 74 | "value": 6692 75 | } 76 | } 77 | ] 78 | }, 79 | "STRREF": { 80 | "type": "dword", 81 | "value": 6687 82 | } 83 | } 84 | ] 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/demo/triggerpalcus.itp.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "ITP ", 3 | "MAIN": { 4 | "type": "list", 5 | "value": [ 6 | { 7 | "__struct_id": 0, 8 | "ID": { 9 | "type": "byte", 10 | "value": 5 11 | }, 12 | "STRREF": { 13 | "type": "dword", 14 | "value": 1082 15 | } 16 | }, 17 | { 18 | "__struct_id": 0, 19 | "ID": { 20 | "type": "byte", 21 | "value": 6 22 | }, 23 | "STRREF": { 24 | "type": "dword", 25 | "value": 6790 26 | } 27 | }, 28 | { 29 | "__struct_id": 0, 30 | "ID": { 31 | "type": "byte", 32 | "value": 16 33 | }, 34 | "STRREF": { 35 | "type": "dword", 36 | "value": 9129 37 | } 38 | }, 39 | { 40 | "__struct_id": 0, 41 | "LIST": { 42 | "type": "list", 43 | "value": [ 44 | { 45 | "__struct_id": 0, 46 | "ID": { 47 | "type": "byte", 48 | "value": 0 49 | }, 50 | "STRREF": { 51 | "type": "dword", 52 | "value": 6688 53 | } 54 | }, 55 | { 56 | "__struct_id": 0, 57 | "ID": { 58 | "type": "byte", 59 | "value": 1 60 | }, 61 | "STRREF": { 62 | "type": "dword", 63 | "value": 6689 64 | } 65 | }, 66 | { 67 | "__struct_id": 0, 68 | "ID": { 69 | "type": "byte", 70 | "value": 2 71 | }, 72 | "STRREF": { 73 | "type": "dword", 74 | "value": 6690 75 | } 76 | }, 77 | { 78 | "__struct_id": 0, 79 | "ID": { 80 | "type": "byte", 81 | "value": 3 82 | }, 83 | "STRREF": { 84 | "type": "dword", 85 | "value": 6691 86 | } 87 | }, 88 | { 89 | "__struct_id": 0, 90 | "ID": { 91 | "type": "byte", 92 | "value": 4 93 | }, 94 | "STRREF": { 95 | "type": "dword", 96 | "value": 6692 97 | } 98 | } 99 | ] 100 | }, 101 | "STRREF": { 102 | "type": "dword", 103 | "value": 6687 104 | } 105 | }, 106 | { 107 | "__struct_id": 0, 108 | "LIST": { 109 | "type": "list", 110 | "value": [ 111 | { 112 | "__struct_id": 0, 113 | "ID": { 114 | "type": "byte", 115 | "value": 11 116 | }, 117 | "STRREF": { 118 | "type": "dword", 119 | "value": 53181 120 | } 121 | }, 122 | { 123 | "__struct_id": 0, 124 | "ID": { 125 | "type": "byte", 126 | "value": 12 127 | }, 128 | "STRREF": { 129 | "type": "dword", 130 | "value": 2255 131 | } 132 | }, 133 | { 134 | "__struct_id": 0, 135 | "ID": { 136 | "type": "byte", 137 | "value": 13 138 | }, 139 | "STRREF": { 140 | "type": "dword", 141 | "value": 2256 142 | } 143 | }, 144 | { 145 | "__struct_id": 0, 146 | "ID": { 147 | "type": "byte", 148 | "value": 14 149 | }, 150 | "STRREF": { 151 | "type": "dword", 152 | "value": 2257 153 | } 154 | }, 155 | { 156 | "__struct_id": 0, 157 | "ID": { 158 | "type": "byte", 159 | "value": 15 160 | }, 161 | "STRREF": { 162 | "type": "dword", 163 | "value": 53182 164 | } 165 | } 166 | ] 167 | }, 168 | "STRREF": { 169 | "type": "dword", 170 | "value": 5563 171 | } 172 | } 173 | ] 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/demo/waypointpalcus.itp.json: -------------------------------------------------------------------------------- 1 | { 2 | "__data_type": "ITP ", 3 | "MAIN": { 4 | "type": "list", 5 | "value": [ 6 | { 7 | "__struct_id": 0, 8 | "LIST": { 9 | "type": "list", 10 | "value": [ 11 | { 12 | "__struct_id": 0, 13 | "ID": { 14 | "type": "byte", 15 | "value": 0 16 | }, 17 | "STRREF": { 18 | "type": "dword", 19 | "value": 6688 20 | } 21 | }, 22 | { 23 | "__struct_id": 0, 24 | "ID": { 25 | "type": "byte", 26 | "value": 1 27 | }, 28 | "STRREF": { 29 | "type": "dword", 30 | "value": 6689 31 | } 32 | }, 33 | { 34 | "__struct_id": 0, 35 | "ID": { 36 | "type": "byte", 37 | "value": 2 38 | }, 39 | "STRREF": { 40 | "type": "dword", 41 | "value": 6690 42 | } 43 | }, 44 | { 45 | "__struct_id": 0, 46 | "ID": { 47 | "type": "byte", 48 | "value": 3 49 | }, 50 | "STRREF": { 51 | "type": "dword", 52 | "value": 6691 53 | } 54 | }, 55 | { 56 | "__struct_id": 0, 57 | "ID": { 58 | "type": "byte", 59 | "value": 4 60 | }, 61 | "STRREF": { 62 | "type": "dword", 63 | "value": 6692 64 | } 65 | } 66 | ] 67 | }, 68 | "STRREF": { 69 | "type": "dword", 70 | "value": 6687 71 | } 72 | }, 73 | { 74 | "__struct_id": 0, 75 | "ID": { 76 | "type": "byte", 77 | "value": 5 78 | }, 79 | "STRREF": { 80 | "type": "dword", 81 | "value": 6798 82 | } 83 | } 84 | ] 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/plugins/chat/chat_c_config.nss: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------- 2 | // File: chat_c_config.nss 3 | // System: Chat Command System 4 | // URL: https://github.com/squattingmonk/nwn-core-framework 5 | // Authors: Edward A. Burke (tinygiant) 6 | // ----------------------------------------------------------------------------- 7 | // This file contains user-definable toggles and settings for the chat command 8 | // system. 9 | // ----------------------------------------------------------------------------- 10 | 11 | // Delimiters must be single characters; multiple consecutive delimiters will be 12 | // ignored. If a delimiter is passed that is greater than one character, the 13 | // first character will be used. 14 | const string CHAT_DELIMITER = " "; 15 | 16 | // This string contains characters used to designate a chat command. If a chat 17 | // message uses one of these characters as its first character, it will be 18 | // treated as a command. Do not use "-", "=", ":", any characters in 19 | // CHAT_GROUPS below, or any normal alphanumeric characters. 20 | const string CHAT_DESIGNATORS = "!@#$%^&*;,./?`~|\\"; 21 | 22 | // This string contains pairs of characters used to group words into a single 23 | // parameter. Grouping characters must be paired and, if necessary, escaped. 24 | // Unpaired grouping characters will result in grouping functions being lost and 25 | // error provided in log. Do not use "-", "=", ":", any characters in 26 | // CHAT_COMMAND_DESIGNATORS above, or any normal alphanumeric characters. 27 | const string CHAT_GROUPS = "``{}[]()<>"; 28 | 29 | // To keep grouping symbols as part of the returned data, set this to FALSE. 30 | const int REMOVE_GROUPING_SYMBOLS = TRUE; 31 | 32 | // To force logging of all chat commands, set this to TRUE. 33 | const int LOG_ALL_CHAT_COMMANDS = TRUE; 34 | 35 | // To force logging of all chat command results that are not errors, set this to 36 | // TRUE. 37 | const int LOG_ALL_CHAT_RESULTS = TRUE; 38 | -------------------------------------------------------------------------------- /src/plugins/chat/chat_l_plugin.nss: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------- 2 | // File: chat_l_plugin.nss 3 | // System: Chat Command System (library script) 4 | // URL: https://github.com/squattingmonk/nwn-core-framework 5 | // Authors: Edward A. Burke (tinygiant) 6 | // ----------------------------------------------------------------------------- 7 | 8 | #include "util_i_library" 9 | #include "chat_i_main" 10 | #include "core_i_framework" 11 | 12 | // ----------------------------------------------------------------------------- 13 | // OnPlayerChat 14 | // ----------------------------------------------------------------------------- 15 | 16 | void chat_OnPlayerChat() 17 | { 18 | object oPC = GetPCChatSpeaker(); 19 | string sMessage = GetPCChatMessage(); 20 | 21 | if (ParseCommandLine(oPC, sMessage)) 22 | { 23 | SetPCChatMessage(); 24 | string sDesignator = GetChatDesignator(oPC); 25 | string sCommand = GetChatCommand(oPC); 26 | 27 | int nState = RunEvent(CHAT_PREFIX + sDesignator, oPC); 28 | if (!(nState & EVENT_STATE_DENIED)) 29 | RunEvent(CHAT_PREFIX + sDesignator + sCommand, oPC); 30 | } 31 | } 32 | 33 | // ----------------------------------------------------------------------------- 34 | // Library Dispatch 35 | // ----------------------------------------------------------------------------- 36 | 37 | void OnLibraryLoad() 38 | { 39 | if (!GetIfPluginExists("chat")) 40 | { 41 | object oPlugin = CreatePlugin("chat"); 42 | SetName(oPlugin, "[Plugin] Chat Command System"); 43 | SetDescription(oPlugin, 44 | "Allows players and DMs to run commands via the chat bar"); 45 | RegisterEventScript(oPlugin, MODULE_EVENT_ON_PLAYER_CHAT, 46 | "chat_OnPlayerChat", EVENT_PRIORITY_FIRST); 47 | } 48 | 49 | RegisterLibraryScript("chat_OnPlayerChat", 1); 50 | } 51 | 52 | void OnLibraryScript(string sScript, int nEntry) 53 | { 54 | switch (nEntry) 55 | { 56 | case 1: chat_OnPlayerChat(); break; 57 | default: CriticalError("Library function " + sScript + " not found"); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/plugins/dialogs/dlg_l_plugin.nss: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------- 2 | // File: dlg_l_plugin.nss 3 | // System: Dynamic Dialogs (library script) 4 | // URL: https://github.com/squattingmonk/nwn-core-framework 5 | // Authors: Michael A. Sinclair (Squatting Monk) 6 | // ----------------------------------------------------------------------------- 7 | // This library contains hook-in scripts for the Dynamic Dialogs plugin. If the 8 | // Dynamic Dialogs plugin is activated, these scripts will fire on the 9 | // appropriate events. 10 | // ----------------------------------------------------------------------------- 11 | 12 | #include "core_i_framework" 13 | #include "dlg_i_dialogs" 14 | #include "util_i_color" 15 | #include "util_i_library" 16 | 17 | // ----------------------------------------------------------------------------- 18 | // Event Hook-In Scripts 19 | // ----------------------------------------------------------------------------- 20 | 21 | // ----- WrapDialog ------------------------------------------------------------ 22 | // Starts a dialog between the calling object and the PC that triggered the 23 | // event being executed. Only valid when being called by an event queue. 24 | // ----- Variables ------------------------------------------------------------- 25 | // string "*Dialog": The name of the dialog script (library or otherwise) 26 | // int "*Private": Whether the dialog should be hidden from other players. 27 | // int "*NoHello": Prevent the NPC from saying hello on dialog start 28 | // int "*NoZoom": Prevent camera from zooming in on dialog start 29 | // ----- Aliases --------------------------------------------------------------- 30 | 31 | void WrapDialog(int bGhost = FALSE) 32 | { 33 | // Get the PC that triggered the event. This information is pulled off the 34 | // event queue since we don't know which event is calling us. 35 | object oPC = GetEventTriggeredBy(); 36 | 37 | if (!GetIsPC(oPC)) 38 | return; 39 | 40 | string sDialog = GetLocalString(OBJECT_SELF, DLG_DIALOG); 41 | int bPrivate = GetLocalInt (OBJECT_SELF, DLG_PRIVATE); 42 | int bNoHello = GetLocalInt (OBJECT_SELF, DLG_NO_HELLO); 43 | int bNoZoom = GetLocalInt (OBJECT_SELF, DLG_NO_ZOOM); 44 | 45 | StartDialog(oPC, OBJECT_SELF, sDialog, bPrivate, bNoHello, bNoZoom); 46 | } 47 | 48 | 49 | // ----------------------------------------------------------------------------- 50 | // Plugin Control Dialog 51 | // ----------------------------------------------------------------------------- 52 | // This dialog allows users to view and modify Core Framework Plugins. 53 | // ----------------------------------------------------------------------------- 54 | 55 | const string PLUGIN_DIALOG = "PluginControlDialog"; 56 | const string PLUGIN_PAGE = "Plugin: "; 57 | const string PLUGIN_PAGE_MAIN = "Plugin List"; 58 | const string PLUGIN_PAGE_FAIL = "Not Authorized"; 59 | const string PLUGIN_ACTIVATE = "Activate Plugin"; 60 | const string PLUGIN_DEACTIVATE = "Deactivate Plugin"; 61 | 62 | // Adds a dummy page for a plugin if it does not already exist 63 | string AddPluginPage(string sPlugin) 64 | { 65 | string sPage = PLUGIN_PAGE + sPlugin; 66 | if (!HasDialogPage(sPage)) 67 | { 68 | AddDialogPage(sPage, "Plugin: \nStatus: \n\n", sPlugin); 69 | AddDialogNode(sPage, sPage, "Activate plugin", PLUGIN_ACTIVATE); 70 | AddDialogNode(sPage, sPage, "Deactivate plugin", PLUGIN_DEACTIVATE); 71 | SetDialogTarget(PLUGIN_PAGE_MAIN, sPage, DLG_NODE_BACK); 72 | } 73 | 74 | return sPage; 75 | } 76 | 77 | string PluginStatusText(int nStatus) 78 | { 79 | switch (nStatus) 80 | { 81 | case PLUGIN_STATUS_OFF: 82 | return HexColorString("[Inactive]", COLOR_GRAY); 83 | case PLUGIN_STATUS_ON: 84 | return HexColorString("[Active]", COLOR_GREEN); 85 | //case PLUGIN_STATUS_MISSING: 86 | // return HexColorString("[Missing]", COLOR_RED); 87 | } 88 | 89 | return ""; 90 | } 91 | 92 | void PluginControl_Init() 93 | { 94 | EnableDialogNode(DLG_NODE_BACK); 95 | EnableDialogNode(DLG_NODE_END); 96 | 97 | AddDialogToken("Plugin"); 98 | AddDialogToken("Status"); 99 | AddDialogToken("Description"); 100 | SetDialogPage(PLUGIN_PAGE_MAIN); 101 | AddDialogPage(PLUGIN_PAGE_MAIN, 102 | "This dialog allows you to manage the plugins in the Core Framework. " + 103 | "To manage a plugin, click its name below.\n\nThe following plugins " + 104 | "are installed:"); 105 | SetDialogLabel(DLG_NODE_BACK, "[Refresh]", PLUGIN_PAGE_MAIN); 106 | 107 | string sPlugin, sPage; 108 | int i, nCount = CountStringList(PLUGINS); 109 | for (i; i < nCount; i++) 110 | { 111 | sPlugin = GetListString(PLUGINS, i); 112 | AddPluginPage(sPlugin); 113 | } 114 | 115 | AddDialogPage(PLUGIN_PAGE_FAIL, "Sorry, but only a DM can use this."); 116 | DisableDialogNode(DLG_NODE_BACK, PLUGIN_PAGE_FAIL); 117 | } 118 | 119 | void PluginControl_Page() 120 | { 121 | object oPC = GetPCSpeaker(); 122 | 123 | if (!GetIsDM(oPC)) 124 | { 125 | SetDialogPage(PLUGIN_PAGE_FAIL); 126 | return; 127 | } 128 | 129 | string sPage = GetDialogPage(); 130 | 131 | if (sPage == PLUGIN_PAGE_MAIN) 132 | { 133 | // Delete the old plugin list 134 | DeleteDialogNodes(PLUGIN_PAGE_MAIN); 135 | 136 | // Build the list of plugins 137 | object oPlugin; 138 | string sPlugin, sText, sTarget; 139 | int i, nStatus, nCount = CountObjectList(PLUGINS); 140 | 141 | for (i; i < nCount; i++) 142 | { 143 | oPlugin = GetListObject(PLUGINS, i); 144 | sPlugin = GetListString(PLUGINS, i); 145 | sTarget = AddPluginPage(sPlugin); 146 | nStatus = GetIsPluginActivated(oPlugin); 147 | sText = sPlugin + " " + PluginStatusText(nStatus); 148 | AddDialogNode(PLUGIN_PAGE_MAIN, sTarget, sText); 149 | } 150 | 151 | return; 152 | } 153 | 154 | // The page is for a plugin 155 | string sPlugin = GetDialogData(sPage); 156 | object oPlugin = GetPlugin(sPlugin); 157 | int nStatus = GetIsPluginActivated(oPlugin); 158 | switch (nStatus) 159 | { 160 | case PLUGIN_STATUS_OFF: 161 | case PLUGIN_STATUS_ON: 162 | FilterDialogNodes(!nStatus); break; 163 | default: 164 | FilterDialogNodes(0, CountDialogNodes(sPage) - 1); 165 | } 166 | 167 | CacheDialogToken("Plugin", sPlugin); 168 | CacheDialogToken("Status", PluginStatusText(nStatus)); 169 | CacheDialogToken("Description", GetDescription(oPlugin)); 170 | } 171 | 172 | void PluginControl_Node() 173 | { 174 | string sPage = GetDialogPage(); 175 | string sPrefix = GetStringLeft(sPage, GetStringLength(PLUGIN_PAGE)); 176 | 177 | if (sPrefix == PLUGIN_PAGE) 178 | { 179 | int nNode = GetDialogNode(); 180 | string sData = GetDialogData(sPage, nNode); 181 | string sPlugin = GetDialogData(sPage); 182 | 183 | if (sData == PLUGIN_ACTIVATE) 184 | ActivatePlugin(sPlugin); 185 | else if (sData == PLUGIN_DEACTIVATE) 186 | DeactivatePlugin(sPlugin); 187 | } 188 | } 189 | 190 | // ----------------------------------------------------------------------------- 191 | // Library Dispatch 192 | // ----------------------------------------------------------------------------- 193 | 194 | void OnLibraryLoad() 195 | { 196 | // Plugin setup 197 | if (!GetIfPluginExists("dlg")) 198 | { 199 | object oPlugin = CreatePlugin("dlg"); 200 | SetName(oPlugin, "[Plugin] Dynamic Dialogs"); 201 | SetDescription(oPlugin, 202 | "This plugin allows the creation and launching of script-driven dialogs."); 203 | LoadLibraries("dlg_l_tokens, dlg_l_demo"); 204 | } 205 | 206 | // Event scripts 207 | RegisterLibraryScript("StartDialog", 0x0100+0x01); 208 | RegisterLibraryScript("StartGhostDialog", 0x0100+0x02); 209 | 210 | // Plugin Control Dialog 211 | RegisterLibraryScript("PluginControl_Init", 0x0200+0x01); 212 | RegisterLibraryScript("PluginControl_Page", 0x0200+0x02); 213 | RegisterLibraryScript("PluginControl_Node", 0x0200+0x03); 214 | 215 | RegisterDialogScript(PLUGIN_DIALOG, "PluginControl_Init", DLG_EVENT_INIT, DLG_PRIORITY_FIRST); 216 | RegisterDialogScript(PLUGIN_DIALOG, "PluginControl_Page", DLG_EVENT_PAGE); 217 | RegisterDialogScript(PLUGIN_DIALOG, "PluginControl_Node", DLG_EVENT_NODE); 218 | } 219 | 220 | void OnLibraryScript(string sScript, int nEntry) 221 | { 222 | switch (nEntry & 0xff00) 223 | { 224 | case 0x0100: 225 | switch (nEntry & 0x00ff) 226 | { 227 | case 0x01: WrapDialog(); break; 228 | case 0x02: WrapDialog(TRUE); break; 229 | } break; 230 | 231 | case 0x0200: 232 | switch (nEntry & 0x00ff) 233 | { 234 | case 0x01: PluginControl_Init(); break; 235 | case 0x02: PluginControl_Page(); break; 236 | case 0x03: PluginControl_Node(); break; 237 | } break; 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /src/plugins/pqj/pqj_i_main.nss: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------- 2 | // File: pqj_i_main.nss 3 | // System: Persistent Quests and Journals (include script) 4 | // URL: https://github.com/squattingmonk/nwn-core-framework 5 | // Authors: Michael A. Sinclair (Squatting Monk) 6 | // ----------------------------------------------------------------------------- 7 | // This is the main include file for the Persistent Quests and Journals plugin. 8 | // ----------------------------------------------------------------------------- 9 | 10 | #include "util_i_debug" 11 | #include "util_i_sqlite" 12 | 13 | // ----------------------------------------------------------------------------- 14 | // Function Prototypes 15 | // ----------------------------------------------------------------------------- 16 | 17 | // ---< pqj_CreateTable >--- 18 | // ---< pqj_i_main >--- 19 | // Creates a table for PQJ quest data in oPC's persistent SQLite database. If 20 | // bForce is true, will drop any existing table before creating a new one. 21 | void pqj_CreateTable(object oPC, int bForce = FALSE); 22 | 23 | // ---< pqj_RestoreJournalEntries >--- 24 | // ---< pqj_i_main >--- 25 | // Restores all journal entries from oPC's persistent SQLite database. This 26 | // should be called once OnClientEnter. Ensure the table has been created using 27 | // pqj_CreateTable() before calling this. 28 | void pqj_RestoreJournalEntries(object oPC); 29 | 30 | // ---< pqj_GetQuestState >--- 31 | // ---< pqj_i_main >--- 32 | // Returns the state of a quest for the PC. This matches a plot ID and number 33 | // from the journal. Returns 0 if the quest has not been started. 34 | int pqj_GetQuestState(string sPlotID, object oPC); 35 | 36 | // ---< pqj_AddJournalQuestEntry >--- 37 | // ---< pqj_i_main >--- 38 | // As AddJournalQuestEntry(), but stores the quest state in the database so it 39 | // can be restored after a server reset. 40 | void pqj_AddJournalQuestEntry(string sPlotID, int nState, object oPC, int bAllPartyMembers = TRUE, int bAllPlayers = FALSE, int bAllowOverrideHigher = FALSE); 41 | 42 | // ---< pqj_RemoveJournalQuestEntry >--- 43 | // ---< pqj_i_main >--- 44 | // As RemoveJournalQuestEntry(), but removes the quest from the database so it 45 | // will not be restored after a server reset. 46 | void pqj_RemoveJournalQuestEntry(string sPlotID, object oPC, int bAllPartyMembers = TRUE, int bAllPlayers = FALSE); 47 | 48 | // ----------------------------------------------------------------------------- 49 | // Funcion Definitions 50 | // ----------------------------------------------------------------------------- 51 | 52 | void pqj_CreateTable(object oPC, int bForce = FALSE) 53 | { 54 | if (!GetIsPC(oPC) || GetIsDM(oPC)) 55 | return; 56 | 57 | Debug("Creating table pqjdata on " + GetName(oPC)); 58 | SqlCreateTablePC(oPC, "pqjdata", 59 | "quest TEXT NOT NULL PRIMARY KEY, " + 60 | "state INTEGER NOT NULL DEFAULT 0", bForce); 61 | } 62 | 63 | void pqj_RestoreJournalEntries(object oPC) 64 | { 65 | if (!GetIsPC(oPC) || GetIsDM(oPC)) 66 | return; 67 | 68 | int nState; 69 | string sPlotID; 70 | string sName = GetName(oPC); 71 | string sQuery = "SELECT quest, state FROM pqjdata"; 72 | sqlquery qQuery = SqlPrepareQueryObject(oPC, sQuery); 73 | while (SqlStep(qQuery)) 74 | { 75 | sPlotID = SqlGetString(qQuery, 0); 76 | nState = SqlGetInt(qQuery, 1); 77 | Debug("Restoring journal entry; PC: " + sName + ", " + 78 | "PlotID: " + sPlotID + "; PlotState: " + IntToString(nState)); 79 | AddJournalQuestEntry(sPlotID, nState, oPC, FALSE); 80 | } 81 | } 82 | 83 | int pqj_GetQuestState(string sPlotID, object oPC) 84 | { 85 | if (!GetIsPC(oPC) || GetIsDM(oPC)) 86 | return 0; 87 | 88 | string sQuery = "SELECT state FROM pqjdata WHERE quest=@quest;"; 89 | sqlquery qQuery = SqlPrepareQueryObject(oPC, sQuery); 90 | SqlBindString(qQuery, "@quest", sPlotID); 91 | if (SqlStep(qQuery)) 92 | return SqlGetInt(qQuery, 0); 93 | 94 | return 0; 95 | } 96 | 97 | // Internal function for pqj_AddJournalQuestEntry(). 98 | void _StoreQuestEntry(string sPlotID, int nState, object oPC, int bAllowOverrideHigher = FALSE) 99 | { 100 | string sMessage = "persistent journal entry for " + GetName(oPC) + "; " + 101 | "sPlotID: " + sPlotID + "; nState: " + IntToString(nState); 102 | string sQuery = "INSERT INTO pqjdata (quest, state) " + 103 | "VALUES (@quest, @state) ON CONFLICT (quest) DO UPDATE SET state = " + 104 | (bAllowOverrideHigher ? "@state" : "MAX(state, @state)") + ";"; 105 | sqlquery qQuery = SqlPrepareQueryObject(oPC, sQuery); 106 | SqlBindString(qQuery, "@quest", sPlotID); 107 | SqlBindInt(qQuery, "@state", nState); 108 | SqlStep(qQuery); 109 | 110 | string sError = SqlGetError(qQuery); 111 | if (sError == "") 112 | Debug("Adding " + sMessage); 113 | else 114 | CriticalError("Could not add " + sMessage + ": " + sError); 115 | } 116 | 117 | void pqj_AddJournalQuestEntry(string sPlotID, int nState, object oPC, int bAllPartyMembers = TRUE, int bAllPlayers = FALSE, int bAllowOverrideHigher = FALSE) 118 | { 119 | if (!GetIsPC(oPC)) 120 | return; 121 | 122 | AddJournalQuestEntry(sPlotID, nState, oPC, bAllPartyMembers, bAllPlayers, bAllowOverrideHigher); 123 | 124 | if (bAllPlayers) 125 | { 126 | Debug("Adding journal entry " + sPlotID + " for all players"); 127 | oPC = GetFirstPC(); 128 | while (GetIsObjectValid(oPC)) 129 | { 130 | _StoreQuestEntry(sPlotID, nState, oPC, bAllowOverrideHigher); 131 | oPC = GetNextPC(); 132 | } 133 | } 134 | else if (bAllPartyMembers) 135 | { 136 | Debug("Adding journal entry " + sPlotID + " for " + GetName(oPC) + 137 | "'s party members"); 138 | object oPartyMember = GetFirstFactionMember(oPC, TRUE); 139 | while (GetIsObjectValid(oPartyMember)) 140 | { 141 | _StoreQuestEntry(sPlotID, nState, oPartyMember, bAllowOverrideHigher); 142 | oPartyMember = GetNextFactionMember(oPC, TRUE); 143 | } 144 | } 145 | else 146 | _StoreQuestEntry(sPlotID, nState, oPC, bAllowOverrideHigher); 147 | } 148 | 149 | // Internal function for pqj_RemoveJournalQuestEntry() 150 | void _DeleteQuestEntry(string sPlotID, object oPC) 151 | { 152 | string sName = GetName(oPC); 153 | string sMessage = "persistent journal entry for " + sName + "; " + 154 | "PlotID: " + sPlotID; 155 | 156 | string sQuery = "DELETE FROM pqjdata WHERE quest=@quest;"; 157 | sqlquery qQuery = SqlPrepareQueryObject(oPC, sQuery); 158 | SqlBindString(qQuery, "@quest", sPlotID); 159 | SqlStep(qQuery); 160 | 161 | string sError = SqlGetError(qQuery); 162 | if (sError == "") 163 | Debug("Removed " + sMessage); 164 | else 165 | CriticalError("Could not remove " + sMessage + ": " + sError); 166 | } 167 | 168 | void pqj_RemoveJournalQuestEntry(string sPlotID, object oPC, int bAllPartyMembers = TRUE, int bAllPlayers = FALSE) 169 | { 170 | RemoveJournalQuestEntry(sPlotID, oPC, bAllPartyMembers, bAllPlayers); 171 | 172 | if (bAllPlayers) 173 | { 174 | Debug("Removing journal entry " + sPlotID + " for all players"); 175 | oPC = GetFirstPC(); 176 | while (GetIsObjectValid(oPC)) 177 | { 178 | _DeleteQuestEntry(sPlotID, oPC); 179 | oPC = GetNextPC(); 180 | } 181 | } 182 | else if (bAllPartyMembers) 183 | { 184 | Debug("Removing journal entry " + sPlotID + " for " + GetName(oPC) + 185 | "'s party members"); 186 | object oPartyMember = GetFirstFactionMember(oPC, TRUE); 187 | while (GetIsObjectValid(oPartyMember)) 188 | { 189 | _DeleteQuestEntry(sPlotID, oPartyMember); 190 | oPartyMember = GetNextFactionMember(oPC, TRUE); 191 | } 192 | } 193 | else 194 | _DeleteQuestEntry(sPlotID, oPC); 195 | } 196 | -------------------------------------------------------------------------------- /src/plugins/pqj/pqj_l_plugin.nss: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------------- 2 | // File: pqj_l_plugin.nss 3 | // System: Persistent Quests and Journals (library script) 4 | // URL: https://github.com/squattingmonk/nwn-core-framework 5 | // Authors: Michael A. Sinclair (Squatting Monk) 6 | // ----------------------------------------------------------------------------- 7 | // This library script contains scripts to hook in to Core Framework events. 8 | // ----------------------------------------------------------------------------- 9 | 10 | #include "util_i_library" 11 | #include "core_i_framework" 12 | #include "pqj_i_main" 13 | 14 | // ----------------------------------------------------------------------------- 15 | // Library Dispatch 16 | // ----------------------------------------------------------------------------- 17 | 18 | void OnLibraryLoad() 19 | { 20 | if (!GetIfPluginExists("pqj")) 21 | { 22 | object oPlugin = CreatePlugin("pqj"); 23 | SetName(oPlugin, "[Plugin] Persistent Quests and Journals"); 24 | SetDescription(oPlugin, 25 | "This plugin allows database-driven persistent journal entries."); 26 | 27 | RegisterEventScript(oPlugin, MODULE_EVENT_ON_CLIENT_ENTER, "pqj_RestoreJournalEntries"); 28 | } 29 | 30 | RegisterLibraryScript("pqj_RestoreJournalEntries", 1); 31 | } 32 | 33 | void OnLibraryScript(string sScript, int nEntry) 34 | { 35 | switch (nEntry) 36 | { 37 | case 1: 38 | { 39 | object oPC = GetEventTriggeredBy(); 40 | pqj_CreateTable(oPC); 41 | pqj_RestoreJournalEntries(oPC); 42 | } break; 43 | default: CriticalError("Library function " + sScript + " not found"); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/plugins/targeting/target_l_plugin.nss: -------------------------------------------------------------------------------- 1 | /// ---------------------------------------------------------------------------- 2 | /// @file target_l_plugin.nss 3 | /// @author Ed Burke (tinygiant98) 4 | /// @brief Event scripts to integrate player targeting into the 5 | /// core framework 6 | /// ---------------------------------------------------------------------------- 7 | 8 | #include "util_i_library" 9 | #include "util_i_targeting" 10 | #include "core_i_framework" 11 | 12 | // ----------------------------------------------------------------------------- 13 | // Event Scripts 14 | // ----------------------------------------------------------------------------- 15 | 16 | /// @brief Creates the required targeting hook and data tables in the 17 | /// module's volatile sqlite database. 18 | void targeting_OnModuleLoad() 19 | { 20 | CreateTargetingDataTables(TRUE); 21 | } 22 | 23 | /// @brief Checks the targeting player for a current hook. If found, executes 24 | /// the targeting event and denies further OnPlayerTarget scripts. 25 | void targeting_OnPlayerTarget() 26 | { 27 | object oPC = GetLastPlayerToSelectTarget(); 28 | 29 | if (SatisfyTargetingHook(oPC)) 30 | SetEventState(EVENT_STATE_ABORT); 31 | } 32 | 33 | // ----------------------------------------------------------------------------- 34 | // Library Dispatch 35 | // ----------------------------------------------------------------------------- 36 | 37 | void OnLibraryLoad() 38 | { 39 | if (!GetIfPluginExists("targeting")) 40 | { 41 | object oPlugin = CreatePlugin("targeting"); 42 | SetName(oPlugin, "[Plugin] Player Targeting System"); 43 | SetDescription(oPlugin, "Manages forced player targeting mode and target lists."); 44 | SetDebugPrefix(HexColorString("[Targeting]", COLOR_CORAL_LIGHT), oPlugin); 45 | 46 | RegisterEventScript(oPlugin, MODULE_EVENT_ON_MODULE_LOAD, "targeting_OnModuleLoad"); 47 | RegisterEventScript(oPlugin, MODULE_EVENT_ON_PLAYER_TARGET, "targeting_OnPlayerTarget", EVENT_PRIORITY_FIRST); 48 | } 49 | 50 | RegisterLibraryScript("targeting_OnModuleLoad", 1); 51 | RegisterLibraryScript("targeting_OnPlayerTarget", 2); 52 | } 53 | 54 | void OnLibraryScript(string sScript, int nEntry) 55 | { 56 | switch (nEntry) 57 | { 58 | case 1: targeting_OnModuleLoad(); break; 59 | case 2: targeting_OnPlayerTarget(); break; 60 | default: CriticalError("Library function " + sScript + " not found"); 61 | } 62 | } 63 | --------------------------------------------------------------------------------