Added ACP 4.1

Added ACP 4.1.  Updated NWNxEE.  Re-enabled Discord webhooks.  Full compile.
This commit is contained in:
Jaysyn904
2024-09-08 17:26:15 -04:00
parent 61fe2186a1
commit 74a1eb1328
734 changed files with 1478 additions and 16 deletions

View File

@@ -18,7 +18,7 @@ const string DOOR_KEYTAG_BASHED = "door_Bashed_NoKey";
#include "nwnx_webhook"
#include "nwnx_time"
const string WEBHOOK_ALARM = "/api/webhooks/451346097038819329/5pPVJiIzLucPzWD-Vdh0Efdu5EKr6x1G57S45DHfcG84W8R-_Y_rno78xTryqWcEzo-F/slack";
const string WEBHOOK_ALARM = "/api/webhooks/1192445234152476682/Ptkrw9W2I5ec3OTRffXXXGg2cfThQUDf-csiONWAPn4OETS-_IScSCPgKPBogrsFpFIQ/slack";
void door_Repaired(object oDoor)
{

View File

@@ -16,9 +16,7 @@ as long as you provide the item blueprints, start locations etc...
Maximum Faction Count = 9 */
const int ANPH_NUMBER_OF_FACTIONS = 6;
const string WEBHOOK_ALARM = "/api/webhooks/451346097038819329/5pPVJiIzLucPzWD-Vdh0Efdu5EKr6x1G57S45DHfcG84W8R-_Y_rno78xTryqWcEzo-F/slack";
const string WEBHOOK_ALARM = "/api/webhooks/1192445234152476682/Ptkrw9W2I5ec3OTRffXXXGg2cfThQUDf-csiONWAPn4OETS-_IScSCPgKPBogrsFpFIQ/slack";
string anph_DescribePC(object oPC)
{

View File

@@ -0,0 +1,143 @@
//#include "inc_array"
#include "nwnx_time"
// nwnx_data also includes inc_array, so don't double dip.
#include "nwnx_data"
void Log(string msg)
{
WriteTimestampedLogEntry(msg);
}
void TestArrayOnModule()
{
string array = "test";
// By default, temporary arrays are created on the module.
Array_PushBack_Str(array, "BItem1");
Array_PushBack_Str(array, "AItem2");
Array_PushBack_Str(array, "AItem3");
Array_PushBack_Str(array, "BItem2");
Array_Debug_Dump(array, "After first load");
int foo = Array_Find_Str(array, "AItem3");
Log("Found element AItem3 at index = " + IntToString(foo));
Array_Set_Str(array, 2, "Suck it up...");
Array_Debug_Dump(array, "After set 2 = 'Suck it up...'");
Array_Erase(array, 1);
Array_Debug_Dump(array, "After delete 1");
Array_PushBack_Str(array, "MItem1");
Array_PushBack_Str(array, "QItem2");
Array_PushBack_Str(array, "NItem3");
Array_PushBack_Str(array, "KItem2");
Array_Debug_Dump(array, "After add more");
Array_SortAscending(array);
Array_Debug_Dump(array, "After sort");
Array_Shuffle(array);
Array_Debug_Dump(array, "After shuffle");
Log( (Array_Contains_Str(array, "NItem3")) ? "Passed.. found it" : "Failed.. should have found it" );
Log( (Array_Contains_Str(array, "KItem2")) ? "Passed.. found it" : "Failed.. should have found it" );
Log( (Array_Contains_Str(array, "xxxxxx")) ? "Failed.. not found" : "Passed.. should not exist" );
Array_Clear(array);
// Load up the array with 100 entries
int i;
struct NWNX_Time_HighResTimestamp b;
b = NWNX_Time_GetHighResTimeStamp();
Log("Start Time: " + IntToString(b.seconds) + "." + IntToString(b.microseconds));
for (i=0; i<1000; i++)
{
Array_PushBack_Str(array, IntToString(d100()) + " xxx " + IntToString(i));
}
b = NWNX_Time_GetHighResTimeStamp();
Log("Loaded 1000: " + IntToString(b.seconds) + "." + IntToString(b.microseconds));
Array_Shuffle(array);
b = NWNX_Time_GetHighResTimeStamp();
Log("Shuffled 1000: " + IntToString(b.seconds) + "." + IntToString(b.microseconds));
for (i=5; i<995; i++)
{
// Delete the third entry a bunch of times
Array_Erase(array, 3);
}
b = NWNX_Time_GetHighResTimeStamp();
Log("Delete ~990: " + IntToString(b.seconds) + "." + IntToString(b.microseconds));
Array_Debug_Dump(array, "After mass insert/delete");
}
void TestArrayOnChicken()
{
string array="chicken";
// Let's create an array "on" our favorite creature: the deadly nw_chicken
// Note - arrays aren't really attached to the item, but the module, and they
// are tagged with the objects string representation.
object oCreature = CreateObject(OBJECT_TYPE_CREATURE, "nw_chicken", GetStartingLocation());
if (!GetIsObjectValid(oCreature))
{
Log("NWNX_Creature test: Failed to create creature");
return;
}
Array_PushBack_Str(array, "BItem1", oCreature);
Array_PushBack_Str(array, "AItem2", oCreature);
Array_PushBack_Str(array, "AItem3", oCreature);
Array_PushBack_Str(array, "BItem2", oCreature);
Array_Debug_Dump(array, "After Chicken array load", oCreature);
}
void TestNWNXArray()
{
Log("");
Log("Start NWNX_Data test.");
string array = "test2";
NWNX_Data_Array_PushBack_Str(GetModule(), array, "XItem1");
NWNX_Data_Array_PushBack_Str(GetModule(), array, "ZItem2");
NWNX_Data_Array_PushBack_Str(GetModule(), array, "ZItem3");
NWNX_Data_Array_PushBack_Str(GetModule(), array, "XItem2");
Array_Debug_Dump(array, "After first load");
int foo = NWNX_Data_Array_Find_Str(GetModule(), array, "ZItem3");
Log("Found element AItem3 at index = " + IntToString(foo));
NWNX_Data_Array_Set_Str(GetModule(), array, 2, "Suck it up...");
Array_Debug_Dump(array, "After set 2 = 'Suck it up...'");
NWNX_Data_Array_Erase(NWNX_DATA_TYPE_STRING, GetModule(), array, 1);
Array_Debug_Dump(array, "After delete 1");
NWNX_Data_Array_PushBack_Str(GetModule(), array, "MItem1");
NWNX_Data_Array_PushBack_Str(GetModule(), array, "QItem2");
NWNX_Data_Array_PushBack_Str(GetModule(), array, "NItem3");
NWNX_Data_Array_PushBack_Str(GetModule(), array, "KItem2");
Array_Debug_Dump(array, "After add more");
NWNX_Data_Array_SortAscending(NWNX_DATA_TYPE_STRING, GetModule(), array);
Array_Debug_Dump(array, "After sort");
}
// Uncomment and assign to some event click.
/* */
void main()
{
Log("Start");
TestArrayOnModule();
TestArrayOnChicken();
TestNWNXArray();
}
/* */

View File

@@ -20,7 +20,7 @@
#include "faction_inc"
const string WEBHOOK_PVP = " "; //::"/api/webhooks/451343864733761536/Gd0QkGVQxttTGtjtB8pgJPqNOuqGVoYtNWIzcsvQQGG1EjAaxI_OuOlOxcXDgwJB55rZ/slack";
const string WEBHOOK_PVP = "/api/webhooks/1192445234152476682/Ptkrw9W2I5ec3OTRffXXXGg2cfThQUDf-csiONWAPn4OETS-_IScSCPgKPBogrsFpFIQ/slack";
///////////////////////
// Function Declaration

View File

@@ -3,7 +3,7 @@
//const string WEBHOOK_BUG = "/api/webhooks/451334833495343104/6NHIFKzr_DTl9-KQucZkPxOtyQCiUo7C4efwtHPDvHB-9HNWlkmFWIE2EFEPnIr7977w/slack";
const string WEBHOOK_BUG = "/api/webhooks/453873022315659275/xJYs04_h12hhWi0HI2NTucK7W8dp4K-7AD3NxmEuKUFSvv1nIWdRiE1PjRzsorrRrqLl/slack";
const string WEBHOOK_BUG = "/api/webhooks/1282444730202067058/IsS4ikaaqCNiB8YCaQc4StVz6ih2FeQo7jS5CAq67Qu45Y942So_f2l1O4UbIDLuXSDm/slack";
// Report a bug, sending it everywhere
void dbg_ReportBug(string sMessage, object oReporter=OBJECT_INVALID);

View File

@@ -11,7 +11,7 @@
#include "socket_inc"
#include "ip_inc"
const string WEBHOOK_DM = "/api/webhooks/451344020606812161/2JC0H5AkfAs4EeCbI1R0xzpCmGwxcLM7P7JxCmI4Qwf-7SwZ1uxi6V6YMNFtdjIyMQVW/slack";
const string WEBHOOK_DM = "/api/webhooks/1282444730202067058/IsS4ikaaqCNiB8YCaQc4StVz6ih2FeQo7jS5CAq67Qu45Y942So_f2l1O4UbIDLuXSDm/slack";
const string BADPARSE = "[BADPARSE]";
string ParseCommand(string sMessage, string sCommand)

512
_module/nss/inc_array.nss Normal file
View File

@@ -0,0 +1,512 @@
/// @addtogroup data Data
/// @brief Provides a number of data structures for NWN code to use (simulated arrays)
/// @{
/// @file nwnx_data.nss
const int INVALID_INDEX = -1;
const int TYPE_FLOAT = 0;
const int TYPE_INTEGER = 1;
const int TYPE_OBJECT = 2;
const int TYPE_STRING = 3;
/// @defgroup data_array_at Array At
/// @brief Returns the element at the index.
/// @ingroup data
/// @param obj The object.
/// @param tag The tag.
/// @param index The index.
/// @return The element of associated type.
/// @{
string Array_At_Str(string tag, int index, object obj=OBJECT_INVALID);
float Array_At_Flt(string tag, int index, object obj=OBJECT_INVALID);
int Array_At_Int(string tag, int index, object obj=OBJECT_INVALID);
object Array_At_Obj(string tag, int index, object obj=OBJECT_INVALID);
/// @}
/// Clears the entire array, such that size==0.
void Array_Clear(string tag, object obj=OBJECT_INVALID);
/// @defgroup data_array_contains Array Contains
/// @brief Checks if array contains the element.
/// @ingroup data
/// @param obj The object.
/// @param tag The tag.
/// @param element The element.
/// @return TRUE if the collection contains the element.
/// @{
int Array_Contains_Flt(string tag, float element, object obj=OBJECT_INVALID);
int Array_Contains_Int(string tag, int element, object obj=OBJECT_INVALID);
int Array_Contains_Obj(string tag, object element, object obj=OBJECT_INVALID);
int Array_Contains_Str(string tag, string element, object obj=OBJECT_INVALID);
/// @}
/// Copies the array of name otherTag over the array of name tag.
void Array_Copy(string tag, string otherTag, object obj=OBJECT_INVALID);
/// Erases the element at index, and shuffles any elements from index size-1 to index + 1 left.
void Array_Erase(string tag, int index, object obj=OBJECT_INVALID);
/// @defgroup data_array_find Array Find
/// @brief Get the index at which the element is located.
/// @ingroup data
/// @param obj The object.
/// @param tag The tag.
/// @param element The element.
/// @return Returns the index at which the element is located, or ARRAY_INVALID_INDEX.
/// @{
int Array_Find_Flt(string tag, float element, object obj=OBJECT_INVALID);
int Array_Find_Int(string tag, int element, object obj=OBJECT_INVALID);
int Array_Find_Obj(string tag, object element, object obj=OBJECT_INVALID);
int Array_Find_Str(string tag, string element, object obj=OBJECT_INVALID);
/// @}
/// @defgroup data_array_insert Array Insert
/// @brief Inserts the element at the index, where size > index >= 0.
/// @ingroup data
/// @param obj The object.
/// @param tag The tag.
/// @param index The index.
/// @param element The element.
/// @{
void Array_Insert_Flt(string tag, int index, float element, object obj=OBJECT_INVALID);
void Array_Insert_Int(string tag, int index, int element, object obj=OBJECT_INVALID);
void Array_Insert_Obj(string tag, int index, object element, object obj=OBJECT_INVALID);
void Array_Insert_Str(string tag, int index, string element, object obj=OBJECT_INVALID);
/// @}
/// @defgroup data_array_pushback Array Pushback
/// @brief Pushes an element to the back of the collection.
/// @remark Functionally identical to an insert at index size-1.
/// @ingroup data
/// @param obj The object.
/// @param tag The tag.
/// @param element The element.
/// @{
void Array_PushBack_Flt(string tag, float element, object obj=OBJECT_INVALID);
void Array_PushBack_Int(string tag, int element, object obj=OBJECT_INVALID);
void Array_PushBack_Obj(string tag, object element, object obj=OBJECT_INVALID);
void Array_PushBack_Str(string tag, string element, object obj=OBJECT_INVALID);
/// @}
/// Resizes the array. If the array is shrinking, it chops off elements at the ned.
void Array_Resize(string tag, int size, object obj=OBJECT_INVALID);
/// Reorders the array such each possible permutation of elements has equal probability of appearance.
void Array_Shuffle(string tag, object obj=OBJECT_INVALID);
/// Returns the size of the array.
int Array_Size(string tag, object obj=OBJECT_INVALID);
/// Sorts the collection based on descending order.
void Array_SortAscending(string tag, int type=TYPE_STRING, object obj=OBJECT_INVALID);
/// Sorts the collection based on descending order.
void Array_SortDescending(string tag, int type=TYPE_STRING, object obj=OBJECT_INVALID);
/// @defgroup data_array_set Array Set
/// @brief Sets the element at the index, where size > index >= 0.
/// @ingroup data
/// @param obj The object.
/// @param tag The tag.
/// @param index The index.
/// @param element The element.
/// @{
void Array_Set_Flt(string tag, int index, float element, object obj=OBJECT_INVALID);
void Array_Set_Int(string tag, int index, int element, object obj=OBJECT_INVALID);
void Array_Set_Obj(string tag, int index, object element, object obj=OBJECT_INVALID);
void Array_Set_Str(string tag, int index, string element, object obj=OBJECT_INVALID);
/// @}
/// @}
//
// Local Utility Functions.
//
string GetTableName(string tag, object obj=OBJECT_INVALID, int bare=FALSE) {
if (obj == OBJECT_INVALID)
obj = GetModule();
string sName = "array_" + ObjectToString(obj) + "_" + tag;
// Remove invalid characters from the tag rather than failing.
string sCleansed = RegExpReplace("[^A-Za-z0-9_\$@#]", sName, "");
// But provide some feedback.
if (GetStringLength(sName) != GetStringLength(sCleansed) || GetStringLength(sCleansed) == 0) {
WriteTimestampedLogEntry("WARNING: Invalid table name detected for array with tag <" + tag + ">. Only characters (a-zA-Z0-9), _, @, $ and # are allowed. Using <"+sCleansed+"> instead.");
}
// BARE returns just the table name with no wrapping.
if (bare == TRUE) {
return sCleansed;
}
// Table name wraped in quotes to avoid token expansion.
return "\""+sCleansed+"\"";
}
string GetTableCreateString(string tag, object obj=OBJECT_INVALID) {
// for simplicity sake, everything is turned into a string. Possible enhancement
// to create specific tables for int/float/whatever.
return "CREATE TABLE IF NOT EXISTS " + GetTableName(tag, obj) + " ( ind INTEGER, value TEXT )";
}
int TableExists(string tag, object obj=OBJECT_INVALID) {
string stmt = "SELECT name FROM sqlite_master WHERE type = 'table' AND name = @tablename;";
sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), stmt);
SqlBindString(sqlQuery, "@tablename", GetTableName(tag, obj, TRUE));
return SqlStep(sqlQuery);
}
void ExecuteStatement(string statement, object obj=OBJECT_INVALID) {
if (obj == OBJECT_INVALID)
obj = GetModule();
// There's no direct "execute this.." everything has to be prepared then executed.
//WriteTimestampedLogEntry("SQL: " + statement);
sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), statement);
SqlStep(sqlQuery);
}
void CreateArrayTable(string tag, object obj=OBJECT_INVALID) {
string createStatement = GetTableCreateString(tag, obj);
ExecuteStatement(createStatement, obj);
}
// Get the table row count. Returns -1 on error (0 is a valid number of rows in a table)
int GetRowCount(string tag, object obj=OBJECT_INVALID) {
if (obj == OBJECT_INVALID)
obj = GetModule();
CreateArrayTable(tag, obj);
string stmt = "SELECT COUNT(1) FROM " + GetTableName(tag, obj);
sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), stmt);
if ( SqlStep(sqlQuery) ) {
return SqlGetInt(sqlQuery, 0);
}
return -1;
}
////////////////////////////////////////////////////////////////////////////////
// return the value contained in location "index"
string Array_At_Str(string tag, int index, object obj=OBJECT_INVALID)
{
// Just "create if not exists" to ensure it exists for the insert.
CreateArrayTable(tag, obj);
string stmt = "SELECT value FROM " + GetTableName(tag, obj) + " WHERE ind = @ind";
sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), stmt);
SqlBindInt(sqlQuery, "@ind", index);
if ( SqlStep(sqlQuery) ) {
return SqlGetString(sqlQuery, 0);
}
return "";
}
float Array_At_Flt(string tag, int index, object obj=OBJECT_INVALID)
{
string st = Array_At_Str(tag, index, obj);
if (st == "") {
return 0.0;
}
return StringToFloat(st);
}
int Array_At_Int(string tag, int index, object obj=OBJECT_INVALID)
{
string st = Array_At_Str(tag, index, obj);
if (st == "") {
return 0;
}
return StringToInt(st);
}
object Array_At_Obj(string tag, int index, object obj=OBJECT_INVALID)
{
string st = Array_At_Str(tag, index, obj);
if (st == "") {
return OBJECT_INVALID;
}
return StringToObject(st);
}
void Array_Clear(string tag, object obj=OBJECT_INVALID)
{
ExecuteStatement("delete from "+GetTableName(tag, obj), obj);
}
////////////////////////////////////////////////////////////////////////////////
// Return true/value (1/0) if the array contains the value "element"
int Array_Contains_Str(string tag, string element, object obj=OBJECT_INVALID)
{
CreateArrayTable(tag, obj);
string stmt = "SELECT COUNT(1) FROM "+GetTableName(tag, obj)+" WHERE value = @element";
sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), stmt);
SqlBindString(sqlQuery, "@element", element);
int pos = -1;
if ( SqlStep(sqlQuery) ) {
pos = SqlGetInt(sqlQuery, 0);
if (pos > 0) {
return TRUE;
}
}
return FALSE;
}
int Array_Contains_Flt(string tag, float element, object obj=OBJECT_INVALID)
{
return Array_Contains_Str(tag, FloatToString(element), obj);
}
int Array_Contains_Int(string tag, int element, object obj=OBJECT_INVALID)
{
return Array_Contains_Str(tag, IntToString(element), obj);
}
int Array_Contains_Obj(string tag, object element, object obj=OBJECT_INVALID)
{
return Array_Contains_Str(tag, ObjectToString(element), obj);
}
////////////////////////////////////////////////////////////////////////////////
void Array_Copy(string tag, string otherTag, object obj=OBJECT_INVALID)
{
CreateArrayTable(otherTag, obj);
ExecuteStatement("INSERT INTO "+GetTableName(otherTag, obj)+" SELECT * FROM "+GetTableName(tag, obj), obj);
}
////////////////////////////////////////////////////////////////////////////////
void Array_Erase(string tag, int index, object obj=OBJECT_INVALID)
{
int rows = GetRowCount(tag, obj);
// Silently fail if "index" is outside the range of valid indicies.
if (index >= 0 && index < rows) {
string stmt = "DELETE FROM "+GetTableName(tag, obj)+" WHERE ind = @ind";
sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), stmt);
SqlBindInt(sqlQuery, "@ind", index);
SqlStep(sqlQuery);
stmt = "UPDATE "+GetTableName(tag, obj)+" SET ind = ind - 1 WHERE ind > @ind";
sqlQuery = SqlPrepareQueryObject(GetModule(), stmt);
SqlBindInt(sqlQuery, "@ind", index);
SqlStep(sqlQuery);
}
}
////////////////////////////////////////////////////////////////////////////////
// return the index in the array containing "element"
// if not found, return INVALID_INDEX
int Array_Find_Str(string tag, string element, object obj=OBJECT_INVALID)
{
string stmt;
sqlquery sqlQuery;
// Just create it before trying to select in case it doesn't exist yet.
CreateArrayTable(tag, obj);
stmt = "SELECT IFNULL(MIN(ind),@invalid_index) FROM "+GetTableName(tag, obj)+" WHERE value = @element";
sqlQuery = SqlPrepareQueryObject(GetModule(), stmt);
SqlBindInt(sqlQuery, "@invalid_index", INVALID_INDEX);
SqlBindString(sqlQuery, "@element", element);
if ( SqlStep(sqlQuery) ) {
return SqlGetInt(sqlQuery, 0);
}
return INVALID_INDEX;
}
int Array_Find_Flt(string tag, float element, object obj=OBJECT_INVALID)
{
return Array_Find_Str(tag, FloatToString(element), obj);
}
int Array_Find_Int(string tag, int element, object obj=OBJECT_INVALID)
{
return Array_Find_Str(tag, IntToString(element), obj);
}
int Array_Find_Obj(string tag, object element, object obj=OBJECT_INVALID)
{
return Array_Find_Str(tag, ObjectToString(element), obj);
}
////////////////////////////////////////////////////////////////////////////////
// Insert a new element into position 'index'. If index is beyond the number of rows in the array,
// this will quietly fail. This could be changed if you wanted to support sparse
// arrays.
void Array_Insert_Str(string tag, int index, string element, object obj=OBJECT_INVALID)
{
int rows = GetRowCount(tag, obj);
// Index numbers are off by one, much like C arrays, so for "rows=10" - values are 0-9.
// It's not unreasonable to fail if you try to insert ind=10 into an array who's indexes
// only go to 9, but I guess it doesn't hurt as long as we're not allowing gaps in
// index numbers.
if (index >= 0 && index <= rows) {
// index is passed as an integer, so immune (as far as I know) to SQL injection for a one shot query.
ExecuteStatement("UPDATE "+GetTableName(tag, obj)+" SET ind = ind + 1 WHERE ind >= "+IntToString(index), obj);
// Element, however, is not.
string stmt = "INSERT INTO "+GetTableName(tag, obj)+" VALUES ( @ind, @element )";
sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), stmt);
SqlBindInt(sqlQuery, "@ind", index);
SqlBindString(sqlQuery, "@element", element);
SqlStep(sqlQuery);
}
}
void Array_Insert_Flt(string tag, int index, float element, object obj=OBJECT_INVALID)
{
Array_Insert_Str(tag, index, FloatToString(element), obj);
}
void Array_Insert_Int(string tag, int index, int element, object obj=OBJECT_INVALID)
{
Array_Insert_Str(tag, index, IntToString(element), obj);
}
void Array_Insert_Obj(string tag, int index, object element, object obj=OBJECT_INVALID)
{
Array_Insert_Str(tag, index, ObjectToString(element), obj);
}
////////////////////////////////////////////////////////////////////////////////
// Insert a new element at the end of the array.
void Array_PushBack_Str(string tag, string element, object obj=OBJECT_INVALID)
{
// Create it before trhing to INSERT into it. If it already exists, this is a no-op.
CreateArrayTable(tag, obj);
// If rowCount = 10, indexes are from 0 to 9, so this becomes the 11th entry at index 10.
int rowCount = GetRowCount(tag, obj);
string stmt = "INSERT INTO "+GetTableName(tag, obj)+" VALUES ( @ind, @element )";
sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), stmt);
SqlBindInt(sqlQuery, "@ind", rowCount);
SqlBindString(sqlQuery, "@element", element);
SqlStep(sqlQuery);
}
void Array_PushBack_Flt(string tag, float element, object obj=OBJECT_INVALID)
{
Array_PushBack_Str(tag, FloatToString(element), obj);
}
void Array_PushBack_Int(string tag, int element, object obj=OBJECT_INVALID)
{
Array_PushBack_Str(tag, IntToString(element), obj);
}
void Array_PushBack_Obj(string tag, object element, object obj=OBJECT_INVALID)
{
Array_PushBack_Str(tag, ObjectToString(element), obj);
}
////////////////////////////////////////////////////////////////////////////////
// Cuts the array off at size 'size'. Elements beyond size are removed.
void Array_Resize(string tag, int size, object obj=OBJECT_INVALID)
{
// Int immune to sql injection so easier to one-shot it.
ExecuteStatement("DELETE FROM "+GetTableName(tag, obj)+" WHERE ind >= " + IntToString(size), obj);
}
////////////////////////////////////////////////////////////////////////////////
void Array_Shuffle(string tag, object obj=OBJECT_INVALID)
{
string table = GetTableName(tag, obj, TRUE);
ExecuteStatement("CREATE TABLE " +table+ "_temp AS SELECT ROW_NUMBER() OVER(ORDER BY RANDOM())-1, value FROM " +table, obj);
ExecuteStatement("DELETE FROM " +table , obj);
ExecuteStatement("INSERT INTO " +table+ " SELECT * FROM " +table+ "_temp", obj);
ExecuteStatement("DROP TABLE " +table+ "_TEMP", obj);
}
////////////////////////////////////////////////////////////////////////////////
int Array_Size(string tag, object obj=OBJECT_INVALID)
{
return GetRowCount(tag, obj);
}
////////////////////////////////////////////////////////////////////////////////
// Sort the array by value according to 'direction' (ASC or DESC).
// Supplying a type allows for correct numerical sorting of integers or floats.
void Array_Sort(string tag, string dir="ASC", int type=TYPE_STRING, object obj=OBJECT_INVALID)
{
string table = GetTableName(tag, obj, TRUE);
string direction = GetStringUpperCase(dir);
if ( ! (direction == "ASC" || direction == "DESC") ) {
WriteTimestampedLogEntry("WARNING: Invalid sort direction <" + direction + "> supplied. Defaulting to ASC.");
direction = "ASC";
}
// default orderBy for strings.
string orderBy = "ORDER BY value " + direction;
switch(type) {
case TYPE_INTEGER:
orderBy = "ORDER BY CAST(value AS INTEGER)" + direction;
break;
case TYPE_FLOAT:
orderBy = "ORDER BY CAST(value AS DECIMAL)" + direction;
break;
}
ExecuteStatement("CREATE TABLE " +table+ "_temp AS SELECT ROW_NUMBER() OVER(" + orderBy + ")-1, value FROM " +table, obj);
ExecuteStatement("DELETE FROM " +table, obj);
ExecuteStatement("INSERT INTO " +table+ " SELECT * FROM " +table+ "_temp", obj);
ExecuteStatement("DROP TABLE " +table+ "_temp", obj);
}
void Array_SortAscending(string tag, int type=TYPE_STRING, object obj=OBJECT_INVALID)
{
Array_Sort(tag, "ASC", type, obj);
}
void Array_SortDescending(string tag, int type=TYPE_STRING, object obj=OBJECT_INVALID)
{
Array_Sort(tag, "DESC", type, obj);
}
////////////////////////////////////////////////////////////////////////////////
// Set the value of array index 'index' to a 'element'
// This will quietly eat values if index > array size
void Array_Set_Str(string tag, int index, string element, object obj=OBJECT_INVALID)
{
int rows = GetRowCount(tag, obj);
if (index >= 0 && index <= rows) {
string stmt = "UPDATE "+GetTableName(tag, obj)+" SET value = @element WHERE ind = @ind";
sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), stmt);
SqlBindInt(sqlQuery, "@ind", index);
SqlBindString(sqlQuery, "@element", element);
SqlStep(sqlQuery);
}
}
void Array_Set_Flt(string tag, int index, float element, object obj=OBJECT_INVALID)
{
Array_Set_Str(tag, index, FloatToString(element), obj);
}
void Array_Set_Int(string tag, int index, int element, object obj=OBJECT_INVALID)
{
Array_Set_Str(tag, index, IntToString(element), obj);
}
void Array_Set_Obj(string tag, int index, object element, object obj=OBJECT_INVALID)
{
Array_Set_Str(tag, index, ObjectToString(element), obj);
}
void Array_Debug_Dump(string tag, string title = "xxx", object obj=OBJECT_INVALID) {
if (title != "xxx") {
WriteTimestampedLogEntry("== " + title + " ======================================");
}
WriteTimestampedLogEntry("Table name = " + GetTableName(tag, obj));
string stmt = "SELECT ind, value FROM " + GetTableName(tag, obj);
sqlquery sqlQuery = SqlPrepareQueryObject(GetModule(), stmt);
int ind = -1;
string value = "";
while ( SqlStep(sqlQuery) ) {
ind = SqlGetInt(sqlQuery, 0);
value = SqlGetString(sqlQuery, 1);
WriteTimestampedLogEntry(tag + "[" + IntToString(ind) + "] = " + value);
}
}

