Updated Tar Lake interior

Updated Tar Lake interior.  Added Water Breathing to Amulet of Water Breathing.  Updated tar mephit.
This commit is contained in:
Jaysyn904
2023-08-18 23:16:27 -04:00
parent c8abdf7473
commit c0e04f09c3
44 changed files with 11274 additions and 5367 deletions

View File

@@ -0,0 +1,20 @@
void main()
{
// Get the entering object (usually a player character)
object oPC = GetEnteringObject();
// Check if the entering object is a player character and not the module itself
if (GetIsPC(oPC) && !GetIsDM(oPC))
{
// Find the nearest creature with the tag "TARMEPHIT001"
object oCreature = GetNearestObjectByTag("TARMEPHIT001", oPC);
// Check if a valid creature was found
if (GetIsObjectValid(oCreature))
{
// Make the creature say the message
SpeakString("Hey, you stay away from our tar!", TALKVOLUME_SHOUT);
}
}
}

View File

@@ -32,7 +32,7 @@ void main()
SetLocalInt(oPC, "bEnteredDungeon", 1);
//:: Fires any NESS spawners
ExecuteScript("spawn_smpl_onen2");
ExecuteScript("ra_onareaenter");
//////////////////////////////////////////////// Sparky Spawner Section
if (GetLocalInt(oArea, "sparkyloaded") != 1)

View File

@@ -0,0 +1,50 @@
/// ----------------------------------------------------------------------------
/// @file nui_c_config.nss
/// @author Ed Burke (tinygiant98) <af.hog.pilot@gmail.com>
/// @brief NUI Form Creation and Management System Configuration
/// ----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// FORM INSPECTOR
// -----------------------------------------------------------------------------
// The form inspection capability allows you to record data about a form's status,
// including bind values and how various events affect them. To use the inspection
// capability, you must include the `nui_f_inspector` formfile in your module and
// set NUI_FI_RECORD_DATA to the desired value.
// *** WARNING *** Form inspection is very expensive. Is it recommended that
// you only use the form inspection capability during debug or set this
// value to NUI_FI_WHEN_OPEN to prevent unnecessary traffic.
const int NUI_FI_NEVER = 0;
const int NUI_FI_ALWAYS = 1;
const int NUI_FI_WHEN_OPEN = 2;
const int NUI_FI_RECORD_DATA = NUI_FI_WHEN_OPEN;
// -----------------------------------------------------------------------------
// Custom Functions
// MODIFY THESE TO ENSURE COMPATIBILTY WITH YOUR MODULE'S SYSTEMS
// -----------------------------------------------------------------------------
// This system has some basic debugging functionality. In order to make this system work
// under multiple modules without collision, the following function is provided to
// allow you to call whatever debugging system you'd like to call. If you use
// squattingmonk's debug utility, no changes need to be made. The primary system does
// not provide any organic debug calls, but this function is available to all formfiles
// for debugging purposes.
//
const int NUI_DEBUG_SEVERITY_NONE = 0;
const int NUI_DEBUG_SEVERITY_CRITICAL = 1;
const int NUI_DEBUG_SEVERITY_ERROR = 2;
const int NUI_DEBUG_SEVERITY_WARNING = 3;
const int NUI_DEBUG_SEVERITY_NOTICE = 4;
const int NUI_DEBUG_SEVERITY_DEBUG = 5;
//#include "util_i_debug"
void NUI_Debug(string sMessage, int nSeverity = 4)
{
//Debug(sMessage, nSeverity);
}

View File