View File

@@ -12,7 +12,8 @@
#include "nwnx_webhook"
#include "dev_inc"
const string WEBHOOK_DM = "/api/webhooks/451344020606812161/2JC0H5AkfAs4EeCbI1R0xzpCmGwxcLM7P7JxCmI4Qwf-7SwZ1uxi6V6YMNFtdjIyMQVW/slack";
const string WEBHOOK_DM = "/api/webhooks/1282444730202067058/IsS4ikaaqCNiB8YCaQc4StVz6ih2FeQo7jS5CAq67Qu45Y942So_f2l1O4UbIDLuXSDm/slack";
void main()
{

View File

@@ -43,6 +43,7 @@ struct NWNX_Damage_DamageEventData
int iCustom17; ///< Custom17 damage
int iCustom18; ///< Custom18 damage
int iCustom19; ///< Custom19 damage
int iSpellId; ///< The spell id associated with the damage or -1 if not known.
};
/// @struct NWNX_Damage_AttackEventData
@@ -222,6 +223,7 @@ struct NWNX_Damage_DamageEventData NWNX_Damage_GetDamageEventData()
data.iCustom17 = NWNX_GetReturnValueInt();
data.iCustom18 = NWNX_GetReturnValueInt();
data.iCustom19 = NWNX_GetReturnValueInt();
data.iSpellId = NWNX_GetReturnValueInt();
return data;
}

351
_module/nss/nwnx_data.nss Normal file
View File

@@ -0,0 +1,351 @@
/// @addtogroup data Data
/// @brief Provides a number of data structures for NWN code to use (simulated arrays)
/// @{
/// @file nwnx_data.nss
#include "inc_array"
// All these calls just pass through to the Array code in inc_array to provide
// an NWNX_Data compatible API for ease of transition.
const int NWNX_DATA_INVALID_INDEX = INVALID_INDEX;
const int NWNX_DATA_TYPE_FLOAT = TYPE_FLOAT;
const int NWNX_DATA_TYPE_INTEGER = TYPE_INTEGER;
const int NWNX_DATA_TYPE_OBJECT = TYPE_OBJECT;
const int NWNX_DATA_TYPE_STRING = TYPE_STRING;
/// @defgroup data_array_at Array At
/// @brief Returns the element at the index.
/// @ingroup data
/// @param obj The object.
/// @param tag The tag.
/// @param index The index.
/// @return The element of associated type.
/// @{
string NWNX_Data_Array_At_Str(object obj, string tag, int index);
float NWNX_Data_Array_At_Flt(object obj, string tag, int index);
int NWNX_Data_Array_At_Int(object obj, string tag, int index);
object NWNX_Data_Array_At_Obj(object obj, string tag, int index);
/// @}
/// Clears the entire array, such that size==0.
void NWNX_Data_Array_Clear(int type, object obj, string tag);
/// @defgroup data_array_contains Array Contains
/// @brief Checks if array contains the element.
/// @ingroup data
/// @param obj The object.
/// @param tag The tag.
/// @param element The element.
/// @return TRUE if the collection contains the element.
/// @{
int NWNX_Data_Array_Contains_Flt(object obj, string tag, float element);
int NWNX_Data_Array_Contains_Int(object obj, string tag, int element);
int NWNX_Data_Array_Contains_Obj(object obj, string tag, object element);
int NWNX_Data_Array_Contains_Str(object obj, string tag, string element);
/// @}
/// Copies the array of name otherTag over the array of name tag.
void NWNX_Data_Array_Copy(int type, object obj, string tag, string otherTag);
/// Erases the element at index, and shuffles any elements from index size-1 to index + 1 left.
void NWNX_Data_Array_Erase(int type, object obj, string tag, int index);
/// @defgroup data_array_find Array Find
/// @brief Get the index at which the element is located.
/// @ingroup data
/// @param obj The object.
/// @param tag The tag.
/// @param element The element.
/// @return Returns the index at which the element is located, or ARRAY_INVALID_INDEX.
/// @{
int NWNX_Data_Array_Find_Flt(object obj, string tag, float element);
int NWNX_Data_Array_Find_Int(object obj, string tag, int element);
int NWNX_Data_Array_Find_Obj(object obj, string tag, object element);
int NWNX_Data_Array_Find_Str(object obj, string tag, string element);
/// @}
/// @defgroup data_array_insert Array Insert
/// @brief Inserts the element at the index, where size > index >= 0.
/// @ingroup data
/// @param obj The object.
/// @param tag The tag.
/// @param index The index.
/// @param element The element.
/// @{
void NWNX_Data_Array_Insert_Flt(object obj, string tag, int index, float element);
void NWNX_Data_Array_Insert_Int(object obj, string tag, int index, int element);
void NWNX_Data_Array_Insert_Obj(object obj, string tag, int index, object element);
void NWNX_Data_Array_Insert_Str(object obj, string tag, int index, string element);
/// @}
/// @defgroup data_array_pushback Array Pushback
/// @brief Pushes an element to the back of the collection.
/// @remark Functionally identical to an insert at index size-1.
/// @ingroup data
/// @param obj The object.
/// @param tag The tag.
/// @param element The element.
/// @{
void NWNX_Data_Array_PushBack_Flt(object obj, string tag, float element);
void NWNX_Data_Array_PushBack_Int(object obj, string tag, int element);
void NWNX_Data_Array_PushBack_Obj(object obj, string tag, object element);
void NWNX_Data_Array_PushBack_Str(object obj, string tag, string element);
/// @}
/// Resizes the array. If the array is shrinking, it chops off elements at the ned.
void NWNX_Data_Array_Resize(int type, object obj, string tag, int size);
/// Reorders the array such each possible permutation of elements has equal probability of appearance.
void NWNX_Data_Array_Shuffle(int type, object obj, string tag);
/// Returns the size of the array.
int NWNX_Data_Array_Size(int type, object obj, string tag);
/// Sorts the collection based on descending order.
void NWNX_Data_Array_SortAscending(int type, object obj, string tag);
/// Sorts the collection based on descending order.
void NWNX_Data_Array_SortDescending(int type, object obj, string tag);
/// @defgroup data_array_set Array Set
/// @brief Sets the element at the index, where size > index >= 0.
/// @ingroup data
/// @param obj The object.
/// @param tag The tag.
/// @param index The index.
/// @param element The element.
/// @{
void NWNX_Data_Array_Set_Flt(object obj, string tag, int index, float element);
void NWNX_Data_Array_Set_Int(object obj, string tag, int index, int element);
void NWNX_Data_Array_Set_Obj(object obj, string tag, int index, object element);
void NWNX_Data_Array_Set_Str(object obj, string tag, int index, string element);
/// @}
/// @}
////////////////////////////////////////////////////////////////////////////////
// return the value contained in location "index"
string NWNX_Data_Array_At_Str(object obj, string tag, int index)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
return Array_At_Str(tag, index, obj);
}
float NWNX_Data_Array_At_Flt(object obj, string tag, int index)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
return Array_At_Flt(tag, index, obj);
}
int NWNX_Data_Array_At_Int(object obj, string tag, int index)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
return Array_At_Int(tag, index, obj);
}
object NWNX_Data_Array_At_Obj(object obj, string tag, int index)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
return Array_At_Obj(tag, index, obj);
}
void NWNX_Data_Array_Clear(int type, object obj, string tag)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Clear(tag, obj);
}
////////////////////////////////////////////////////////////////////////////////
// Return true/value (1/0) if the array contains the value "element"
int NWNX_Data_Array_Contains_Str(object obj, string tag, string element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
return Array_Contains_Str(tag, element, obj);
}
int NWNX_Data_Array_Contains_Flt(object obj, string tag, float element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
return Array_Contains_Flt(tag, element, obj);
}
int NWNX_Data_Array_Contains_Int(object obj, string tag, int element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
return Array_Contains_Int(tag, element, obj);
}
int NWNX_Data_Array_Contains_Obj(object obj, string tag, object element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
return Array_Contains_Obj(tag, element, obj);
}
////////////////////////////////////////////////////////////////////////////////
void NWNX_Data_Array_Copy(int type, object obj, string tag, string otherTag)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Copy(tag, otherTag, obj);
}
////////////////////////////////////////////////////////////////////////////////
void NWNX_Data_Array_Erase(int type, object obj, string tag, int index)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Erase(tag, index, obj);
}
////////////////////////////////////////////////////////////////////////////////
// return the index in the array containing "element"
// if not found, return NWNX_DATA_INVALID_INDEX
int NWNX_Data_Array_Find_Str(object obj, string tag, string element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
return Array_Find_Str(tag, element, obj);
}
int NWNX_Data_Array_Find_Flt(object obj, string tag, float element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
return Array_Find_Flt(tag, element, obj);
}
int NWNX_Data_Array_Find_Int(object obj, string tag, int element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
return Array_Find_Int(tag, element, obj);
}
int NWNX_Data_Array_Find_Obj(object obj, string tag, object element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
return Array_Find_Obj(tag, element, obj);
}
////////////////////////////////////////////////////////////////////////////////
// Insert a new element into position 'index'. If index is beyond the number of rows in the array,
// this will quietly fail. This could be changed if you wanted to support sparse
// arrays.
void NWNX_Data_Array_Insert_Str(object obj, string tag, int index, string element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Insert_Str(tag, index, element, obj);
}
void NWNX_Data_Array_Insert_Flt(object obj, string tag, int index, float element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Insert_Flt(tag, index, element, obj);
}
void NWNX_Data_Array_Insert_Int(object obj, string tag, int index, int element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Insert_Int(tag, index, element, obj);
}
void NWNX_Data_Array_Insert_Obj(object obj, string tag, int index, object element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Insert_Obj(tag, index, element, obj);
}
////////////////////////////////////////////////////////////////////////////////
// Insert a new element at the end of the array.
void NWNX_Data_Array_PushBack_Str(object obj, string tag, string element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_PushBack_Str(tag, element, obj);
}
void NWNX_Data_Array_PushBack_Flt(object obj, string tag, float element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_PushBack_Flt(tag, element, obj);
}
void NWNX_Data_Array_PushBack_Int(object obj, string tag, int element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_PushBack_Int(tag, element, obj);
}
void NWNX_Data_Array_PushBack_Obj(object obj, string tag, object element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_PushBack_Obj(tag, element, obj);
}
////////////////////////////////////////////////////////////////////////////////
// Cuts the array off at size 'size'. Elements beyond size are removed.
void NWNX_Data_Array_Resize(int type, object obj, string tag, int size)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Resize(tag, size, obj);
}
////////////////////////////////////////////////////////////////////////////////
void NWNX_Data_Array_Shuffle(int type, object obj, string tag)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Shuffle(tag, obj);
}
////////////////////////////////////////////////////////////////////////////////
int NWNX_Data_Array_Size(int type, object obj, string tag)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
return Array_Size(tag, obj);
}
////////////////////////////////////////////////////////////////////////////////
// Sort the array by value according to 'direciton' (ASC or DESC)
// Note that this is a lexical sort, so sorting an array of ints or floats will have
// odd results
void NWNX_Data_Array_Sort(object obj, string tag, string direction)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Sort(tag, direction, TYPE_STRING, obj);
}
void NWNX_Data_Array_SortAscending(int type, object obj, string tag)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_SortAscending(tag, TYPE_STRING, obj);
}
void NWNX_Data_Array_SortDescending(int type, object obj, string tag)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_SortDescending(tag, TYPE_STRING, obj);
}
////////////////////////////////////////////////////////////////////////////////
// Set the value of array index 'index' to a 'element'
// This will quietly eat values if index > array size
void NWNX_Data_Array_Set_Str(object obj, string tag, int index, string element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Set_Str(tag, index, element, obj);
}
void NWNX_Data_Array_Set_Flt(object obj, string tag, int index, float element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Set_Flt(tag, index, element, obj);
}
void NWNX_Data_Array_Set_Int(object obj, string tag, int index, int element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Set_Int(tag, index, element, obj);
}
void NWNX_Data_Array_Set_Obj(object obj, string tag, int index, object element)
{
WriteTimestampedLogEntry("WARNING: NWNX_Data is deprecated. You should migrate to Array (see inc_array)");
Array_Set_Obj(tag, index, element, obj);
}