@@ -0,0 +1,225 @@
/// ----------------------------------------------------------------------------
/// @file nui_c_storage.nss
/// @author Ed Burke (tinygiant98) <af.hog.pilot@gmail.com>
/// @brief Persistent Storage formfile configuration settings
/// ----------------------------------------------------------------------------
/// @note Most of the following global/default settings can be overriden on a
/// per-container basis by setting a local variable on the container
/// object as noted in the setting descriptions below. Constants, such as
/// PS_TRUE, PS_NONE, etc. should be used in this configuration file, however,
/// actual values must be used when setting local overrides. Those values
/// are provided below.
/// @warning This system uses player character UUIDs. This can cause issues in
/// single-player modules if the player-character is not exported and the
/// UUID is not saved to the .bic file.
/// @brief By default, containers will be saved to a database table referenced
/// by the container object's tag. The saved item data includes the UUID
/// and CD Key of the PC that deposited the item so the same container can
/// be used for multiple PCs. To set a specific (unique) name to use as the
/// table name instead, set a local string called `PS_UNIQUE_ID` on the
/// container object and set it to any unique string.
/// @brief Determines usage of the `Search` button.
/// Configuration File:
/// PS_TRUE to force players to click the `Search` button
/// before an inventory search will commence. This is a good idea
/// for containers that you expect will have large inventories.
/// PS_FALSE to allow real-time searching as the player types
/// characters into the `Search` textbox.
/// Local Override (int): PS_FORCE_SEARCH_BUTTON
/// 1 = PS_TRUE
/// -1 = PS_FALSE
const int PS_FORCE_SEARCH_BUTTON_DEFAULT = PS_TRUE;
/// @brief Determines whether item object state is saved to the database. The
/// object state includes variables and effects.
/// Configuration File:
/// PS_TRUE saves the object state
/// PS_FALSE does not save the object state
/// Local Override (int): PS_FORCE_OBJECT_STATE
/// 1 = PS_TRUE
/// -1 = PS_FALSE
const int PS_FORCE_OBJECT_STATE_DEFAULT = PS_TRUE;
/// @brief Sets the item storage limit.
/// Configuration File:
/// PS_UNLIMITED to allow unlimited item storage.
/// Set to any positive integer to limit item storage to that amount.
/// Local Override (int): PS_STORAGE_LIMIT
/// -1 = PS_UNLIMITED
/// Set to any positive integer to limit item storage to that amount.
const int PS_STORAGE_LIMIT_DEFAULT = 500;
/// @brief Set the maximum distance (meters) a PC can travel from the container
/// before the form will auto-close.
/// Configuration File:
/// PS_UNLIMITED_DISTANCE to never auto-close the form
/// Set to any positive float to limit distance to that amount.
/// Local Override (float): PS_DISTANCE
/// -1.0 = PS_UNLIMITED_DISTANCE
/// Set to any positive float to limit distance to that amount.
const float PS_DISTANCE_DEFAULT = 5.0;
/// @brief Set the container access type. Container inventories can be accessed
/// by two methods: exclusive and contentious.
/// - Exclusive: Multiple players may open the same container, but each
/// player will only see items they've previously deposited. Players
/// may only withdraw items they've previously deposited.
/// - Contentious: Multiple players may open the same container. All
/// players will see all items deposited by any player. Any player
/// can remove any item, regardless of who originally deposited the
/// item.
///
/// Configuration File:
/// PS_ACCESS_EXCLUSIVE for exclusive access
/// PS_ACCESS_CONTENTIOUS for contentious access
/// Local Override (int): PS_ACCESS_TYPE
/// 1 = PS_ACCESS_EXCLUSIVE
/// 2 = PS_ACCESS_CONTENTIOUS
const int PS_ACCESS_TYPE_DEFAULT = PS_ACCESS_EXCLUSIVE;
/// @brief Set the container type. Containers can be of multiple types:
/// - Public: Any player can open, deposit and withdraw items from this
/// container. Whether they are limited to specific items is dependant
/// on the container's access setting.
/// - Character: Creates a 'portable' storage container for any player
/// character. Any container of this type will hold the same inventory
/// for any specific player.
/// - CD Key: Creates a 'portable' storage container for any characters
/// owned by cd-key associated with the player character. Any container
/// of this type will hold the inventory desposited by any character
/// sharing the player's cd key.
///
/// Configuration File:
/// PS_CONTAINER_PUBLIC for public.
/// PS_CONTAINER_CHARACTER for per-character.
/// PS_CONTAINER_CD_KEY for per-cdkey.
/// Local Override (int): PS_CONTAINER_TYPE
/// 1 = PS_CONTAINER_PUBLIC
/// 2 = PS_CONTAINER_CHARACTER
/// 3 = PS_CONTAINER_CDKEY
const int PS_CONTAINER_TYPE_DEFAULT = PS_CONTAINER_CDKEY;
/// @brief Set the default container type, if the container is an item. Containers
/// can be of multiple types:
/// - Public: Any player can open, deposit and withdraw items from this
/// container. Whether they are limited to specific items is dependant
/// on the container's access setting.
/// - Character: Creates a 'portable' storage container for any player
/// character. Any container of this type will hold the same inventory
/// for any specific player.
/// - CD Key: Creates a 'portable' storage container for any characters
/// owned by cd-key associated with the player character. Any container
/// of this type will hold the inventory desposited by any character
/// sharing the player's cd key.
///
/// Configuration File:
/// PS_CONTAINER_PUBLIC for public.
/// PS_CONTAINER_CHARACTER for per-character.
/// PS_CONTAINER_CD_KEY for per-cdkey.
/// Local Override (int): PS_CONTAINER_TYPE
/// 1 = PS_CONTAINER_PUBLIC
/// 2 = PS_CONTAINER_CHARACTER
/// 3 = PS_CONTAINER_CDKEY
const int PS_CONTAINER_ITEM_TYPE_DEFAULT = PS_CONTAINER_CHARACTER;
/// @brief Determines whether the player's inventory window will be opened
/// when a container is opened.
/// Configuration File:
/// PS_TRUE to open the inventory window.
/// PS_FALSE to prevent the window from opening. If the inventory
/// window is already open, this will not close it.
/// Local Override (int): PS_OPEN_INVENTORY
/// 1 = PS_TRUE
/// -1 = PS_FALSE
const int PS_OPEN_INVENTORY_DEFAULT = PS_TRUE;
/// @brief Determines the maximum amount of gold a container can store.
/// If the container is set to store no gold, the form controls that
/// manipulate gold storage will not be visible on the form.
/// Configuration File:
/// PS_UNLIMITED to allow unlimited gold storage.
/// PS_NONE to prevent gold storage.
/// Set to any positive integer to limit gold to that amount.
/// Local Override (int): PS_MAX_GOLD
/// -1 = PS_UNLIMITED
/// -2 = PS_NONE
/// Set to any positive integer to limit gold to that amount.
const int PS_MAX_GOLD_DEFAULT = 1500000;
/// @note Reference these terms for the following option:
/// Container: A persistent storage object in the game, such as a chest.
/// Container Item: An item which:
/// Can have its own inventory
/// Can be carried in a player's inventory
/// @brief Determines handling for container objects. Containers can optionally
/// store container items.
/// Configuration File:
/// PS_UNLIMITED to allow storage of an unlimited number of container items.
/// PS_NONE to prevent storage of any container items.
/// Set to any positive integer to limit storage to that number of container
/// items.
/// Local Override (int): PS_MAX_CONTAINER_TIMES
/// -1 = PS_UNLIMITED
/// -2 = PS_NONE
/// Set to any positive integer to limit storage to that number of container
/// items.
const int PS_MAX_CONTAINER_ITEMS_DEFAULT = 100;
/// @brief Determines how many items can be stored in stored container items.
/// Configuration File:
/// PS_UNLIMITED to allow storage of any number of items within a container
/// item's inventory. This will be naturally limited by the size of
/// the container item's inventory.
/// PS_NONE to prevent any items from being stored in a container item. If
/// container item storage is allow and PS_NONE is used, only empty
/// container items can be stored.
/// Set to any positive integer to limit the number of items stored in
/// the inventory of a container item.
/// Local Override (int): PS_MAX_CONTAINER_ITEMS_INVENTORY
/// -1 = PS_UNLIMITED
/// -2 = PS_NONE
/// Set to any positive integer to limit the number of items stored in
/// the inventory of a container item.
///
/// @note This configuration option has no effect if PS_MAX_CONTAINER_ITEMS_DEFAULT
/// is set to PS_NONE or its local override is set to -1.
/// @warning Items that fail check involved with container item limitations do
/// not have default messages reported to the player. The item will simply fail
/// to be stored.
const int PS_MAX_CONTAINER_ITEMS_INVENTORY_DEFAULT = 1000;
/// @brief Creates the form's title.
/// @param oContainer The container object being used.
/// @param oPC The player using oContainer.
/// @note A local string called `PS_TITLE` may be set on the object for easy
/// reference in this function. The function below is an example and may
/// be modified in any way. The returned value will be displayed as the
/// form's title.
string ps_GetFormTitle(object oContainer, object oPC, int nAccess, int nType)
{
string sTitle;
if ((sTitle = GetLocalString(oContainer, PS_TITLE)) != "")
return sTitle;
else
{
switch (nType)
{
case PS_CONTAINER_PUBLIC:
return GetTag(oContainer);
case PS_CONTAINER_CDKEY:
return GetName(oPC) + "'s Player-Specific Storage";
case PS_CONTAINER_CHARACTER:
return GetName(oPC) + "'s Character-Specific Storage";
}
if (GetIsPC(OBJECT_SELF))
return GetName(OBJECT_SELF) + "'s Storage";
}
return "Persistent Storage";
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,43 @@
/// ----------------------------------------------------------------------------
/// @file nui_i_library.nss
/// @author Ed Burke (tinygiant98) <af.hog.pilot@gmail.com>
/// @brief Boilerplate code for creating a library dispatcher. Should only be
/// included in library scripts as it implements main().
/// ----------------------------------------------------------------------------
#include "nui_i_main"
// -----------------------------------------------------------------------------
// Function Protoypes
// -----------------------------------------------------------------------------
void DefineForm();
void BindForm();
void HandleNUIEvents();
void HandleModuleEvents();
// -----------------------------------------------------------------------------
// Function Implementations
// -----------------------------------------------------------------------------
// These are dummy implementations to prevent nwnsc from complaining that they
// do not exist. If you want to compile in the toolset rather than using nwnsc,
// comment these lines out.
//#pragma default_function(DefineForm)
//#pragma default_function(BindForm)
//#pragma default_function(HandleNUIEvents)
//#pragma default_function(HandleModuleEvents)
// -----------------------------------------------------------------------------
// Library Dispatch
// -----------------------------------------------------------------------------
void main()
{
string sOperation = GetScriptParam("NUI_FUNCTION");
if (sOperation == NUI_DEFINE) DefineForm();
else if (sOperation == NUI_BIND) BindForm();
else if (sOperation == NUI_EVENT_NUI) HandleNUIEvents();
else HandleModuleEvents();
}

2741
_module/nss/nui_i_main.nss Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
#include "nui_i_main"
void main()
{
NUI();
}

View File

@@ -0,0 +1,7 @@
#include "nui_i_main"
void main()
{
NUI_HandleEvents(GetLastPlayerToSelectTarget());
}

View File

@@ -26,11 +26,11 @@ void ApplyHeatEffect(object oCreature)
{
int iHeatDam = d4(1);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectDamage(iHeatDam, DAMAGE_TYPE_FIRE), oCreature, 6.0f);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, EffectDamage(iHeatDam, DAMAGE_TYPE_FIRE), oCreature, 6.0f));
}
//:: Can't breath in tar
//:: Can't breathe in tar
void ApplySuffocationEffect(object oCreature)
{
int iConstitution = GetAbilityScore(oCreature, ABILITY_CONSTITUTION);
@@ -139,9 +139,10 @@ void main()
//:: Calculate the DC for the Strength check
int iStrengthDC = 15 + iArmorPenalty;
//:: Roll a Strength check against the DC
//:: Be an Ooze Mephit or roll a Strength check against the DC
if (GetResRef(OBJECT_SELF) != "mepooze001" &&
GetResRef(OBJECT_SELF) != "tarmephit001" ||
GetAppearanceType(oCreature) != APPEARANCE_TYPE_MEPHIT_OOZE ||
d20() + GetAbilityModifier(ABILITY_STRENGTH, oCreature) < iStrengthDC)
{
//:: Apply the other effects since the Strength check failed

View File

@@ -0,0 +1,225 @@
/// ----------------------------------------------------------------------------
/// @file util_c_color.nss
/// @author Ed Burke (tinygiant98) <af.hog.pilot@gmail.com>
/// @brief Configuration file for util_i_color.nss.
/// @details
/// These color codes are used with the functions from util_i_color.nss. These
/// are hex color codes, the same as you'd use in web design and may other
/// areas, so they are easy to look up and to copy-paste into other programs.
///
/// You can change the values of any of constants below, but do not change the
/// names of the constants themselves. You can also add your own constants for
/// use in your module.
///
/// ## Acknowledgement
/// - Function colors copied from https://nwn.wiki/display/NWN1/Colour+Tokens.
/// ----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// X11 Color Palette
// -----------------------------------------------------------------------------
// ----- Whites ----------------------------------------------------------------
const int COLOR_AZURE = 0xf0ffff;
const int COLOR_BEIGE = 0xf5f5dc;
const int COLOR_BLUE_ALICE = 0xf0f8ff;
const int COLOR_HONEYDEW = 0xf0fff0;
const int COLOR_IVORY = 0xfffff0;
const int COLOR_LAVENDERBLUSH = 0xfff0f5;
const int COLOR_LINEN = 0xfaf0e6;
const int COLOR_MINTCREAM = 0xf5fffa;
const int COLOR_MISTYROSE = 0xffe4e1;
const int COLOR_OLDLACE = 0xfdf5e6;
const int COLOR_SEASHELL = 0xfff5ee;
const int COLOR_SNOW = 0xfffafa;
const int COLOR_WHITE = 0xffffff;
const int COLOR_WHITE_ANTIQUE = 0xfaebd7;
const int COLOR_WHITE_FLORAL = 0xfffaf0;
const int COLOR_WHITE_GHOST = 0xf8f8ff;
const int COLOR_WHITE_SMOKE = 0xf5f5f5;
// ----- Blues -----------------------------------------------------------------
const int COLOR_AQUA = 0x00ffff;
const int COLOR_AQUAMARINE = 0x7fffd4;
const int COLOR_BLUE = 0x0000ff;
const int COLOR_BLUE_CORNFLOWER = 0x6495ed;
const int COLOR_BLUE_DARK = 0x00008b;
const int COLOR_BLUE_DODGER = 0x1e90ff;
const int COLOR_BLUE_LIGHT = 0xadd8e6;
const int COLOR_BLUE_MEDIUM = 0x0000cd;
const int COLOR_BLUE_MIDNIGHT = 0x191970;
const int COLOR_BLUE_POWDER = 0xb0e0e6;
const int COLOR_BLUE_ROYAL = 0x4169e1;
const int COLOR_BLUE_SKY = 0x87ceeb;
const int COLOR_BLUE_SKY_DEEP = 0x00bfff;
const int COLOR_BLUE_SKY_LIGHT = 0x87cefa;
const int COLOR_BLUE_SLATE = 0x6a5acd;
const int COLOR_BLUE_SLATE_MEDIUM = 0x7b68ee;
const int COLOR_BLUE_STEEL = 0x4682b4;
const int COLOR_BLUE_STEEL_LIGHT = 0xb0c4de;
const int COLOR_CYAN = 0x00ffff;
const int COLOR_CYAN_LIGHT = 0xe0ffff;
const int COLOR_NAVY = 0x000080;
const int COLOR_TURQUOISE = 0x40e0d0;
const int COLOR_TURQUOISE_DARK = 0x00ced1;
const int COLOR_TURQUOISE_MEDIUM = 0x48d1cc;
const int COLOR_TURQUOISE_PALE = 0xafeeee;
// ----- Browns ----------------------------------------------------------------
const int COLOR_BISQUE = 0xffe4c4;
const int COLOR_BLANCHED_ALMOND = 0xffebcd;
const int COLOR_BROWN = 0xa52a2a;
const int COLOR_BROWN_LIGHT = 0xd0814b;
const int COLOR_BROWN_ROSY = 0xbc8f8f;
const int COLOR_BROWN_SADDLE = 0x8b4513;
const int COLOR_BROWN_SANDY = 0xf4a460;
const int COLOR_BURLYWOOD = 0xdeb887;
const int COLOR_CHOCOLATE = 0xd2691e;
const int COLOR_CORNSILK = 0xfff8dc;
const int COLOR_GOLDENROD = 0xdaa520;
const int COLOR_GOLDENROD_DARK = 0xb8860b;
const int COLOR_MAROON = 0x800000;
const int COLOR_PERU = 0xcd853f;
const int COLOR_SIENNA = 0xa0522d;
const int COLOR_TAN = 0xd2b48c;
const int COLOR_WHEAT = 0xf5deb3;
const int COLOR_WHITE_NAVAJO = 0xffdead;
// ----- Purples ---------------------------------------------------------------
const int COLOR_BLUE_SLATE_DARK = 0x483d8b;
const int COLOR_BLUE_VIOLET = 0x8a2be2;
const int COLOR_FUCHSIA = 0xff00ff;
const int COLOR_INDIGO = 0x4b0082;
const int COLOR_LAVENDER = 0xe6e6fa;
const int COLOR_MAGENTA = 0xff00ff;
const int COLOR_MAGENTA_DARK = 0x8b008b;
const int COLOR_ORCHID = 0xda70d6;
const int COLOR_ORCHID_DARK = 0x9932cc;
const int COLOR_ORCHID_MEDIUM = 0xba55d3;
const int COLOR_PLUM = 0xdda0dd;
const int COLOR_PURPLE = 0x800080;
const int COLOR_PURPLE_MEDIUM = 0x9370d8;
const int COLOR_THISTLE = 0xd8bfd8;
const int COLOR_VIOLET = 0xee82ee;
const int COLOR_VIOLET_DARK = 0x9400d3;
const int COLOR_VIOLET_LIGHT = 0xf397f8;
// ----- Oranges ---------------------------------------------------------------
const int COLOR_CORAL = 0xff7f50;
const int COLOR_ORANGE = 0xffa500;
const int COLOR_ORANGE_DARK = 0xff8c00;
const int COLOR_ORANGE_LIGHT = 0xf3b800;
const int COLOR_ORANGE_RED = 0xff4500;
const int COLOR_SALMON_LIGHT = 0xffa07a;
const int COLOR_TOMATO = 0xff6347;
// ----- Reds ------------------------------------------------------------------
const int COLOR_CORAL_LIGHT = 0xf08080;
const int COLOR_CRIMSON = 0xdc143c;
const int COLOR_FIREBRICK = 0xb22222;
const int COLOR_RED = 0xff0000;
const int COLOR_RED_DARK = 0x8b0000;
const int COLOR_RED_INDIAN = 0xcd5c4c;
const int COLOR_RED_LIGHT = 0xfa6155;
const int COLOR_SALMON = 0xfa8072;
const int COLOR_SALMON_DARK = 0xe9967a;
// ----- Pinks -----------------------------------------------------------------
const int COLOR_PINK = 0xffc0cb;
const int COLOR_PINK_DEEP = 0xff1493;
const int COLOR_PINK_HOT = 0xff69b4;
const int COLOR_PINK_LIGHT = 0xffb6c1;
const int COLOR_VIOLET_RED_MEDIUM = 0xc71585;
const int COLOR_VIOLET_RED_PALE = 0xdb7093;
// ----- Grays -----------------------------------------------------------------
const int COLOR_BLACK = 0x000000;
const int COLOR_GAINSBORO = 0xdcdcdc;
const int COLOR_GRAY = 0x808080;
const int COLOR_GRAY_DARK = 0xa9a9a9;
const int COLOR_GRAY_DIM = 0x696969;
const int COLOR_GRAY_LIGHT = 0xd3d3d3;
const int COLOR_GRAY_SLATE = 0x708090;
const int COLOR_GRAY_SLATE_DARK = 0x2f4f4f;
const int COLOR_GRAY_SLATE_LIGHT = 0x778899;
const int COLOR_SILVER = 0xc0c0c0;
// ----- Greens ----------------------------------------------------------------
const int COLOR_AQUAMARINE_MEDIUM = 0x66cdaa;
const int COLOR_CHARTREUSE = 0x7fff00;
const int COLOR_CYAN_DARK = 0x008b8b;
const int COLOR_GREEN = 0x008000;
const int COLOR_GREEN_DARK = 0x006400;
const int COLOR_GREEN_FOREST = 0x228b22;
const int COLOR_GREEN_LAWN = 0x7cfc00;
const int COLOR_GREEN_LIGHT = 0x90ee90;
const int COLOR_GREEN_LIME = 0x32cd32;
const int COLOR_GREEN_OLIVE_DARK = 0x556b2f;
const int COLOR_GREEN_PALE = 0x98fb98;
const int COLOR_GREEN_SEA = 0x2e8b57;
const int COLOR_GREEN_SEA_DARK = 0x8fbc8f;
const int COLOR_GREEN_SEA_LIGHT = 0x20b2aa;
const int COLOR_GREEN_SEA_MEDIUM = 0x3cb371;
const int COLOR_GREEN_SPRING = 0x00ff7f;
const int COLOR_GREEN_SPRING_MEDIUM = 0x00fa9a;
const int COLOR_GREEN_YELLOW = 0xadff2f;
const int COLOR_LIME = 0x00ff00;
const int COLOR_OLIVE = 0x808000;
const int COLOR_OLIVE_DRAB = 0x6b8e23;
const int COLOR_TEAL = 0x008080;
const int COLOR_YELLOW_GREEN = 0x9acd32;
// ----- Yellows ---------------------------------------------------------------
const int COLOR_GOLD = 0xffd700;
const int COLOR_GOLDENROD_LIGHT = 0xfafad2;
const int COLOR_GOLDENROD_PALE = 0xeee8aa;
const int COLOR_KHAKI = 0xf0e68c;
const int COLOR_KHAKI_DARK = 0xbdb76b;
const int COLOR_LEMON_CHIFFON = 0xfffacd;
const int COLOR_MOCCASIN = 0xffe4b5;
const int COLOR_PAPAYA_WHIP = 0xffefd5;
const int COLOR_PEACH_PUFF = 0xffdab9;
const int COLOR_YELLOW = 0xffff00;
const int COLOR_YELLOW_DARK = 0xd0ce00;
const int COLOR_YELLOW_LIGHT = 0xffffe0;
// -----------------------------------------------------------------------------
// Colors By Function
// -----------------------------------------------------------------------------
const int COLOR_DEFAULT = 0xfefefe;
const int COLOR_ATTENTION = 0xfea400;
const int COLOR_BUG = 0x660000;
const int COLOR_FAIL = 0xff0000;
const int COLOR_SUCCESS = 0x3dc93d;
const int COLOR_DEBUG = 0xb4b4b4;
const int COLOR_INFO = 0xd0814b;
// ----- Damage Types ----------------------------------------------------------
const int COLOR_DAMAGE_MAGICAL = 0xcc77ff;
const int COLOR_DAMAGE_ACID = 0x01ff01;
const int COLOR_DAMAGE_COLD = 0x99ffff;
const int COLOR_DAMAGE_DIVINE = 0xffff01;
const int COLOR_DAMAGE_ELECTRICAL = 0x0166ff;
const int COLOR_DAMAGE_FIRE = 0xff0101;
const int COLOR_DAMAGE_NEGATIVE = 0x999999;
const int COLOR_DAMAGE_POSITIVE = 0xffffff;
const int COLOR_DAMAGE_SONIC = 0xff9901;
// ----- Chat Log Messages -----------------------------------------------------
const int COLOR_MESSAGE_FEEDBACK = 0xffff01;
const int COLOR_MESSAGE_COMBAT = 0xff6601;
const int COLOR_MESSAGE_MAGIC = 0xcc77ff;
const int COLOR_MESSAGE_SKILLS = 0x0166ff;
const int COLOR_MESSAGE_SAVING = 0x66ccff;
const int COLOR_SAVE_STATUS = 0x20ff20;
const int COLOR_PAUSE_STATE = 0xff0101;
const int COLOR_NAME_CLIENT = 0x99ffff;
const int COLOR_NAME_OTHER = 0xcc99cc;
// -----------------------------------------------------------------------------
// Custom Colors
// -----------------------------------------------------------------------------
// You can add any custom colors you need for your functions below this line.
// -----------------------------------------------------------------------------

View File

@@ -0,0 +1,364 @@
/// ----------------------------------------------------------------------------
/// @file util_i_color.nss
/// @author Michael A. Sinclair (Squatting Monk) <squattingmonk@gmail.com>
/// @brief Functions to handle colors.
/// @details
/// NWN normally uses color codes to color strings. These codes take the format
/// `<cRGB>`, where RGB are ALT codes (0-0255) for colors.
///
/// Because color codes are arcane and can't be easily looked up, the functions
/// in this file prefer to use hex color codes. These codes are the same as
/// you'd use in web design and many other areas, so they are easy to look up
/// and can be copied and pasted into other programs. util_c_color.nss provides
/// some hex codes for common uses.
///
/// This file also contains functions to represent colors as RGB or HSV
/// triplets. HSV (Hue, Saturation, Value) may be particularly useful if you
/// want to play around with shifting colors.
///
/// ## Acknowledgements
/// - `GetColorCode()` function by rdjparadis.
/// - RGB <-> HSV colors adapted from NWShacker's Named Color Token System.
/// ----------------------------------------------------------------------------
#include "x3_inc_string"
#include "util_i_math"
#include "util_c_color"
// -----------------------------------------------------------------------------
// Constants
// -----------------------------------------------------------------------------
/// Used to generate colors from RGB values. NEVER modify this string.
/// @see https://nwn.wiki/display/NWN1/Colour+Tokens
/// @note First character is "nearest to 00" since we can't use `\x00` itself
/// @note COLOR_TOKEN originally by rdjparadis. Converted to NWN:EE escaped
/// characters by Jasperre.
const string COLOR_TOKEN = "\x01\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
// -----------------------------------------------------------------------------
// Types
// -----------------------------------------------------------------------------
struct RGB
{
int r;
int g;
int b;
};
struct HSV
{
float h;
float s;
float v;
};
// -----------------------------------------------------------------------------
// Function Prototypes
// -----------------------------------------------------------------------------
// ----- Type Creation ---------------------------------------------------------
/// @brief Create an RBG color struct.
/// @param nRed The value of the red channel (0..255).
/// @param nGreen The value of the green channel (0..255).
/// @param nBlue The value of the blue channel (0..255).
struct RGB GetRGB(int nRed, int nGreen, int nBlue);
/// @brief Create an HSV color struct.
/// @details The ranges are as follows:
/// 0.0 <= H < 360.0
/// 0.0 <= S <= 1.0
/// 0.0 <= V <= 1.0
/// @param fHue The hue (i.e. location on color wheel).
/// @param fSaturation The saturation (i.e., distance from white/black).
/// @param fValue The value (i.e., brightness of color).
struct HSV GetHSV(float fHue, float fSaturation, float fValue);
// ----- Type Conversion -------------------------------------------------------
/// @brief Convert a hexadecimal color to an RGB struct.
/// @param nColor Hexadecimal to convert to RGB.
struct RGB HexToRGB(int nColor);
/// @brief Convert an RGB struct to a hexadecimal color.
/// @param rgb RGB to convert to hexadecimal.
int RGBToHex(struct RGB rgb);
/// @brief Convert an RGB struct to an HSV struct.
/// @param rgb RGB to convert to HSV.
struct HSV RGBToHSV(struct RGB rgb);
/// @brief Convert an HSV struct to an RGB struct.
/// @param hsv HSV to convert to RGB.
struct RGB HSVToRGB(struct HSV hsv);
/// @brief Converts a hexadecimal color to an HSV struct.
/// @param nColor Hexadecimal to convert to HSV.
struct HSV HexToHSV(int nColor);
/// @brief Converts an HSV struct to a hexadecial color.
/// @param hsv HSV to convert to hexadecimal.
int HSVToHex(struct HSV hsv);
// ----- Coloring Functions ----------------------------------------------------
/// @brief Construct a color code that can be used to color a string.
/// @param nRed The intensity of the red channel (0..255).
/// @param nGreen The intensity of the green channel (0..255).
/// @param nBlue The intensity of the blue channel (0..255).
/// @returns A string color code in `<cRBG>` form.
string GetColorCode(int nRed, int nGreen, int nBlue);
/// @brief Convert a hexadecimal color to a color code.
/// @param nColor Hexadecimal representation of an RGB color.
/// @returns A string color code in `<cRBG>` form.
string HexToColor(int nColor);
/// @brief Convert a color code prefix to a hexadecimal
/// @param sColor A string color code in `<cRBG>` form.
int ColorToHex(string sColor);
/// @brief Color a string with a color code.
/// @param sString The string to color.
/// @param sColor A string color code in `<cRBG>` form.
string ColorString(string sString, string sColor);
/// @brief Color a string with a hexadecimal color.
/// @param sString The string to color.
/// @param nColor A hexadecimal color.
string HexColorString(string sString, int nColor);
/// @brief Color a string with an RGB color.
/// @param sString The string to color.
/// @param rgb The RGB color struct.
string RGBColorString(string sString, struct RGB rgb);
/// @brief Color a string with a struct HSV color
/// @param sString The string to color.
/// @param hsv The HSV color struct.
string HSVColorString(string sString, struct HSV hsv);
/// @brief Remove color codes from a string.
/// @param sString The string to uncolor.
/// @returns sString with color codes removed.
string UnColorString(string sString);
// -----------------------------------------------------------------------------
// Function Definitions
// -----------------------------------------------------------------------------
// ----- Type Creation ---------------------------------------------------------
struct RGB GetRGB(int nRed, int nGreen, int nBlue)
{
struct RGB rgb;
rgb.r = clamp(nRed, 0, 255);
rgb.g = clamp(nGreen, 0, 255);
rgb.b = clamp(nBlue, 0, 255);
return rgb;
}
struct HSV GetHSV(float fHue, float fSat, float fVal)
{
struct HSV hsv;
hsv.h = fclamp(fHue, 0.0, 360.0);
hsv.s = fclamp(fSat, 0.0, 1.0);
hsv.v = fclamp(fVal, 0.0, 1.0);
if (hsv.h == 360.0)
hsv.h = 0.0;
return hsv;
}
// ----- Type Conversion -------------------------------------------------------
struct RGB HexToRGB(int nColor)
{
int nRed = (nColor & 0xff0000) >> 16;
int nGreen = (nColor & 0x00ff00) >> 8;
int nBlue = (nColor & 0x0000ff);
return GetRGB(nRed, nGreen, nBlue);
}
int RGBToHex(struct RGB rgb)
{
int nRed = (clamp(rgb.r, 0, 255) << 16);
int nGreen = (clamp(rgb.g, 0, 255) << 8);
int nBlue = clamp(rgb.b, 0, 255);
return nRed + nGreen + nBlue;
}
struct HSV RGBToHSV(struct RGB rgb)
{
// Ensure the RGB values are within defined limits
rgb = GetRGB(rgb.r, rgb.g, rgb.b);
struct HSV hsv;
// Convert RGB to a range from 0 - 1
float fRed = IntToFloat(rgb.r) / 255.0;
float fGreen = IntToFloat(rgb.g) / 255.0;
float fBlue = IntToFloat(rgb.b) / 255.0;
float fMax = fmax(fRed, fmax(fGreen, fBlue));
float fMin = fmin(fRed, fmin(fGreen, fBlue));
float fChroma = fMax - fMin;
if (fMax > fMin)
{
if (fMax == fRed)
hsv.h = 60.0 * ((fGreen - fBlue) / fChroma);
else if (fMax == fGreen)
hsv.h = 60.0 * ((fBlue - fRed) / fChroma + 2.0);
else
hsv.h = 60.0 * ((fRed - fGreen) / fChroma + 4.0);
if (hsv.h < 0.0)
hsv.h += 360.0;
}
if (fMax > 0.0)
hsv.s = fChroma / fMax;
hsv.v = fMax;
return hsv;
}
struct RGB HSVToRGB(struct HSV hsv)
{
// Ensure the HSV values are within defined limits
hsv = GetHSV(hsv.h, hsv.s, hsv.v);
struct RGB rgb;
// If value is 0, the resulting color will always be black
if (hsv.v == 0.0)
return rgb;
// If the saturation is 0, the resulting color will be a shade of grey
if (hsv.s == 0.0)
{
// Scale from white to black based on value
int nValue = FloatToInt(hsv.v * 255.0);
return GetRGB(nValue, nValue, nValue);
}
float h = hsv.h / 60.0;
float f = frac(h);
int v = FloatToInt(hsv.v * 255.0);
int p = FloatToInt(v * (1.0 - hsv.s));
int q = FloatToInt(v * (1.0 - hsv.s * f));
int t = FloatToInt(v * (1.0 - hsv.s * (1.0 - f)));
int i = FloatToInt(h);
switch (i % 6)
{
case 0: rgb = GetRGB(v, t, p); break;
case 1: rgb = GetRGB(q, v, p); break;
case 2: rgb = GetRGB(p, v, t); break;
case 3: rgb = GetRGB(p, q, v); break;
case 4: rgb = GetRGB(t, p, v); break;
case 5: rgb = GetRGB(v, p, q); break;
}
return rgb;
}
struct HSV HexToHSV(int nColor)
{
return RGBToHSV(HexToRGB(nColor));
}
int HSVToHex(struct HSV hsv)
{
return RGBToHex(HSVToRGB(hsv));
}
// ----- Coloring Functions ----------------------------------------------------
string GetColorCode(int nRed, int nGreen, int nBlue)
{
return "<c" + GetSubString(COLOR_TOKEN, nRed, 1) +
GetSubString(COLOR_TOKEN, nGreen, 1) +
GetSubString(COLOR_TOKEN, nBlue, 1) + ">";
}
string HexToColor(int nColor)
{
if (nColor < 0 || nColor > 0xffffff)
return "";
int nRed = (nColor & 0xff0000) >> 16;
int nGreen = (nColor & 0x00ff00) >> 8;
int nBlue = (nColor & 0x0000ff);
return GetColorCode(nRed, nGreen, nBlue);
}
int ColorToHex(string sColor)
{
if (sColor == "")
return -1;
string sRed = GetSubString(sColor, 2, 1);
string sGreen = GetSubString(sColor, 3, 1);
string sBlue = GetSubString(sColor, 4, 1);
int nRed = FindSubString(COLOR_TOKEN, sRed) << 16;
int nGreen = FindSubString(COLOR_TOKEN, sGreen) << 8;
int nBlue = FindSubString(COLOR_TOKEN, sBlue);
return nRed + nGreen + nBlue;
}
string ColorString(string sString, string sColor)
{
if (sColor != "")
sString = sColor + sString + "</c>";
return sString;
}
string HexColorString(string sString, int nColor)
{
string sColor = HexToColor(nColor);
return ColorString(sString, sColor);
}
string RGBColorString(string sString, struct RGB rgb)
{
string sColor = GetColorCode(rgb.r, rgb.g, rgb.b);
return ColorString(sString, sColor);
}
string HSVColorString(string sString, struct HSV hsv)
{
struct RGB rgb = HSVToRGB(hsv);
return RGBColorString(sString, rgb);
}
string UnColorString(string sString)
{
sString = StringReplace(sString, "</c>", "");
int nOpen = FindSubString(sString, "<c");
int nClose = FindSubString(sString, ">", nOpen);
int nLength;
string sPrefix, sSuffix;
while (nOpen != -1 && nClose != -1)
{
nLength = GetStringLength(sString);
sPrefix = GetStringLeft(sString, nOpen);
sSuffix = GetStringRight(sString, nLength - nClose - 1);
sString = sPrefix + sSuffix;
nOpen = FindSubString(sString, "<c");
nClose = FindSubString(sString, ">", nOpen);
}
return sString;
}

View File

@@ -0,0 +1,338 @@
/// ----------------------------------------------------------------------------
/// @file util_i_csvlists.nss
/// @author Michael A. Sinclair (Squatting Monk) <squattingmonk@gmail.com>
/// @author Ed Burke (tinygiant98) <af.hog.pilot@gmail.com>
/// @brief Functions for manipulating comma-separated value (CSV) lists.
/// @details
///
/// ## Usage:
///
/// ```nwscript
/// string sKnight, sKnights = "Lancelot, Galahad, Robin";
/// int i, nCount = CountList(sKnights);
/// for (i = 0; i < nCount; i++)
/// {
/// sKnight = GetListItem(sKnights, i);
/// SpeakString("Sir " + sKnight);
/// }
///
/// int bBedivere = HasListItem(sKnights, "Bedivere");
/// SpeakString("Bedivere " + (bBedivere ? "is" : "is not") + " in the party.");
///
/// sKnights = AddListItem(sKnights, "Bedivere");
/// bBedivere = HasListItem(sKnights, "Bedivere");
/// SpeakString("Bedivere " + (bBedivere ? "is" : "is not") + " in the party.");
///
/// int nRobin = FindListItem(sKnights, "Robin");
/// SpeakString("Robin is knight " + IntToString(nRobin) + " in the party.");
/// ```
/// ----------------------------------------------------------------------------
#include "x3_inc_string"
#include "util_i_math"
#include "util_i_strings"
// -----------------------------------------------------------------------------
// Function Prototypes
// -----------------------------------------------------------------------------
/// @brief Return the number of items in a CSV list.
/// @param sList The CSV list to count.
int CountList(string sList);
/// @brief Add an item to a CSV list.
/// @param sList The CSV list to add the item to.
/// @param sListItem The item to add to sList.
/// @param bAddUnique If TRUE, will only add the item to the list if it is not
/// already there.
/// @returns A modified copy of sList with sListItem added.
string AddListItem(string sList, string sListItem, int bAddUnique = FALSE);
/// @brief Return the item at an index in a CSV list.
/// @param sList The CSV list to get the item from.
/// @param nIndex The index of the item to get (0-based).
string GetListItem(string sList, int nIndex = 0);
/// @brief Return the index of a value in a CSV list.
/// @param sList The CSV list to search.
/// @param sListItem The value to search for.
/// @returns -1 if the item was not found in the list.
int FindListItem(string sList, string sListItem);
/// @brief Return whether a CSV list contains a value.
/// @param sList The CSV list to search.
/// @param sListItem The value to search for.
/// @returns TRUE if the item is in the list, otherwise FALSE.
int HasListItem(string sList, string sListItem);
/// @brief Delete the item at an index in a CSV list.
/// @param sList The CSV list to delete the item from.
/// @param nIndex The index of the item to delete (0-based).
/// @returns A modified copy of sList with the item deleted.
string DeleteListItem(string sList, int nIndex = 0);
/// @brief Delete the first occurrence of an item in a CSV list.
/// @param sList The CSV list to remove the item from.
/// @param sListItem The value to remove from the list.
/// @returns A modified copy of sList with the item removed.
string RemoveListItem(string sList, string sListItem);
/// @brief Copy items from one CSV list to another.
/// @param sSource The CSV list to copy items from.
/// @param sTarget The CSV list to copy items to.
/// @param nIndex The index to begin copying from.
/// @param nRange The number of items to copy.
/// @param bAddUnique If TRUE, will only copy items to sTarget if they are not
/// already there.
/// @returns A modified copy of sTarget with the items added to the end.
string CopyListItem(string sSource, string sTarget, int nIndex, int nRange = 1, int bAddUnique = FALSE);
/// @brief Merge the contents of two CSV lists.
/// @param sList1 The first CSV list.
/// @param sList2 The second CSV list.
/// @param bAddUnique If TRUE, will only put items in the returned list if they
/// are not already there.
/// @returns A CSV list containing the items from each list.
string MergeLists(string sList1, string sList2, int bAddUnique = FALSE);
/// @brief Add an item to a CSV list saved as a local variable on an object.
/// @param oObject The object on which the local variable is saved.
/// @param sListName The varname for the local variable.
/// @param sListItem The item to add to the list.
/// @param bAddUnique If TRUE, will only add the item to the list if it is not
/// already there.
/// @returns The updated copy of the list with sListItem added.
string AddLocalListItem(object oObject, string sListName, string sListItem, int bAddUnique = FALSE);
/// @brief Delete an item in a CSV list saved as a local variable on an object.
/// @param oObject The object on which the local variable is saved.
/// @param sListName The varname for the local variable.
/// @param nIndex The index of the item to delete (0-based).
/// @returns The updated copy of the list with the item at nIndex deleted.
string DeleteLocalListItem(object oObject, string sListName, int nNth = 0);
/// @brief Remove an item in a CSV list saved as a local variable on an object.
/// @param oObject The object on which the local variable is saved.
/// @param sListName The varname for the local variable.
/// @param sListItem The value to remove from the list.
/// @returns The updated copy of the list with the first instance of sListItem
/// removed.
string RemoveLocalListItem(object oObject, string sListName, string sListItem);
/// @brief Merge the contents of a CSV list with those of a CSV list stored as a
/// local variable on an object.
/// @param oObject The object on which the local variable is saved.
/// @param sListName The varname for the local variable.
/// @param sListToMerge The CSV list to merge into the saved list.
/// @param bAddUnique If TRUE, will only put items in the returned list if they
/// are not already there.
/// @returns The updated copy of the list with all items from sListToMerge
/// added.
string MergeLocalList(object oObject, string sListName, string sListToMerge, int bAddUnique = FALSE);
/// @brief Convert a comma-separated value list to a JSON array.
/// @param sList Source CSV list.
/// @returns JSON array representation of CSV list.
json ListToJson(string sList);
/// @brief Convert a JSON array to a comma-separate value list.
/// @param jArray JSON array list.
/// @returns CSV list of JSON array values.
string JsonToList(json jArray);
// -----------------------------------------------------------------------------
// Function Implementations
// -----------------------------------------------------------------------------
int CountList(string sList)
{
if (sList == "")
return 0;
return GetSubStringCount(sList, ",") + 1;
}
string AddListItem(string sList, string sListItem, int bAddUnique = FALSE)
{
if (bAddUnique && HasListItem(sList, sListItem))
return sList;
if (sList != "")
return sList + ", " + sListItem;
return sListItem;
}
string GetListItem(string sList, int nIndex = 0)
{
if (nIndex < 0 || sList == "")
return "";
// Loop through the elements until we find the one we want.
int nCount, nLeft, nRight = FindSubString(sList, ",");
while (nRight != -1 && nCount < nIndex)
{
nCount++;
nLeft = nRight + 1;
nRight = FindSubString(sList, ",", nLeft);
}
// If there were not enough elements, return a null string.
if (nCount < nIndex)
return "";
// Get the element
return TrimString(GetStringSlice(sList, nLeft, nRight - 1));
}
int FindListItem(string sList, string sListItem)
{
sList = TrimString(sList);
sListItem = TrimString(sListItem);
if (sList == "")
return -1;
int nItem, nStart, nEnd;
do
{
nEnd = FindSubString(sList, ",", nStart);
if (TrimString(GetStringSlice(sList, nStart, nEnd - 1)) == sListItem)
return nItem;
nItem++;
nStart = nEnd + 1;
}
while (nEnd >= 0);
return -1;
}
int HasListItem(string sList, string sListItem)
{
return (FindListItem(sList, sListItem) > -1);
}
string DeleteListItem(string sList, int nIndex = 0)
{
if (nIndex < 0 || sList == "")
return sList;
int nPos = FindSubStringN(sList, ",", nIndex);
if (nPos < 0)
{
if (nIndex)
{
nPos = FindSubStringN(sList, ",", nIndex - 1);
return TrimStringRight(GetStringSlice(sList, 0, nPos - 1));
}
return "";
}
string sRight = GetStringSlice(sList, nPos + 1);
if (!nIndex)
return sRight;
nPos = FindSubStringN(sList, ",", nIndex - 1);
sRight = nPos < 0 ? TrimStringLeft(sRight) : sRight;
return GetStringSlice(sList, 0, nPos) + sRight;
}
string RemoveListItem(string sList, string sListItem)
{
return DeleteListItem(sList, FindListItem(sList, sListItem));
}
string CopyListItem(string sSource, string sTarget, int nIndex, int nRange = 1, int bAddUnique = FALSE)
{
string sValue;
int i, nCount = CountList(sSource);
if (nIndex < 0 || nIndex >= nCount || !nCount)
return sSource;
nRange = clamp(nRange, 1, nCount - nIndex);
for (i = 0; i < nRange; i++)
{
sValue = GetListItem(sSource, nIndex + i);
sTarget = AddListItem(sTarget, sValue, bAddUnique);
}
return sTarget;
}
string MergeLists(string sList1, string sList2, int bAddUnique = FALSE)
{
int i, nCount = CountList(sList2);
for (i = 0; i < nCount; i++)
sList1 = AddListItem(sList1, GetListItem(sList2, i), bAddUnique);
return sList1;
}
string AddLocalListItem(object oObject, string sListName, string sListItem, int bAddUnique = FALSE)
{
string sList = GetLocalString(oObject, sListName);
sList = AddListItem(sList, sListItem, bAddUnique);
SetLocalString(oObject, sListName, sList);
return sList;
}
string DeleteLocalListItem(object oObject, string sListName, int nNth = 0)
{
string sList = GetLocalString(oObject, sListName);
sList = DeleteListItem(sList, nNth);
SetLocalString(oObject, sListName, sList);
return sList;
}
string RemoveLocalListItem(object oObject, string sListName, string sListItem)
{
string sList = GetLocalString(oObject, sListName);
sList = RemoveListItem(sList, sListItem);
SetLocalString(oObject, sListName, sList);
return sList;
}
string MergeLocalList(object oObject, string sListName, string sListToMerge, int bAddUnique = FALSE)
{
string sList = GetLocalString(oObject, sListName);
sList = MergeLists(sList, sListToMerge, bAddUnique);
SetLocalString(oObject, sListName, sList);
return sList;
}
json ListToJson(string sList)
{
json jRet = JsonArray();
if (sList == "")
return jRet;
string sItem;
int nStart, nEnd;
do
{
nEnd = FindSubString(sList, ",", nStart);
sItem = TrimString(GetStringSlice(sList, nStart, nEnd - 1));
jRet = JsonArrayInsert(jRet, JsonString(sItem));
nStart = nEnd + 1;
} while (nEnd != -1);
return jRet;
}
string JsonToList(json jArray)
{
if (JsonGetType(jArray) != JSON_TYPE_ARRAY)
return "";
string sList;
int i, nCount = JsonGetLength(jArray);
for (i; i < nCount; i++)
{
if (i > 0)
sList += ", ";
sList += JsonGetString(JsonArrayGet(jArray, i));
}
return sList;
}

177
_module/nss/util_i_math.nss Normal file
View File

@@ -0,0 +1,177 @@
/// ----------------------------------------------------------------------------
/// @file util_i_math.nss
/// @author Michael A. Sinclair (Squatting Monk) <squattingmonk@gmail.com>
/// @brief Useful math utility functions.
/// ----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Function Prototypes
// -----------------------------------------------------------------------------
/// @brief Return the closest integer to the binary logarithm of a number.
int log2(int n);
/// @brief Restrict an integer to a range.
/// @param nValue The number to evaluate.
/// @param nMin The minimum value for the number.
/// @param nMax The maximum value for the number.
/// @returns nValue if it is between nMin and nMax. Otherwise returns the
/// closest of nMin or nMax.
int clamp(int nValue, int nMin, int nMax);
/// @brief Restrict a float to a range.
/// @param fValue The number to evaluate.
/// @param fMin The minimum value for the number.
/// @param fMax The maximum value for the number.
/// @returns fValue if it is between fMin and fMax. Otherwise returns the
/// closest of fMin or fMax.
float fclamp(float fValue, float fMin, float fMax);
/// @brief Return the larger of two integers.
int max(int a, int b);
/// @brief Return the smaller of two integers.
int min(int a, int b);
/// @brief Return the sign of an integer.
/// @returns -1 if n is negative, 0 if 0, or 1 if positive.
int sign(int n);
/// @brief Return the larger of two floats.
float fmax(float a, float b);
/// @brief Return the smaller of two floats.
float fmin(float a, float b);
/// @brief Return the sign of a float.
/// @returns -1 if f is negative, 0 if 0, or 1 if positive.
int fsign(float f);
/// @brief Truncate a float (i.e., remove numbers to the right of the decimal
/// point).
float trunc(float f);
/// @brief Return the fractional part of a float (i.e., numbers to the right of
/// the decimal point).
float frac(float f);
/// @brief Return a % b (modulo function).
/// @param a The dividend
/// @param b The divisor
/// @note For consistency with NWN's integer modulo operator, the result has the
/// same sign as a (i.e., fmod(-1, 2) == -1).
float fmod(float a, float b);
/// @brief Round a float down to the nearest whole number.
float floor(float f);
/// @brief Round a float up to the nearest whole number.
float ceil(float f);
/// @brief Round a float towards to the nearest whole number.
/// @note In case of a tie (i.e., +/- 0.5), rounds away from 0.
float round(float f);
/// @brief Determine if x is in [a..b]
/// @param x Value to compare
/// @param a Low end of range
/// @param b High end of range
int between(int x, int a, int b);
/// @brief Determine if x is in [a..b]
/// @param x Value to compare
/// @param a Low end of range
/// @param b High end of range
int fbetween(float x, float a, float b);
// -----------------------------------------------------------------------------
// Function Definitions
// -----------------------------------------------------------------------------
int log2(int n)
{
int nResult;
while (n >>= 1)
nResult++;
return nResult;
}
int clamp(int nValue, int nMin, int nMax)
{
return (nValue < nMin) ? nMin : ((nValue > nMax) ? nMax : nValue);
}
float fclamp(float fValue, float fMin, float fMax)
{
return (fValue < fMin) ? fMin : ((fValue > fMax) ? fMax : fValue);
}
int max(int a, int b)
{
return (b > a) ? b : a;
}
int min(int a, int b)
{
return (b > a) ? a : b;
}
int sign(int n)
{
return (n > 0) ? 1 : (n < 0) ? -1 : 0;
}
float fmax(float a, float b)
{
return (b > a) ? b : a;
}
float fmin(float a, float b)
{
return (b > a) ? a : b;
}
int fsign(float f)
{
return f > 0.0 ? 1 : f < 0.0 ? -1 : 0;
}
float trunc(float f)
{
return IntToFloat(FloatToInt(f));
}
float frac(float f)
{
return f - trunc(f);
}
float fmod(float a, float b)
{
return a - b * trunc(a / b);
}
float floor(float f)
{
return IntToFloat(FloatToInt(f) - (f < 0.0));
}
float ceil(float f)
{
return IntToFloat(FloatToInt(f) + (trunc(f) < f));
}
float round(float f)
{
return IntToFloat(FloatToInt(f + (f < 0.0 ? -0.5 : 0.5)));
}
int between(int x, int a, int b)
{
return ((x - a) * (x - b)) <= 0;
}
int fbetween(float x, float a, float b)
{
return ((x - a) * (x - b)) <= 0.0;
}

View File

@@ -0,0 +1,428 @@
/// ----------------------------------------------------------------------------
/// @file util_i_strings.nss
/// @author Michael A. Sinclair (Squatting Monk) <squattingmonk@gmail.com>
/// @author Ed Burke (tinygiant98) <af.hog.pilot@gmail.com>
/// @brief Functions for formatting times
/// ----------------------------------------------------------------------------
/// @details This file holds utility functions for manipulating strings.
/// ----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Constants
// -----------------------------------------------------------------------------
const string CHARSET_NUMERIC = "0123456789";
const string CHARSET_ALPHA = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string CHARSET_ALPHA_LOWER = "abcdefghijklmnopqrstuvwxyz";
const string CHARSET_ALPHA_UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// -----------------------------------------------------------------------------
// Function Prototypes
// -----------------------------------------------------------------------------
/// @brief Return the number of occurrences of a substring within a string.
/// @param sString The string to search.
/// @param sSubString The substring to search for.
int GetSubStringCount(string sString, string sSubString);
/// @brief Return the position of a given occurrence of a substring within a
/// string.
/// @param sString The string to search.
/// @param sSubString The substring to search for.
/// @param nNth The occurrence to search for. Uses a zero-based index.
/// @returns The position of the start of the nNth occurrence of the substring,
/// or -1 if the substring did not occur at least nNth + 1 times.
int FindSubStringN(string sString, string sSubString, int nNth = 0);
/// @brief Return the character at a position in a string.
/// @param sString The string to search.
/// @param nPos The position to check.
/// @returns "" if sString is not nPos + 1 characters long.
string GetChar(string sString, int nPos);
/// @brief Return the substring of a string bounded by a start and end position.
/// @param sString The string to search.
/// @param nStart The starting position of the substring to return.
/// @param nEnd The ending position of the substring to return. If -1, will
/// return to the end of the string.
/// @returns "" if nStart is not at least nStart + 1 characters long or if nEnd
/// is < nStart and not -1.
/// @note Both nStart and nEnd are inclusive, so if nStart == nEnd, the
/// character at that index will be returned.
string GetStringSlice(string sString, int nStart, int nEnd = -1);
/// @brief Replace the substring bounded by a string slice with another string.
/// @param sString The string to search.
/// @param sSub The substring to replace with.
/// @param nStart The starting position in sString of the substring to replace.
/// @param nEnd The ending position in sString of the substring to replace.
string ReplaceSubString(string sString, string sSub, int nStart, int nEnd);
/// @brief Replace a substring in a string with another string.
/// @param sString The string to search.
/// @param sToken The substring to search for.
/// @param sSub The substring to replace with.
string SubstituteSubString(string sString, string sToken, string sSub);
/// @brief Replace all substrings in a string with another string.
/// @param sString The string to search.
/// @param sToken The substring to search for.
/// @param sSub The substring to replace with.
string SubstituteSubStrings(string sString, string sToken, string sSub);
/// @brief Return whether a string contains a substring.
/// @param sString The string to search.
/// @param sSubString The substring to search for.
/// @param nStart The position in sString to begin searching from (0-based).
/// @returns TRUE if sSubString is in sString, FALSE otherwise.
int HasSubString(string sString, string sSubString, int nStart = 0);
/// @brief Return whether any of a string's characters are in a character set.
/// @param sString The string to search.
/// @param sSet The set of characters to search for.
/// @returns TRUE if any characters are in the set; FALSE otherwise.
int GetAnyCharsInSet(string sString, string sSet);
/// @brief Return whether all of a string's characters are in a character set.
/// @param sString The string to search.
/// @param sSet The set of characters to search for.
/// @returns TRUE if all characters are in the set; FALSE otherwise.
int GetAllCharsInSet(string sString, string sSet);
/// @brief Return whether all letters in a string are upper-case.
/// @param sString The string to check.
int GetIsUpperCase(string sString);
/// @brief Return whether all letters in a string are lower-case.
/// @param sString The string to check.
int GetIsLowerCase(string sString);
/// @brief Return whether all characters in sString are letters.
/// @param sString The string to check.
int GetIsAlpha(string sString);
/// @brief Return whether all characters in sString are digits.
/// @param sString The string to check.
int GetIsNumeric(string sString);
/// @brief Return whether all characters in sString are letters or digits.
/// @param sString The string to check.
int GetIsAlphaNumeric(string sString);
/// @brief Trim characters from the left side of a string.
/// @param sString The string to trim.
/// @param sRemove The set of characters to remove.
string TrimStringLeft(string sString, string sRemove = " ");
/// @brief Trim characters from the right side of a string.
/// @param sString The string to trim.
/// @param sRemove The set of characters to remove.
string TrimStringRight(string sString, string sRemove = " ");
/// @brief Trim characters from both sides of a string.
/// @param sString The string to trim.
/// @param sRemove The set of characters to remove.
string TrimString(string sString, string sRemove = " ");
/// @brief Interpolate values from a json array into a string using sqlite's
/// printf().
/// @param jArray A json array containing float, int, or string elements to
/// interpolate. The number of elements must match the number of format
/// specifiers in sFormat.
/// @param sFormat The string to interpolate the values into. Must contain
/// format specifiers that correspond to the elements in jArray. For details
/// on format specifiers, see https://sqlite.org/printf.html.
/// @example
/// FormatValues(JsonParse("[\"Blue\", 255]"), "%s: #%06X"); // "Blue: #0000FF"
string FormatValues(json jArray, string sFormat);
/// @brief Interpolate a float into a string using sqlite's printf().
/// @param f A float to interpolate. Will be passed as an argument to the query
/// as many times as necessary to cover all format specifiers.
/// @param sFormat The string to interpolate the value into. For details on
/// format specifiers, see https://sqlite.org/printf.html.
/// @example
/// FormatFloat(15.0, "%d"); // "15"
/// FormatFloat(15.0, "%.2f"); // "15.00"
/// FormatFloat(15.0, "%05.1f"); // "015.0"
string FormatFloat(float f, string sFormat);
/// @brief Interpolate an int into a string using sqlite's printf().
/// @param n An int to interpolate. Will be passed as an argument to the query
/// as many times as necessary to cover all format specifiers.
/// @param sFormat The string to interpolate the value into. For details on
/// format specifiers, see https://sqlite.org/printf.html.
/// @example
/// FormatInt(15, "%d"); // "15"
/// FormatInt(15, "%04d"); // "0015"
/// FormatInt(15, "In hexadecimal, %d is %#x"); // "In hexadecimal, 15 is 0xf"
/// FormatInt(1000, "%,d"); // "1,000"
string FormatInt(int n, string sFormat);
/// @brief Interpolate a string into another string using sqlite's printf().
/// @param s A string to interpolate. Will be passed as an argument to the query
/// as many times as necessary to cover all format specifiers.
/// @param sFormat The string to interpolate the value into. For details on
/// format specifiers, see https://sqlite.org/printf.html.
/// @example
/// FormatString("foo", "%sbar"); // "foobar"
/// FormatString("foo", "%5sbar"); // " foobar"
/// FormatString("foo", "%-5sbar"); // "foo bar"
string FormatString(string s, string sFormat);
/// @brief Substitute tokens in a string with values from a json array.
/// @param s The string to interpolate the values into. Should have tokens wich
/// contain sDesignator followed by a number denoting the position of the
/// value in jArray (1-based index).
/// @param jArray An array of values to interpolate. May be any combination of
/// strings, floats, decimals, or booleans.
/// @param sDesignator The character denoting the beginning of a token.
/// @example
/// // Assumes jArray = ["Today", 34, 2.5299999999, true];
/// SubstituteString("$1, I ran $2 miles.", jArray); // "Today, I ran 34 miles."
/// SubstituteString("The circle's radius is $3.", jArray); // "The circle's radius is 2.53."
/// SubstituteString("The applicant answered: $4", jArray); // "The applicant answered: true"
string SubstituteString(string s, json jArray, string sDesignator = "$");
/// @brief Repeats a string multiple times.
/// @param s The string to repeat.
/// @param n The number of times to repeat s.
/// @returns The repeated string.
string RepeatString(string s, int n);
// -----------------------------------------------------------------------------
// Function Implementations
// -----------------------------------------------------------------------------
int GetSubStringCount(string sString, string sSubString)
{
if (sString == "" || sSubString == "")
return 0;
int nLength = GetStringLength(sSubString);
int nCount, nPos = FindSubString(sString, sSubString);
while (nPos != -1)
{
nCount++;
nPos = FindSubString(sString, sSubString, nPos + nLength);
}
return nCount;
}
int FindSubStringN(string sString, string sSubString, int nNth = 0)
{
if (nNth < 0 || sString == "" || sSubString == "")
return -1;
int nLength = GetStringLength(sSubString);
int nPos = FindSubString(sString, sSubString);
while (--nNth >= 0 && nPos != -1)
nPos = FindSubString(sString, sSubString, nPos + nLength);
return nPos;
}
string GetChar(string sString, int nPos)
{
return GetSubString(sString, nPos, 1);
}
string GetStringSlice(string sString, int nStart, int nEnd = -1)
{
int nLength = GetStringLength(sString);
if (nEnd < 0 || nEnd > nLength)
nEnd = nLength;
if (nStart < 0 || nStart > nEnd)
return "";
return GetSubString(sString, nStart, nEnd - nStart + 1);
}
string ReplaceSubString(string sString, string sSub, int nStart, int nEnd)
{
int nLength = GetStringLength(sString);
if (nStart < 0 || nStart >= nLength || nStart > nEnd)
return sString;
return GetSubString(sString, 0, nStart) + sSub +
GetSubString(sString, nEnd + 1, nLength - nEnd);
}
string SubstituteSubString(string sString, string sToken, string sSub)
{
int nPos;
if ((nPos = FindSubString(sString, sToken)) == -1)
return sString;
return ReplaceSubString(sString, sSub, nPos, nPos + GetStringLength(sToken) - 1);
}
string SubstituteSubStrings(string sString, string sToken, string sSub)
{
while (FindSubString(sString, sToken) >= 0)
sString = SubstituteSubString(sString, sToken, sSub);
return sString;
}
int HasSubString(string sString, string sSubString, int nStart = 0)
{
return FindSubString(sString, sSubString, nStart) >= 0;
}
int GetAnyCharsInSet(string sString, string sSet)
{
int i, nLength = GetStringLength(sString);
for (i = 0; i < nLength; i++)
{
if (HasSubString(sSet, GetChar(sString, i)))
return TRUE;
}
return FALSE;
}
int GetAllCharsInSet(string sString, string sSet)
{
int i, nLength = GetStringLength(sString);
for (i = 0; i < nLength; i++)
{
if (!HasSubString(sSet, GetChar(sString, i)))
return FALSE;
}
return TRUE;
}
int GetIsUpperCase(string sString)
{
return GetAllCharsInSet(sString, CHARSET_ALPHA_UPPER + CHARSET_NUMERIC);
}
int GetIsLowerCase(string sString)
{
return GetAllCharsInSet(sString, CHARSET_ALPHA_LOWER + CHARSET_NUMERIC);
}
int GetIsAlpha(string sString)
{
return GetAllCharsInSet(sString, CHARSET_ALPHA);
}
int GetIsNumeric(string sString)
{
return GetAllCharsInSet(sString, CHARSET_NUMERIC);
}
int GetIsAlphaNumeric(string sString)
{
return GetAllCharsInSet(sString, CHARSET_ALPHA + CHARSET_NUMERIC);
}
string TrimStringLeft(string sString, string sRemove = " ")
{
while (FindSubString(sRemove, GetStringLeft(sString, 1)) != -1)
sString = GetStringRight(sString, GetStringLength(sString) - 1);
return sString;
}
string TrimStringRight(string sString, string sRemove = " ")
{
while (FindSubString(sRemove, GetStringRight(sString, 1)) != -1)
sString = GetStringLeft(sString, GetStringLength(sString) - 1);
return sString;
}
string TrimString(string sString, string sRemove = " ")
{
return TrimStringRight(TrimStringLeft(sString, sRemove), sRemove);
}
string FormatValues(json jArray, string sFormat)
{
if (JsonGetType(jArray) != JSON_TYPE_ARRAY)
return "";
string sArgs;
int i, nLength = JsonGetLength(jArray);
for (i = 0; i < nLength; i++)
sArgs += ", @" + IntToString(i);
sqlquery q = SqlPrepareQueryObject(GetModule(), "SELECT printf(@format" + sArgs + ");");
SqlBindString(q, "@format", sFormat);
for (i = 0; i < nLength; i++)
{
string sParam = "@" + IntToString(i);
json jValue = JsonArrayGet(jArray, i);
switch (JsonGetType(jValue))
{
case JSON_TYPE_FLOAT: SqlBindFloat (q, sParam, JsonGetFloat (jValue)); break;
case JSON_TYPE_INTEGER: SqlBindInt (q, sParam, JsonGetInt (jValue)); break;
case JSON_TYPE_STRING: SqlBindString(q, sParam, JsonGetString(jValue)); break;
default: break;
}
}
return SqlStep(q) ? SqlGetString(q, 0) : "";
}
string FormatFloat(float f, string sFormat)
{
json jArray = JsonArray();
int i, nCount = GetSubStringCount(sFormat, "%");
for (i = 0; i < nCount; i++)
jArray = JsonArrayInsert(jArray, JsonFloat(f));
return FormatValues(jArray, sFormat);
}
string FormatInt(int n, string sFormat)
{
json jArray = JsonArray();
int i, nCount = GetSubStringCount(sFormat, "%");
for (i = 0; i < nCount; i++)
jArray = JsonArrayInsert(jArray, JsonInt(n));
return FormatValues(jArray, sFormat);
}
string FormatString(string s, string sFormat)
{
json jArray = JsonArray();
int i, nCount = GetSubStringCount(sFormat, "%");
for (i = 0; i < nCount; i++)
jArray = JsonArrayInsert(jArray, JsonString(s));
return FormatValues(jArray, sFormat);
}
string SubstituteString(string s, json jArray, string sDesignator = "$")
{
if (JsonGetType(jArray) != JSON_TYPE_ARRAY)
return s;
int n; for (n = JsonGetLength(jArray) - 1; n >= 0; n--)
{
string sValue;
json jValue = JsonArrayGet(jArray, n);
int nType = JsonGetType(jValue);
if (nType == JSON_TYPE_STRING) sValue = JsonGetString(jValue);
else if (nType == JSON_TYPE_INTEGER) sValue = IntToString(JsonGetInt(jValue));
else if (nType == JSON_TYPE_FLOAT) sValue = FormatFloat(JsonGetFloat(jValue), "%!f");
else if (nType == JSON_TYPE_BOOL) sValue = JsonGetInt(jValue) == 1 ? "true" : "false";
else continue;
s = SubstituteSubStrings(s, sDesignator + IntToString(n + 1), sValue);
}
return s;
}
string RepeatString(string s, int n)
{
string sResult;
while (n-- > 0)
sResult += s;
return sResult;
}

File diff suppressed because it is too large Load Diff

View File

@@ -34,8 +34,10 @@
//:: Created On: 2003-07-16
//:://////////////////////////////////////////////
#include "nui_i_main"
#include "x2_inc_switches"
#include "x2_inc_restsys"
void main()
{
@@ -43,6 +45,8 @@ void main()
SetEventScript(GetModule(), EVENT_SCRIPT_MODULE_ON_PLAYER_TARGET, "mod_target");
SetEventScript(GetModule(), EVENT_SCRIPT_MODULE_ON_PLAYER_GUIEVENT, "mod_gui");
NUI();
if (GetGameDifficulty() == GAME_DIFFICULTY_CORE_RULES || GetGameDifficulty() == GAME_DIFFICULTY_DIFFICULT)
{
// * Setting the switch below will enable a seperate Use Magic Device Skillcheck for