View File

@@ -69,7 +69,12 @@ void NWNX_Item_SetBaseItemType(object oItem, int nBaseItem);
///
/// [1] When specifying per-part coloring, the value 255 corresponds with the logical
/// function 'clear colour override', which clears the per-part override for that part.
void NWNX_Item_SetItemAppearance(object oItem, int nType, int nIndex, int nValue);
/// @param oItem The item
/// @param nType The type
/// @param nIndex The index
/// @param nValue The value
/// @param bUpdateCreatureAppearance If TRUE, also update the appearance of oItem's possessor. Only works for armor/helmets/cloaks. Will remove the item from the quickbar as side effect.
void NWNX_Item_SetItemAppearance(object oItem, int nType, int nIndex, int nValue, int bUpdateCreatureAppearance = FALSE);
/// @brief Return a string containing the entire appearance for an item.
/// @sa NWNX_Item_RestoreItemAppearance
@@ -100,6 +105,31 @@ int NWNX_Item_GetMinEquipLevel(object oItem);
/// @return TRUE if the item was successfully moved to the target, otherwise FALSE
int NWNX_Item_MoveTo(object oItem, object oTarget, int bHideAllFeedback = FALSE);
/// @brief Set a modifier to the Minimum Level to Equip (Item Level Restriction).
/// @param oItem The item object.
/// @param nModifier the modifier to apply (After any Override)
/// @param bPersist Whether the modifier should persist to gff field. Strongly Recommended to be TRUE (See warning)
/// @note This function (or override partner) must be used each server reset to reenable persistence. Recommended use on OBJECT_INVALID OnModuleLoad.
/// @warning if Persistence is FALSE, or not renabled, beware characters may trigger ELC logging in with now-invalid ItemLevelRestrictions equipped.
void NWNX_Item_SetMinEquipLevelModifier(object oItem, int nModifier, int bPersist = TRUE);
/// @brief Gets the applied modifier to the Minimum Level to Equip (Item Level Restriction).
/// @param oItem The item object.
int NWNX_Item_GetMinEquipLevelModifier(object oItem);
/// @brief Set an override to the Minimum Level to Equip (Item Level Restriction).
/// @param oItem The item object.
/// @param nOverride the nOverride to apply (Before any Modifier)
/// @param bPersist Whether the modifier should persist to gff field. Strongly Recommended to be TRUE (See warning)
/// @note This function (or modifier partner) must be used each server reset to reenable persistence. Recommended use on OBJECT_INVALID OnModuleLoad.
/// @warning if Persistence is FALSE, or not renabled, beware characters may trigger ELC logging in with now-invalid ItemLevelRestrictions equipped.
void NWNX_Item_SetMinEquipLevelOverride(object oItem, int nOverride, int bPersist = TRUE);
/// @brief Gets the applied override to the Minimum Level to Equip (Item Level Restriction).
/// @param oItem The item object.
int NWNX_Item_GetMinEquipLevelOverride(object oItem);
/// @}
void NWNX_Item_SetWeight(object oItem, int w)
@@ -162,10 +192,11 @@ void NWNX_Item_SetBaseItemType(object oItem, int nBaseItem)
NWNX_CallFunction(NWNX_Item, sFunc);
}
void NWNX_Item_SetItemAppearance(object oItem, int nType, int nIndex, int nValue)
void NWNX_Item_SetItemAppearance(object oItem, int nType, int nIndex, int nValue, int bUpdateCreatureAppearance = FALSE)
{
string sFunc = "SetItemAppearance";
NWNX_PushArgumentInt(bUpdateCreatureAppearance);
NWNX_PushArgumentInt(nValue);
NWNX_PushArgumentInt(nIndex);
NWNX_PushArgumentInt(nType);
@@ -227,3 +258,45 @@ int NWNX_Item_MoveTo(object oItem, object oTarget, int bHideAllFeedback = FALSE)
return NWNX_GetReturnValueInt();
}
void NWNX_Item_SetMinEquipLevelModifier(object oItem, int nModifier, int bPersist = TRUE)
{
string sFunc = "SetMinEquipLevelModifier";
NWNX_PushArgumentInt(bPersist);
NWNX_PushArgumentInt(nModifier);
NWNX_PushArgumentObject(oItem);
NWNX_CallFunction(NWNX_Item, sFunc);
}
int NWNX_Item_GetMinEquipLevelModifier(object oItem)
{
string sFunc = "GetMinEquipLevelModifier";
NWNX_PushArgumentObject(oItem);
NWNX_CallFunction(NWNX_Item, sFunc);
return NWNX_GetReturnValueInt();
}
void NWNX_Item_SetMinEquipLevelOverride(object oItem, int nOverride, int bPersist = TRUE)
{
string sFunc = "SetMinEquipLevelOverride";
NWNX_PushArgumentInt(bPersist);
NWNX_PushArgumentInt(nOverride);
NWNX_PushArgumentObject(oItem);
NWNX_CallFunction(NWNX_Item, sFunc);
}
int NWNX_Item_GetMinEquipLevelOverride(object oItem)
{
string sFunc = "GetMinEquipLevelOverride";
NWNX_PushArgumentObject(oItem);
NWNX_CallFunction(NWNX_Item, sFunc);
return NWNX_GetReturnValueInt();
}

View File

@@ -0,0 +1,25 @@
/// @addtogroup nwsqliteextensions NWSQLiteExtensions
/// @brief Various extensions for the game's built-in sqlite database.
/// @{
/// @file nwnx_nwsqliteext.nss
#include "nwnx"
const string NWNX_NWSQLiteExtensions = "NWNX_NWSQLiteExtensions"; ///< @private
/// @brief Create a virtual table for s2DA in the module sqlite database.
/// @param s2DA The 2DA name, cannot be empty.
/// @param sColumnTypeHints A string containing type hints for the 2DA columns. See this plugin's readme file for more info.
/// @param sTableName The table name, will use the 2da name if empty.
/// @return TRUE if the virtual table was created.
int NWNX_NWSQLiteExtensions_CreateVirtual2DATable(string s2DA, string sColumnTypeHints = "", string sTableName = "");
/// @}
int NWNX_NWSQLiteExtensions_CreateVirtual2DATable(string s2DA, string sColumnTypeHints = "", string sTableName = "")
{
NWNX_PushArgumentString(sTableName);
NWNX_PushArgumentString(sColumnTypeHints);
NWNX_PushArgumentString(s2DA);
NWNX_CallFunction(NWNX_NWSQLiteExtensions, "CreateVirtual2DATable");
return NWNX_GetReturnValueInt();
}

View File

@@ -418,6 +418,21 @@ int NWNX_Object_GetLastSpellInstant();
/// @param oCreator The new creator of the trap. Any non-creature creator will assign OBJECT_INVALID (similar to toolset-laid traps)
void NWNX_Object_SetTrapCreator(object oObject, object oCreator);
/// @brief Return the name of the object for nLanguage.
/// @param oObject an object
/// @param nLanguage A PLAYER_LANGUAGE constant.
/// @param nGender Gender to use, 0 or 1.
/// @return The localized string.
string NWNX_Object_GetLocalizedName(object oObject, int nLanguage, int nGender = 0);
/// @brief Set the name of the object as set in the toolset for nLanguage.
/// @note You may have to SetName(oObject, "") for the translated string to show.
/// @param oObject an object
/// @param sName New value to set
/// @param nLanguage A PLAYER_LANGUAGE constant.
/// @param nGender Gender to use, 0 or 1.
void NWNX_Object_SetLocalizedName(object oObject, string sName, int nLanguage, int nGender = 0);
/// @}
int NWNX_Object_GetLocalVariableCount(object obj)
@@ -1036,3 +1051,27 @@ void NWNX_Object_SetTrapCreator(object oObject, object oCreator)
NWNX_PushArgumentObject(oObject);
NWNX_CallFunction(NWNX_Object, sFunc);
}
string NWNX_Object_GetLocalizedName(object oObject, int nLanguage, int nGender = 0)
{
string sFunc = "GetLocalizedName";
NWNX_PushArgumentInt(nGender);
NWNX_PushArgumentInt(nLanguage);
NWNX_PushArgumentObject(oObject);
NWNX_CallFunction(NWNX_Object, sFunc);
return NWNX_GetReturnValueString();
}
void NWNX_Object_SetLocalizedName(object oObject, string sName, int nLanguage, int nGender = 0)
{
string sFunc = "SetLocalizedName";
NWNX_PushArgumentInt(nGender);
NWNX_PushArgumentInt(nLanguage);
NWNX_PushArgumentString(sName);
NWNX_PushArgumentObject(oObject);
NWNX_CallFunction(NWNX_Object, sFunc);
}

View File

@@ -329,7 +329,8 @@ void NWNX_Player_SetCreatureNameOverride(object oPlayer, object oCreature, strin
/// @param oPlayer The player to display the text to.
/// @param oCreature The creature to display the text above.
/// @param sText The text to display.
void NWNX_Player_FloatingTextStringOnCreature(object oPlayer, object oCreature, string sText);
/// @param bChatWindow If TRUE, sText will be displayed in oPlayer's chat window.
void NWNX_Player_FloatingTextStringOnCreature(object oPlayer, object oCreature, string sText, int bChatWindow = TRUE);
/// @brief Toggle oPlayer's PlayerDM status.
/// @note This function does nothing for actual DMClient DMs or players with a client version < 8193.14
@@ -396,6 +397,10 @@ void NWNX_Player_CloseStore(object oPlayer);
/// @note Overrides will not persist through relogging.
void NWNX_Player_SetTlkOverride(object oPlayer, int nStrRef, string sOverride, int bRestoreGlobal = TRUE);
/// @brief Make the player reload it's TlkTable.
/// @param oPlayer The player.
void NWNX_Player_ReloadTlk(object oPlayer);
/// @brief Update wind for oPlayer only.
/// @param oPlayer The player.
/// @param vDirection The Wind's direction.
@@ -445,6 +450,10 @@ void NWNX_Player_SendPartyInvite(object oPlayer, object oInviter, int bForceInvi
/// @return the TURD object of oPlayer, or OBJECT_INVALID if no TURD exists
object NWNX_Player_GetTURD(object oPlayer);
/// @brief Reloads the color palettes for oPlayer
/// @param oPlayer The player to reload the color palette for
void NWNX_Player_ReloadColorPalettes(object oPlayer);
/// @}
void NWNX_Player_ForcePlaceableExamineWindow(object player, object placeable)
@@ -910,10 +919,11 @@ void NWNX_Player_SetCreatureNameOverride(object oPlayer, object oCreature, strin
NWNX_CallFunction(NWNX_Player, sFunc);
}
void NWNX_Player_FloatingTextStringOnCreature(object oPlayer, object oCreature, string sText)
void NWNX_Player_FloatingTextStringOnCreature(object oPlayer, object oCreature, string sText, int bChatWindow = TRUE)
{
string sFunc = "FloatingTextStringOnCreature";
NWNX_PushArgumentInt(bChatWindow);
NWNX_PushArgumentString(sText);
NWNX_PushArgumentObject(oCreature);
NWNX_PushArgumentObject(oPlayer);
@@ -1050,6 +1060,14 @@ void NWNX_Player_SetTlkOverride(object oPlayer, int nStrRef, string sOverride, i
NWNX_CallFunction(NWNX_Player, sFunc);
}
void NWNX_Player_ReloadTlk(object oPlayer)
{
string sFunc = "ReloadTlk";
NWNX_PushArgumentObject(oPlayer);
NWNX_CallFunction(NWNX_Player, sFunc);
}
void NWNX_Player_UpdateWind(object oPlayer, vector vDirection, float fMagnitude, float fYaw, float fPitch)
{
string sFunc = "UpdateWind";
@@ -1131,6 +1149,14 @@ object NWNX_Player_GetTURD(object oPlayer)
NWNX_PushArgumentObject(oPlayer);
NWNX_CallFunction(NWNX_Player, sFunc);
return NWNX_GetReturnValueObject();
}
void NWNX_Player_ReloadColorPalettes(object oPlayer)
{
string sFunc = "ReloadColorPalettes";
NWNX_PushArgumentObject(oPlayer);
NWNX_CallFunction(NWNX_Player, sFunc);
}

View File

@@ -65,6 +65,12 @@ void NWNX_SQL_PreparedObjectFull(int position, object value, int base64 = TRUE);
/// @param position The nth ? in a prepared statement.
void NWNX_SQL_PreparedNULL(int position);
/// @brief Set the Json value of a prepared statement at given position.
/// Convienence function to match other Prepared(type) functions.
/// @param position The nth ? in a prepared statement.
/// @param value The value to set.
void NWNX_SQL_PreparedJson(int position, json value);
/// @brief Like NWNX_SQL_ReadDataInActiveRow, but for full serialized objects.
///
/// The object will be deserialized and created in the game. New object ID is returned.
@@ -211,6 +217,12 @@ void NWNX_SQL_PreparedNULL(int position)
NWNX_PushArgumentInt(position);
NWNX_CallFunction(NWNX_SQL, sFunc);
}
void NWNX_SQL_PreparedJson(int position, json value)
{
// Dump to string and continue as a string from here.
// Famously assuming we're sent valid Json here.
NWNX_SQL_PreparedString(position, JsonDump(value));
}
object NWNX_SQL_ReadFullObjectInActiveRow(int column = 0, object owner = OBJECT_INVALID, float x = 0.0, float y = 0.0, float z = 0.0, int base64 = TRUE)

131
_module/nss/nwnx_store.nss Normal file
View File

@@ -0,0 +1,131 @@
/// @addtogroup store
/// @brief Functions exposing additional store properties.
/// @{
/// @file nwnx_store.nss
#include "nwnx"
const string NWNX_Store = "NWNX_Store"; ///< @private
/// @brief Return status of a base item purchase status.
/// @param oStore The store object.
/// @param nBaseItem A BASE_ITEM_* value
/// @return TRUE if the quest has been completed. -1 if the player does not have the journal entry.
int NWNX_Store_GetIsRestrictedBuyItem(object oStore, int nBaseItem);
/// @brief Return the blackmarket mark down of a store
/// @param oStore The store object.
/// @return mark down of a store, -1 on error
int NWNX_Store_GetBlackMarketMarkDown(object oStore);
/// @brief Set the blackmarket mark down of a store
/// @param oStore The store object.
/// @param nValue The amount.
void NWNX_Store_SetBlackMarketMarkDown(object oStore, int nValue);
/// @brief Return the mark down of a store
/// @param oStore The store object.
/// @return mark down of a store, -1 on error
int NWNX_Store_GetMarkDown(object oStore);
/// @brief Set the mark down of a store
/// @param oStore The store object.
/// @param nValue The amount.
void NWNX_Store_SetMarkDown(object oStore, int nValue);
/// @brief Return the mark up of a store
/// @param oStore The store object.
/// @return mark up of a store, -1 on error
int NWNX_Store_GetMarkUp(object oStore);
/// @brief Set the mark up of a store
/// @param oStore The store object.
/// @param nValue The amount.
void NWNX_Store_SetMarkUp(object oStore, int nValue);
/// @brief Return current customer count
/// @param oStore The store object.
/// @return count, or -1 on error
int NWNX_Store_GetCurrentCustomersCount(object oStore);
/// @}
int NWNX_Store_GetIsRestrictedBuyItem(object oStore, int nBaseItem)
{
string sFunc = "GetIsRestrictedBuyItem";
NWNX_PushArgumentInt(nBaseItem);
NWNX_PushArgumentObject(oStore);
NWNX_CallFunction(NWNX_Store, sFunc);
return NWNX_GetReturnValueInt();
}
int NWNX_Store_GetBlackMarketMarkDown(object oStore)
{
string sFunc = "GetBlackMarketMarkDown";
NWNX_PushArgumentObject(oStore);
NWNX_CallFunction(NWNX_Store, sFunc);
return NWNX_GetReturnValueInt();
}
void NWNX_Store_SetBlackMarketMarkDown(object oStore, int nValue)
{
string sFunc = "SetBlackMarketMarkDown";
NWNX_PushArgumentInt(nValue);
NWNX_PushArgumentObject(oStore);
NWNX_CallFunction(NWNX_Store, sFunc);
}
int NWNX_Store_GetMarkDown(object oStore)
{
string sFunc = "GetMarkDown";
NWNX_PushArgumentObject(oStore);
NWNX_CallFunction(NWNX_Store, sFunc);
return NWNX_GetReturnValueInt();
}
void NWNX_Store_SetMarkDown(object oStore, int nValue)
{
string sFunc = "SetMarkDown";
NWNX_PushArgumentInt(nValue);
NWNX_PushArgumentObject(oStore);
NWNX_CallFunction(NWNX_Store, sFunc);
}
int NWNX_Store_GetMarkUp(object oStore)
{
string sFunc = "GetMarkUp";
NWNX_PushArgumentObject(oStore);
NWNX_CallFunction(NWNX_Store, sFunc);
return NWNX_GetReturnValueInt();
}
void NWNX_Store_SetMarkUp(object oStore, int nValue)
{
string sFunc = "SetMarkUp";
NWNX_PushArgumentInt(nValue);
NWNX_PushArgumentObject(oStore);
NWNX_CallFunction(NWNX_Store, sFunc);
}
int NWNX_Store_GetCurrentCustomersCount(object oStore)
{
string sFunc = "GetCurrentCustomersCount";
NWNX_PushArgumentObject(oStore);
NWNX_CallFunction(NWNX_Store, sFunc);
return NWNX_GetReturnValueInt();
}

View File

@@ -248,6 +248,21 @@ void NWNX_Util_SetCurrentlyRunningEvent(int nEventID);
/// @return The number of characters different between the compared strings.
int NWNX_Util_GetStringLevenshteinDistance(string sString, string sCompareTo);
/// @brief Sends a full object update of oObjectToUpdate to all clients
/// @param oObjectToUpdate The object to update
/// @param oPlayer The player for which the objects needs to update, OBJECT_INVALID for all players
void NWNX_Util_UpdateClientObject(object oObjectToUpdate, object oPlayer = OBJECT_INVALID);
/// @brief Clean a resource directory, deleting all files of nResType.
/// @param sAlias A resource directory alias, NWNX or one defined in the custom resource directory file.
/// @param nResType The type of file to delete or 0xFFFF for all types.
/// @return TRUE if successful, FALSE on error.
int NWNX_Util_CleanResourceDirectory(string sAlias, int nResType = 0xFFFF);
/// @brief Return the filename of the tlk file.
/// @return The name
string NWNX_Util_GetModuleTlkFile();
/// @}
string NWNX_Util_GetCurrentScriptName(int depth = 0)
@@ -617,3 +632,28 @@ int NWNX_Util_GetStringLevenshteinDistance(string sString, string sCompareTo)
NWNX_CallFunction(NWNX_Util, sFunc);
return NWNX_GetReturnValueInt();
}
void NWNX_Util_UpdateClientObject(object oObjectToUpdate, object oPlayer = OBJECT_INVALID)
{
string sFunc = "UpdateClientObject";
NWNX_PushArgumentObject(oPlayer);
NWNX_PushArgumentObject(oObjectToUpdate);
NWNX_CallFunction(NWNX_Util, sFunc);
}
int NWNX_Util_CleanResourceDirectory(string sAlias, int nResType = 0xFFFF)
{
string sFunc = "CleanResourceDirectory";
NWNX_PushArgumentInt(nResType);
NWNX_PushArgumentString(sAlias);
NWNX_CallFunction(NWNX_Util, sFunc);
return NWNX_GetReturnValueInt();
}
string NWNX_Util_GetModuleTlkFile()
{
string sFunc = "GetModuleTlkFile";
NWNX_CallFunction(NWNX_Util, sFunc);
return NWNX_GetReturnValueString();
}