1595 lines
61 KiB
Plaintext
1595 lines
61 KiB
Plaintext
///////////////////////////////////////////////////////////////////////////////
|
|
// ip_inc
|
|
// written by: eyesolated
|
|
// written at: Jan. 30, 2004
|
|
//
|
|
// Notes: Include File for the Magic Property System
|
|
|
|
///////////
|
|
// Includes
|
|
//
|
|
// Needs:
|
|
// #include "egs_inc"
|
|
#include "nwnx_sql"
|
|
#include "mod_cfg"
|
|
#include "egs_inc"
|
|
#include "ip_cfg"
|
|
#include "ip_rnd_inc"
|
|
#include "ip_names_inc"
|
|
#include "x2_inc_itemprop"
|
|
#include "x0_i0_stringlib"
|
|
#include "eas_inc"
|
|
|
|
///////////////////////
|
|
// Function Declaration
|
|
//
|
|
|
|
// Help for IP
|
|
void ip_Help();
|
|
|
|
// Recreate the DB Table
|
|
void ip_CreateTable();
|
|
|
|
// Returns FALSE if any of the required System Tables is missing
|
|
int ip_GetTableExists();
|
|
|
|
// Drops all System Tables
|
|
void ip_DropTable();
|
|
|
|
// ip_AddProperty
|
|
// PlayerOnly does not work w/o NWNX
|
|
// VarThree should always be 0 and is not used w/o NWNX to improve performance
|
|
void ip_AddProperty(int iProperty, int iType, string sCategoriesMain, string sCategoriesSub, string sBaseItems, int iLevel, int iVarOne, int iVarTwo, int iVarThree, int iMonsterOnly = FALSE, int iPlayerOnly = FALSE);
|
|
|
|
// Get a Random Item Property with the given criteria
|
|
struct STRUCT_IP_PropertyDetails ip_GetProperty(int iItemMainCategory = -1, int iItemSubCategory = -1, int iItemBaseItem = -1, int iLevel = -1, int iType = -1, int iMonster = FALSE, int iProperty = -1);
|
|
|
|
// Infuse an item with Magic
|
|
void ip_InfuseItemWithMagic(object oItem, int iMaxMagicLevel = 50, int iForceLevel = FALSE, int iIdentified = FALSE, int iNameItem = TRUE, int iIncludeMonsterOnly = FALSE, int iNumberOfProperties = -1, int iOverrideMaxAllowedConfig = -1);
|
|
|
|
// Returns a specific property
|
|
struct STRUCT_IP_PropertyDetails ip_GetSpecificProperty(int iBaseItem, int iProperty, int iVar1 = 0, int iVar2 = 0, int iVar3 = 0);
|
|
|
|
////////////////
|
|
// Function Code
|
|
//
|
|
void ip_Help()
|
|
{
|
|
}
|
|
|
|
// Private NON-NWNx helper code
|
|
void Create_IP_Item(object oStore, string sArray, string sPropertyIdentifier, int iPropID, int iVarOne, int iVarTwo, int iVarThree, string sVarOne, string sVarTwo, string sVarThree)
|
|
{
|
|
SetLocalInt(oStore, CS_IP_ID + sPropertyIdentifier, iPropID);
|
|
SetLocalInt(oStore, CS_IP_VARONE + sPropertyIdentifier, iVarOne);
|
|
SetLocalInt(oStore, CS_IP_VARTWO + sPropertyIdentifier, iVarTwo);
|
|
SetLocalInt(oStore, CS_IP_VARTHREE + sPropertyIdentifier, iVarThree);
|
|
|
|
// Create the default array
|
|
eas_Array_Create(oStore, sArray, EAS_ARRAY_TYPE_STRING);
|
|
eas_SArray_Entry_Add(oStore, sArray, sPropertyIdentifier);
|
|
|
|
// Create the VarOne Array
|
|
eas_Array_Create(oStore, sArray + sVarOne, EAS_ARRAY_TYPE_STRING);
|
|
eas_SArray_Entry_Add(oStore, sArray + sVarOne, sPropertyIdentifier);
|
|
|
|
// Create the VarTwo Array
|
|
eas_Array_Create(oStore, sArray + sVarTwo, EAS_ARRAY_TYPE_STRING);
|
|
eas_SArray_Entry_Add(oStore, sArray + sVarTwo, sPropertyIdentifier);
|
|
|
|
// Create the VarThree Array
|
|
//eas_Array_Create(oStore, sArray + sVarThree);
|
|
//eas_SArray_Entry_Add(oStore, sArray + sVarThree, sPropertyIdentifier);
|
|
|
|
// Create the Combined Arrays
|
|
eas_Array_Create(oStore, sArray + sVarOne + sVarTwo, EAS_ARRAY_TYPE_STRING);
|
|
eas_SArray_Entry_Add(oStore, sArray + sVarOne + sVarTwo, sPropertyIdentifier);
|
|
//eas_Array_Create(oStore, sArray + sVarOne + sVarTwo + sVarThree);
|
|
//eas_SArray_Entry_Add(oStore, sArray + sVarOne + sVarTwo + sVarThree, sPropertyIdentifier);
|
|
//eas_Array_Create(oStore, sArray + sVarOne + sVarThree);
|
|
//eas_SArray_Entry_Add(oStore, sArray + sVarOne + sVarThree, sPropertyIdentifier);
|
|
|
|
//eas_Array_Create(oStore, sArray + sVarTwo + sVarThree);
|
|
//eas_SArray_Entry_Add(oStore, sArray + sVarTwo + sVarThree, sPropertyIdentifier);
|
|
}
|
|
|
|
int ip_GetTableExists()
|
|
{
|
|
if (CI_IP_USE_NWNX)
|
|
{
|
|
int nExists_Table = NWNX_SQL_ExecuteQuery("DESCRIBE " + CS_IP_TABLE);
|
|
return (nExists_Table);
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
void ip_DropTable()
|
|
{
|
|
if (CI_IP_USE_NWNX)
|
|
NWNX_SQL_ExecuteQuery("DROP TABLE " + CS_IP_TABLE);
|
|
}
|
|
|
|
void ip_CreateTable()
|
|
{
|
|
if (CI_IP_USE_NWNX)
|
|
{
|
|
NWNX_SQL_ExecuteQuery("DROP TABLE " + CS_IP_TABLE);
|
|
string sSQL = "CREATE TABLE " + CS_IP_TABLE + " (";
|
|
sSQL += CS_IP_ID + " int NOT NULL, ";
|
|
sSQL += CS_IP_TYPE + " int DEFAULT NULL, ";
|
|
sSQL += CS_IP_CATEGORIES_MAIN + " varchar(32) DEFAULT NULL, ";
|
|
sSQL += CS_IP_CATEGORIES_SUB + " varchar(32) DEFAULT NULL, ";
|
|
sSQL += CS_IP_BASEITEMS + " varchar(32) DEFAULT NULL, ";
|
|
sSQL += CS_IP_LEVEL + " int DEFAULT NULL, ";
|
|
sSQL += CS_IP_VARONE + " int DEFAULT NULL, ";
|
|
sSQL += CS_IP_VARTWO + " int DEFAULT NULL, ";
|
|
sSQL += CS_IP_VARTHREE + " int DEFAULT NULL, ";
|
|
sSQL += CS_IP_MONSTERONLY + " int NOT NULL default 0, ";
|
|
sSQL += CS_IP_PLAYERONLY + " int NOT NULL default 0, ";
|
|
sSQL += "KEY idx (" + CS_IP_ID + ", " + CS_IP_TYPE + ", " + CS_IP_CATEGORIES_MAIN + ", " + CS_IP_CATEGORIES_SUB + ", " + CS_IP_BASEITEMS + ", " + CS_IP_LEVEL + ", " + CS_IP_VARONE + ", " + CS_IP_VARTWO + ", " + CS_IP_VARTHREE + ", " + CS_IP_MONSTERONLY + ", " + CS_IP_PLAYERONLY + "))";
|
|
NWNX_SQL_ExecuteQuery(sSQL);
|
|
}
|
|
else
|
|
{
|
|
object oStoreWaypoint = GetObjectByTag(CS_IP_DB_WAYPOINT);
|
|
CreateObject(OBJECT_TYPE_STORE, CS_IP_DB_MERCHANT_RESREF, GetLocation(oStoreWaypoint), FALSE, CS_IP_DB_MERCHANT_ID);
|
|
CreateObject(OBJECT_TYPE_STORE, CS_IP_DB_MERCHANT_RESREF, GetLocation(oStoreWaypoint), FALSE, CS_IP_DB_MERCHANT_MAIN);
|
|
CreateObject(OBJECT_TYPE_STORE, CS_IP_DB_MERCHANT_RESREF, GetLocation(oStoreWaypoint), FALSE, CS_IP_DB_MERCHANT_SUB);
|
|
CreateObject(OBJECT_TYPE_STORE, CS_IP_DB_MERCHANT_RESREF, GetLocation(oStoreWaypoint), FALSE, CS_IP_DB_MERCHANT_BASE);
|
|
CreateObject(OBJECT_TYPE_STORE, CS_IP_DB_MERCHANT_RESREF, GetLocation(oStoreWaypoint), FALSE, CS_IP_DB_MERCHANT_MONSTERONLY_ID);
|
|
CreateObject(OBJECT_TYPE_STORE, CS_IP_DB_MERCHANT_RESREF, GetLocation(oStoreWaypoint), FALSE, CS_IP_DB_MERCHANT_MONSTERONLY_MAIN);
|
|
CreateObject(OBJECT_TYPE_STORE, CS_IP_DB_MERCHANT_RESREF, GetLocation(oStoreWaypoint), FALSE, CS_IP_DB_MERCHANT_MONSTERONLY_SUB);
|
|
CreateObject(OBJECT_TYPE_STORE, CS_IP_DB_MERCHANT_RESREF, GetLocation(oStoreWaypoint), FALSE, CS_IP_DB_MERCHANT_MONSTERONLY_BASE);
|
|
}
|
|
}
|
|
|
|
void ip_AddProperty(int iProperty,
|
|
int iType,
|
|
string sCategoriesMain,
|
|
string sCategoriesSub,
|
|
string sBaseItems,
|
|
int iLevel,
|
|
int iVarOne,
|
|
int iVarTwo,
|
|
int iVarThree,
|
|
int iMonsterOnly = FALSE,
|
|
int iPlayerOnly = FALSE)
|
|
{
|
|
if (CI_IP_USE_NWNX)
|
|
{
|
|
sCategoriesMain = "'" + sCategoriesMain + "'";
|
|
sCategoriesSub = "'" + sCategoriesSub + "'";
|
|
sBaseItems = "'" + sBaseItems + "'";
|
|
string sSQL = "INSERT INTO " + CS_IP_TABLE + " (" + CS_IP_ID + ", " + CS_IP_TYPE + ", " + CS_IP_CATEGORIES_MAIN + ", " + CS_IP_CATEGORIES_SUB + ", " + CS_IP_BASEITEMS + ", " + CS_IP_LEVEL + ", " + CS_IP_VARONE + ", " + CS_IP_VARTWO + ", " + CS_IP_VARTHREE + ", " + CS_IP_MONSTERONLY + ", " + CS_IP_PLAYERONLY + ") ";
|
|
sSQL += "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
|
NWNX_SQL_PrepareQuery(sSQL);
|
|
NWNX_SQL_PreparedInt(0, iProperty);
|
|
NWNX_SQL_PreparedInt(1, iType);
|
|
NWNX_SQL_PreparedString(2, sCategoriesMain);
|
|
NWNX_SQL_PreparedString(3, sCategoriesSub);
|
|
NWNX_SQL_PreparedString(4, sBaseItems);
|
|
NWNX_SQL_PreparedInt(5, iLevel);
|
|
NWNX_SQL_PreparedInt(6, iVarOne);
|
|
NWNX_SQL_PreparedInt(7, iVarTwo);
|
|
NWNX_SQL_PreparedInt(8, iVarThree);
|
|
NWNX_SQL_PreparedInt(9, iMonsterOnly);
|
|
NWNX_SQL_PreparedInt(10, iPlayerOnly);
|
|
NWNX_SQL_ExecutePreparedQuery();
|
|
}
|
|
else
|
|
{
|
|
// First, we have to split the category strings and put them in a string array
|
|
object oArrayStore = GetObjectByTag(CS_IP_DB_AREA);
|
|
int n;
|
|
string sToken;
|
|
|
|
// Create the Temporary Arrays
|
|
eas_Array_Create(oArrayStore, CS_IP_DB_TEMPARRAY_MAINCATEGORIES, EAS_ARRAY_TYPE_STRING);
|
|
eas_Array_Create(oArrayStore, CS_IP_DB_TEMPARRAY_SUBCATEGORIES, EAS_ARRAY_TYPE_STRING);
|
|
eas_Array_Create(oArrayStore, CS_IP_DB_TEMPARRAY_BASEITEMS, EAS_ARRAY_TYPE_STRING);
|
|
|
|
// Fill the Arrays
|
|
if (sCategoriesMain != "")
|
|
{
|
|
n = 1;
|
|
sToken = GetTokenByPosition(sCategoriesMain, ";", n);
|
|
while (sToken != "")
|
|
{
|
|
eas_SArray_Entry_Add(oArrayStore, CS_IP_DB_TEMPARRAY_MAINCATEGORIES, sToken);
|
|
n++;
|
|
sToken = GetTokenByPosition(sCategoriesMain, ";", n);
|
|
}
|
|
}
|
|
if (sCategoriesSub != "")
|
|
{
|
|
n = 1;
|
|
sToken = GetTokenByPosition(sCategoriesSub, ";", n);
|
|
while (sToken != "")
|
|
{
|
|
eas_SArray_Entry_Add(oArrayStore, CS_IP_DB_TEMPARRAY_SUBCATEGORIES, sToken);
|
|
n++;
|
|
sToken = GetTokenByPosition(sCategoriesSub, ";", n);
|
|
}
|
|
}
|
|
if (sBaseItems != "")
|
|
{
|
|
n = 1;
|
|
sToken = GetTokenByPosition(sBaseItems, ";", n);
|
|
while (sToken != "")
|
|
{
|
|
eas_SArray_Entry_Add(oArrayStore, CS_IP_DB_TEMPARRAY_BASEITEMS, sToken);
|
|
n++;
|
|
sToken = GetTokenByPosition(sBaseItems, ";", n);
|
|
}
|
|
}
|
|
|
|
// Get the Merchant Object
|
|
// For Item Properties, we HAVE to use more than one else things slow down really hard
|
|
object oStore_ID = GetObjectByTag(CS_IP_DB_MERCHANT_ID);
|
|
object oStore_Main = GetObjectByTag(CS_IP_DB_MERCHANT_MAIN);
|
|
object oStore_Sub = GetObjectByTag(CS_IP_DB_MERCHANT_SUB);
|
|
object oStore_Base = GetObjectByTag(CS_IP_DB_MERCHANT_BASE);
|
|
object oStore_MonsterOnly_ID = GetObjectByTag(CS_IP_DB_MERCHANT_MONSTERONLY_ID);
|
|
object oStore_MonsterOnly_Main = GetObjectByTag(CS_IP_DB_MERCHANT_MONSTERONLY_MAIN);
|
|
object oStore_MonsterOnly_Sub = GetObjectByTag(CS_IP_DB_MERCHANT_MONSTERONLY_SUB);
|
|
object oStore_MonsterOnly_Base = GetObjectByTag(CS_IP_DB_MERCHANT_MONSTERONLY_BASE);
|
|
|
|
string sPropertyIdentifier;
|
|
string sArrayName;
|
|
int nCategory;
|
|
|
|
string sVarOne = "_V1" + IntToString(iVarOne);
|
|
string sVarTwo = "_V2" + IntToString(iVarTwo);
|
|
string sVarThree = "_V3" + IntToString(iVarThree);
|
|
|
|
int nMainCategories = eas_Array_GetSize(oArrayStore, CS_IP_DB_TEMPARRAY_MAINCATEGORIES);
|
|
int nSubCategories = eas_Array_GetSize(oArrayStore, CS_IP_DB_TEMPARRAY_SUBCATEGORIES);
|
|
int nBaseItems = eas_Array_GetSize(oArrayStore, CS_IP_DB_TEMPARRAY_BASEITEMS);
|
|
string sCategoryID;
|
|
|
|
// Create the IP in the ID Store
|
|
sPropertyIdentifier = "IP_" + IntToString(iProperty)+ "_L" + IntToString(iLevel) + "_T" + IntToString(iType);
|
|
if (!iMonsterOnly)
|
|
{
|
|
SetLocalInt(oStore_ID, CS_IP_ID + sPropertyIdentifier, iProperty);
|
|
SetLocalInt(oStore_ID, CS_IP_VARONE + sPropertyIdentifier, iVarOne);
|
|
SetLocalInt(oStore_ID, CS_IP_VARTWO + sPropertyIdentifier, iVarTwo);
|
|
SetLocalInt(oStore_ID, CS_IP_VARTHREE + sPropertyIdentifier, iVarThree);
|
|
}
|
|
SetLocalInt(oStore_MonsterOnly_ID, CS_IP_ID + sPropertyIdentifier, iProperty);
|
|
SetLocalInt(oStore_MonsterOnly_ID, CS_IP_VARONE + sPropertyIdentifier, iVarOne);
|
|
SetLocalInt(oStore_MonsterOnly_ID, CS_IP_VARTWO + sPropertyIdentifier, iVarTwo);
|
|
SetLocalInt(oStore_MonsterOnly_ID, CS_IP_VARTHREE + sPropertyIdentifier, iVarThree);
|
|
|
|
// Create the IP in the MainCategory Store
|
|
for (nCategory = 0; nCategory < nMainCategories; nCategory++)
|
|
{
|
|
sCategoryID = eas_SArray_Entry_Get(oArrayStore, CS_IP_DB_TEMPARRAY_MAINCATEGORIES, nCategory);
|
|
sArrayName = CS_IP_ARRAY_MAINCATEGORY + sCategoryID + "_L" + IntToString(iLevel) + "_T" + IntToString(iType);
|
|
sPropertyIdentifier = "IP_" + IntToString(iProperty) + "_MC" + sCategoryID + "_L" + IntToString(iLevel) + "_T" + IntToString(iType) + sVarOne + sVarTwo + sVarThree;
|
|
if (!iMonsterOnly)
|
|
Create_IP_Item(oStore_Main, sArrayName, sPropertyIdentifier, iProperty, iVarOne, iVarTwo, iVarThree, sVarOne, sVarTwo, sVarThree);
|
|
Create_IP_Item(oStore_MonsterOnly_Main, sArrayName, sPropertyIdentifier, iProperty, iVarOne, iVarTwo, iVarThree, sVarOne, sVarTwo, sVarThree);
|
|
}
|
|
|
|
// Create the IP in the SubCategory Store
|
|
for (nCategory = 0; nCategory < nSubCategories; nCategory++)
|
|
{
|
|
sCategoryID = eas_SArray_Entry_Get(oArrayStore, CS_IP_DB_TEMPARRAY_SUBCATEGORIES, nCategory);
|
|
sArrayName = CS_IP_ARRAY_SUBCATEGORY + sCategoryID + "_L" + IntToString(iLevel) + "_T" + IntToString(iType);
|
|
sPropertyIdentifier = "IP_" + IntToString(iProperty) + "_SC" + sCategoryID + "_L" + IntToString(iLevel) + "_T" + IntToString(iType) + sVarOne + sVarTwo + sVarThree;
|
|
if (!iMonsterOnly)
|
|
Create_IP_Item(oStore_Sub, sArrayName, sPropertyIdentifier, iProperty, iVarOne, iVarTwo, iVarThree, sVarOne, sVarTwo, sVarThree);
|
|
Create_IP_Item(oStore_MonsterOnly_Sub, sArrayName, sPropertyIdentifier, iProperty, iVarOne, iVarTwo, iVarThree, sVarOne, sVarTwo, sVarThree);
|
|
}
|
|
|
|
// Create the IP in the BaseItem Store
|
|
for (nCategory = 0; nCategory < nBaseItems; nCategory++)
|
|
{
|
|
sCategoryID = eas_SArray_Entry_Get(oArrayStore, CS_IP_DB_TEMPARRAY_BASEITEMS, nCategory);
|
|
sArrayName = CS_IP_ARRAY_BASEITEM + sCategoryID + "_L" + IntToString(iLevel) + "_T" + IntToString(iType);
|
|
sPropertyIdentifier = "IP_" + IntToString(iProperty) + "_BI" + sCategoryID + "_L" + IntToString(iLevel) + "_T" + IntToString(iType) + sVarOne + sVarTwo + sVarThree;
|
|
if (!iMonsterOnly)
|
|
Create_IP_Item(oStore_Base, sArrayName, sPropertyIdentifier, iProperty, iVarOne, iVarTwo, iVarThree, sVarOne, sVarTwo, sVarThree);
|
|
Create_IP_Item(oStore_MonsterOnly_Base, sArrayName, sPropertyIdentifier, iProperty, iVarOne, iVarTwo, iVarThree, sVarOne, sVarTwo, sVarThree);
|
|
}
|
|
|
|
// Destroy the temporary string arrays
|
|
eas_Array_Delete(oArrayStore, CS_IP_DB_TEMPARRAY_MAINCATEGORIES);
|
|
eas_Array_Delete(oArrayStore, CS_IP_DB_TEMPARRAY_SUBCATEGORIES);
|
|
eas_Array_Delete(oArrayStore, CS_IP_DB_TEMPARRAY_BASEITEMS);
|
|
}
|
|
}
|
|
|
|
int WeightedRandom(int nPossibilities, int nRandomMax, object oArrayStore)
|
|
{
|
|
int nRoll = Random(nRandomMax);
|
|
int n;
|
|
int nWorth;
|
|
for (n = 0 ; n < nPossibilities; n++)
|
|
{
|
|
nWorth = GetLocalInt(oArrayStore, IntToString(n));
|
|
if(nRoll < nWorth)
|
|
{
|
|
return ( n );
|
|
}
|
|
nRoll -= nWorth;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct STRUCT_IP_PropertyDetails ip_GetProperty(int iItemMainCategory = -1,
|
|
int iItemSubCategory = -1,
|
|
int iItemBaseItem = -1,
|
|
int iLevel = -1,
|
|
int iType = -1,
|
|
int iMonster = FALSE,
|
|
int iProperty = -1)
|
|
{
|
|
struct STRUCT_IP_PropertyDetails strResult;
|
|
if (CI_IP_USE_NWNX)
|
|
{
|
|
string sSQL_Property_ID = "SELECT DISTINCT " + CS_IP_ID + " FROM " + CS_IP_TABLE + " WHERE ";
|
|
string sSQL = "SELECT " + CS_IP_ID + ", " + CS_IP_VARONE + ", " + CS_IP_VARTWO + ", " + CS_IP_VARTHREE + " FROM " + CS_IP_TABLE + " WHERE ";
|
|
|
|
int iAND = FALSE;
|
|
string sWhere = "";
|
|
if (iItemMainCategory > -1)
|
|
{
|
|
sWhere += "(" + CS_IP_CATEGORIES_MAIN + " LIKE '%;" + IntToString(iItemMainCategory) + ";%'";
|
|
iAND = TRUE;
|
|
}
|
|
if (iItemSubCategory > -1)
|
|
{
|
|
if (iAND)
|
|
sWhere += " OR ";
|
|
else
|
|
sWhere += "(";
|
|
|
|
sWhere += CS_IP_CATEGORIES_SUB + " LIKE '%;" + IntToString(iItemSubCategory) + ";%'";
|
|
iAND = TRUE;
|
|
}
|
|
if (iItemBaseItem > -1)
|
|
{
|
|
if (iAND)
|
|
sWhere += " OR ";
|
|
|
|
else
|
|
sWhere += "(";
|
|
|
|
sWhere += CS_IP_BASEITEMS + " LIKE '%;" + IntToString(iItemBaseItem) + ";%'";
|
|
iAND = TRUE;
|
|
}
|
|
|
|
if (iAND)
|
|
sWhere += ")";
|
|
|
|
if (iLevel > -1)
|
|
{
|
|
if (iAND)
|
|
sWhere += " AND ";
|
|
|
|
sWhere += CS_IP_LEVEL + " = " + IntToString(iLevel);
|
|
iAND = TRUE;
|
|
}
|
|
if (iType > -1)
|
|
{
|
|
if (iAND)
|
|
sWhere += " AND ";
|
|
|
|
sWhere += CS_IP_TYPE + " = " + IntToString(iType);
|
|
iAND = TRUE;
|
|
}
|
|
if (iProperty > -1)
|
|
{
|
|
if (iAND)
|
|
sWhere += " AND ";
|
|
|
|
sWhere += CS_IP_ID + " = " + IntToString(iProperty);
|
|
iAND = TRUE;
|
|
}
|
|
|
|
if (iAND && iMonster == FALSE)
|
|
sWhere += " AND ";
|
|
if (iMonster == FALSE)
|
|
sWhere += CS_IP_MONSTERONLY + " = 0";
|
|
|
|
sSQL += sWhere;
|
|
sSQL_Property_ID += sWhere;
|
|
sSQL_Property_ID += " ORDER BY rand() LIMIT 1";
|
|
|
|
// Execute first query to determine property
|
|
NWNX_SQL_ExecuteQuery(sSQL_Property_ID);
|
|
if (NWNX_SQL_ReadyToReadNextRow())
|
|
{
|
|
NWNX_SQL_ReadNextRow();
|
|
string sProperty_ID = NWNX_SQL_ReadDataInActiveRow(0);
|
|
if (iAND)
|
|
sSQL += " AND ";
|
|
sSQL += CS_IP_ID + " = " + sProperty_ID;
|
|
}
|
|
|
|
sSQL += " ORDER BY rand() LIMIT 1";
|
|
|
|
NWNX_SQL_ExecuteQuery(sSQL);
|
|
if (NWNX_SQL_ReadyToReadNextRow())
|
|
{
|
|
NWNX_SQL_ReadNextRow();
|
|
int iPropID = StringToInt(NWNX_SQL_ReadDataInActiveRow(0));
|
|
int iVar1 = StringToInt(NWNX_SQL_ReadDataInActiveRow(1));
|
|
int iVar2 = StringToInt(NWNX_SQL_ReadDataInActiveRow(2));
|
|
int iVar3 = StringToInt(NWNX_SQL_ReadDataInActiveRow(3));
|
|
strResult = ( ip_GetSpecificProperty( iItemBaseItem, iPropID, iVar1, iVar2, iVar3 ) );
|
|
strResult.PropID = iPropID;
|
|
return (strResult);
|
|
}
|
|
else
|
|
{
|
|
strResult.PropID = CI_IP_Invalid;
|
|
return (strResult);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Get the Merchant Object
|
|
object oStore_ID;
|
|
object oStore_Main;
|
|
object oStore_Sub;
|
|
object oStore_Base;
|
|
if (!iMonster)
|
|
{
|
|
oStore_ID = GetObjectByTag(CS_IP_DB_MERCHANT_ID);
|
|
oStore_Main = GetObjectByTag(CS_IP_DB_MERCHANT_MAIN);
|
|
oStore_Sub = GetObjectByTag(CS_IP_DB_MERCHANT_SUB);
|
|
oStore_Base = GetObjectByTag(CS_IP_DB_MERCHANT_BASE);
|
|
}
|
|
else
|
|
{
|
|
oStore_ID = GetObjectByTag(CS_IP_DB_MERCHANT_MONSTERONLY_ID);
|
|
oStore_Main = GetObjectByTag(CS_IP_DB_MERCHANT_MONSTERONLY_MAIN);
|
|
oStore_Sub = GetObjectByTag(CS_IP_DB_MERCHANT_MONSTERONLY_SUB);
|
|
oStore_Base = GetObjectByTag(CS_IP_DB_MERCHANT_MONSTERONLY_BASE);
|
|
}
|
|
|
|
// Select the array that contains appropriate Item Properties
|
|
int nArray_ID;
|
|
int nArray_Main;
|
|
int nArray_Sub;
|
|
int nArray_Base;
|
|
string sMonsterOnly = "_MO" + IntToString(iMonster);
|
|
string sArray_ID = CS_IP_ARRAY_ID + "_L" + IntToString(iLevel) + "_T" + IntToString(iType);
|
|
string sArray_Main = CS_IP_ARRAY_MAINCATEGORY + IntToString(iItemMainCategory) + "_L" + IntToString(iLevel) + "_T" + IntToString(iType);
|
|
string sArray_Sub = CS_IP_ARRAY_SUBCATEGORY + IntToString(iItemSubCategory) + "_L" + IntToString(iLevel) + "_T" + IntToString(iType);
|
|
string sArray_Base = CS_IP_ARRAY_BASEITEM + IntToString(iItemBaseItem) + "_L" + IntToString(iLevel) + "_T" + IntToString(iType);
|
|
|
|
if (iItemMainCategory != -1)
|
|
{
|
|
nArray_Main = eas_Array_Exists(oStore_Main, sArray_Main);
|
|
}
|
|
if (iItemSubCategory != -1)
|
|
{
|
|
nArray_Sub = eas_Array_Exists(oStore_Sub, sArray_Sub);
|
|
}
|
|
if (iItemBaseItem != -1)
|
|
{
|
|
nArray_Base = eas_Array_Exists(oStore_Base, sArray_Base);
|
|
}
|
|
|
|
// If no usable Array was found, exit this method
|
|
if (iProperty == -1 &&
|
|
!nArray_Main &&
|
|
!nArray_Sub &&
|
|
!nArray_Base)
|
|
{
|
|
strResult.PropID = CI_IP_Invalid;
|
|
return (strResult);
|
|
}
|
|
|
|
string sPropertyInfo = "";
|
|
object oSelectedStore;
|
|
// If we want a specific property, do that
|
|
if (iProperty != -1)
|
|
{
|
|
string sPropertyIdentifier = "IP_" + IntToString(iProperty)+ "_L" + IntToString(iLevel) + "_T" + IntToString(iType);
|
|
|
|
int iPropID = GetLocalInt(oStore_ID, CS_IP_ID + sPropertyIdentifier);
|
|
int iVar1 = GetLocalInt(oStore_ID, CS_IP_VARONE + sPropertyIdentifier);
|
|
int iVar2 = GetLocalInt(oStore_ID, CS_IP_VARTWO + sPropertyIdentifier);
|
|
int iVar3 = GetLocalInt(oStore_ID, CS_IP_VARTHREE + sPropertyIdentifier);
|
|
strResult = ( ip_GetSpecificProperty( iItemBaseItem, iPropID, iVar1, iVar2, iVar3 ) );
|
|
strResult.PropID = iPropID;
|
|
|
|
return (strResult);
|
|
}
|
|
else
|
|
{
|
|
object oArrayStore = GetObjectByTag(CS_IP_DB_AREA);
|
|
// Now get a random Property from the selected store(s), beginning by Base
|
|
string sPropertyInfo_Base = "";
|
|
string sPropertyInfo_Sub = "";
|
|
string sPropertyInfo_Main = "";
|
|
int nArraySize_Base = eas_Array_GetSize(oStore_Base, sArray_Base);
|
|
int nArraySize_Sub = eas_Array_GetSize(oStore_Sub, sArray_Sub);
|
|
int nArraySize_Main = eas_Array_GetSize(oStore_Main, sArray_Main);
|
|
|
|
if (nArray_Base)
|
|
sPropertyInfo_Base = eas_SArray_Entry_Get(oStore_Base, sArray_Base, Random(nArraySize_Base));
|
|
|
|
if (nArray_Sub)
|
|
sPropertyInfo_Sub = eas_SArray_Entry_Get(oStore_Sub, sArray_Sub, Random(nArraySize_Sub));
|
|
|
|
if (nArray_Main)
|
|
sPropertyInfo_Main = eas_SArray_Entry_Get(oStore_Main, sArray_Main, Random(nArraySize_Main));
|
|
|
|
eas_Array_Create(oArrayStore, CS_IP_DB_TEMPARRAY_STORE, EAS_ARRAY_TYPE_OBJECT);
|
|
eas_Array_Create(oArrayStore, CS_IP_DB_TEMPARRAY_SELECTIP, EAS_ARRAY_TYPE_STRING);
|
|
int nRandomMax = 0;
|
|
int nWorth;
|
|
int nPossibilities = 0;
|
|
|
|
if (sPropertyInfo_Base != "")
|
|
{
|
|
nWorth = nArraySize_Base;
|
|
eas_OArray_Entry_Add(oArrayStore, CS_IP_DB_TEMPARRAY_STORE, oStore_Base);
|
|
eas_SArray_Entry_Add(oArrayStore, CS_IP_DB_TEMPARRAY_SELECTIP, sPropertyInfo_Base);
|
|
nRandomMax += nWorth;
|
|
SetLocalInt(oArrayStore, IntToString(nPossibilities), nWorth);
|
|
nPossibilities += 1;
|
|
}
|
|
if (sPropertyInfo_Sub != "")
|
|
{
|
|
nWorth = nArraySize_Sub;
|
|
eas_OArray_Entry_Add(oArrayStore, CS_IP_DB_TEMPARRAY_STORE, oStore_Sub);
|
|
eas_SArray_Entry_Add(oArrayStore, CS_IP_DB_TEMPARRAY_SELECTIP, sPropertyInfo_Sub);
|
|
nRandomMax += nWorth;
|
|
SetLocalInt(oArrayStore, IntToString(nPossibilities), nWorth);
|
|
nPossibilities += 1;
|
|
}
|
|
if (sPropertyInfo_Main != "")
|
|
{
|
|
nWorth = nArraySize_Main;
|
|
eas_OArray_Entry_Add(oArrayStore, CS_IP_DB_TEMPARRAY_STORE, oStore_Main);
|
|
eas_SArray_Entry_Add(oArrayStore, CS_IP_DB_TEMPARRAY_SELECTIP, sPropertyInfo_Main);
|
|
nRandomMax += nWorth;
|
|
SetLocalInt(oArrayStore, IntToString(nPossibilities), nWorth);
|
|
nPossibilities += 1;
|
|
}
|
|
// Do the weighted randomizer
|
|
int nRandom = WeightedRandom(nPossibilities, nRandomMax, oArrayStore);
|
|
|
|
object oSelectedStore = eas_OArray_Entry_Get(oArrayStore, CS_IP_DB_TEMPARRAY_STORE, nRandom);
|
|
sPropertyInfo = eas_SArray_Entry_Get(oArrayStore, CS_IP_DB_TEMPARRAY_SELECTIP, nRandom);
|
|
|
|
eas_Array_Delete(oArrayStore, CS_IP_DB_TEMPARRAY_SELECTIP);
|
|
eas_Array_Delete(oArrayStore, CS_IP_DB_TEMPARRAY_STORE);
|
|
|
|
if (sPropertyInfo != "")
|
|
{
|
|
int iPropID = GetLocalInt(oSelectedStore, CS_IP_ID + sPropertyInfo);
|
|
int iVar1 = GetLocalInt(oSelectedStore, CS_IP_VARONE + sPropertyInfo);
|
|
int iVar2 = GetLocalInt(oSelectedStore, CS_IP_VARTWO + sPropertyInfo);
|
|
int iVar3 = GetLocalInt(oSelectedStore, CS_IP_VARTHREE + sPropertyInfo);
|
|
strResult = ( ip_GetSpecificProperty( iItemBaseItem, iPropID, iVar1, iVar2, iVar3 ) );
|
|
strResult.PropID = iPropID;
|
|
|
|
return (strResult);
|
|
}
|
|
else
|
|
{
|
|
SendMessageToAllDMs("Invalid property");
|
|
strResult.PropID = CI_IP_Invalid;
|
|
return (strResult);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ip_InfuseItemWithMagic(object oItem, int iMaxMagicLevel = 50, int iForceLevel = FALSE, int iIdentified = FALSE, int iNameItem = TRUE, int iIncludeMonsterOnly = FALSE, int iNumberOfProperties = -1, int iOverrideMaxAllowedConfig = -1)
|
|
{
|
|
// If oItem is Invalid, quit right away
|
|
if (!GetIsObjectValid(oItem))
|
|
return;
|
|
|
|
// Let's get all info on this item first
|
|
struct STRUCT_EGS_ITEMINFO strItem;
|
|
string sItemTag = GetTag(oItem);
|
|
strItem = egs_GetItemInfo(sItemTag);
|
|
|
|
// If no item was found, try using the item object
|
|
if (strItem.MainCategory == 0)
|
|
strItem = egs_GetItemObjectInfo(oItem);
|
|
|
|
/*DEBUG
|
|
SendMessageToAllDMs("Infusing Item '" + sItemTag + "'\n" +
|
|
"Main Category: " + IntToString(strItem.MainCategory) + "\n" +
|
|
"Sub Category: " + IntToString(strItem.SubCategory) + "\n" +
|
|
"Base Item: " + IntToString(strItem.BaseItem));
|
|
END DEBUG*/
|
|
|
|
// Let's do some precalculations here
|
|
|
|
// What's the true MagicLevel we start with?
|
|
// int iActualLevel = Random(iMaxMagicLevel) + 1;
|
|
int iActualLevel = iMaxMagicLevel;
|
|
|
|
// Now we will further reduce the magic level by chance
|
|
int iMinusChance;
|
|
int iCount;
|
|
int iReduceLoop = iMaxMagicLevel / CI_IP_REDUCED_ITEM_LEVEL_MAXIMUM_DIVISOR;
|
|
for (iCount = 0; iCount < iReduceLoop; iCount++)
|
|
{
|
|
iMinusChance = d100();
|
|
if (iMinusChance < (CI_IP_REDUCED_ITEM_LEVEL_CHANCE_BASE - (iCount * CI_IP_REDUCED_ITEM_LEVEL_CHANCE_MODIFIER)) )
|
|
iActualLevel--;
|
|
else
|
|
break;
|
|
}
|
|
|
|
if (iForceLevel)
|
|
iActualLevel = iMaxMagicLevel;
|
|
|
|
// Retrieve the maximum allowed iLevel
|
|
int nMaxAllowedByConfig = iOverrideMaxAllowedConfig;
|
|
if (nMaxAllowedByConfig == -1)
|
|
nMaxAllowedByConfig = CI_IP_MAXMAGICLEVEL;
|
|
|
|
if (iActualLevel < 1) // if level < 1, set to 1
|
|
iActualLevel = 1;
|
|
else if (iActualLevel > nMaxAllowedByConfig && // if level > max allowed and NOT only monsters, set to max allowed
|
|
!iIncludeMonsterOnly)
|
|
iActualLevel = nMaxAllowedByConfig;
|
|
else if (iActualLevel > CI_IP_MAXMAGICLEVEL_MONSTERONLY) // if level > max allowed monsterlevel, set to max allowed monsterlevel
|
|
iActualLevel = CI_IP_MAXMAGICLEVEL_MONSTERONLY;
|
|
|
|
// Some items can't be magical
|
|
switch (strItem.MainCategory)
|
|
{
|
|
case CI_EGS_ITEM_MAIN_FOOD:
|
|
return;
|
|
case CI_EGS_ITEM_MAIN_BOMB:
|
|
return;
|
|
break;
|
|
}
|
|
|
|
// Some items need to be created with a Property in the toolset, here we're
|
|
// deleting that temporary Property. Furthermore, these items are only
|
|
// allowed to have ONE Property, we set them here.
|
|
//
|
|
// Some items are not getting properties at all
|
|
int iStopAfterFirst = FALSE;
|
|
int iAddedRestrictiveChance = 0;
|
|
switch (strItem.BaseItem)
|
|
{
|
|
case BASE_ITEM_POTIONS:
|
|
iStopAfterFirst = TRUE;
|
|
RemoveItemProperty(oItem, GetFirstItemProperty(oItem));
|
|
break;
|
|
case BASE_ITEM_TRAPKIT:
|
|
iStopAfterFirst = TRUE;
|
|
RemoveItemProperty(oItem, GetFirstItemProperty(oItem));
|
|
break;
|
|
case BASE_ITEM_MAGICWAND:
|
|
iStopAfterFirst = TRUE;
|
|
RemoveItemProperty(oItem, GetFirstItemProperty(oItem));
|
|
iAddedRestrictiveChance = CI_IP_RODWAND_EXTRA_CHANCE_RESTRICTIVE;
|
|
break;
|
|
case BASE_ITEM_MAGICROD:
|
|
iStopAfterFirst = TRUE;
|
|
RemoveItemProperty(oItem, GetFirstItemProperty(oItem));
|
|
iAddedRestrictiveChance = CI_IP_RODWAND_EXTRA_CHANCE_RESTRICTIVE;
|
|
break;
|
|
case BASE_ITEM_BOOK:
|
|
SetPlotFlag(oItem, TRUE); // Books can have more than one property and should not be destroyed when using up one
|
|
break;
|
|
case BASE_ITEM_LARGEBOX: iStopAfterFirst = TRUE; break;
|
|
case BASE_ITEM_HEALERSKIT: iStopAfterFirst = TRUE; break;
|
|
case BASE_ITEM_THIEVESTOOLS: iStopAfterFirst = TRUE; break;
|
|
}
|
|
|
|
struct STRUCT_IP_PropertyDetails strIP;
|
|
|
|
// Save the determined ActualLevel for later use
|
|
int iSavedLevel = iActualLevel;
|
|
|
|
// Get positive properties
|
|
int iPropCount = 0; // no properties atm
|
|
int iTries = 0;
|
|
int iMaxProps = CI_IP_MAX_POSITIVE;
|
|
if (iMaxProps < 1)
|
|
iMaxProps = 1;
|
|
if (iMaxProps > CI_IP_MAX_POSITIVE)
|
|
iMaxProps = CI_IP_MAX_POSITIVE;
|
|
|
|
int iPositivePropsWithinRareDeviation = 0;
|
|
int iPositivePropsWithinEpicDeviation = 0;
|
|
int iPositiveProps = 0;
|
|
int iNegativeProps = 0;
|
|
int iRestrictiveProps = 0;
|
|
|
|
int iAnotherProp;
|
|
while (
|
|
(
|
|
(iTries < iMaxProps) &&
|
|
(
|
|
(iPropCount == 0) ||
|
|
(iAnotherProp <= CI_IP_ADDITIONAL_POSITIVE_PROPERTY_CHANCE_BASE - (iPropCount * CI_IP_ADDITIONAL_POSITIVE_PROPERTY_CHANCE_MODIFIER)) && (iPropCount < iMaxProps)
|
|
)
|
|
) ||
|
|
(
|
|
(iPropCount < iNumberOfProperties) &&
|
|
(iTries < iNumberOfProperties * 2)
|
|
)
|
|
)
|
|
{
|
|
iTries++;
|
|
strIP = ip_GetProperty(strItem.MainCategory, strItem.SubCategory, strItem.BaseItem, iActualLevel, CI_IP_TYPE_POSITIVE, iIncludeMonsterOnly);
|
|
//SendMessageToAllDMs("Selected property for: " + GetName(oItem) + "\nLevel: " + IntToString(iActualLevel) + " = " + IntToString(GetItemPropertyType(strIP.IP)));
|
|
if (strIP.PropID == CI_IP_Invalid)
|
|
{
|
|
//SendMessageToAllDMs("Error getting positive property for: " + GetName(oItem) + "\nLevel: " + IntToString(iActualLevel));
|
|
WriteTimestampedLogEntry("Error getting positive property for: " + GetName(oItem) + "\nLevel: " + IntToString(iActualLevel));
|
|
continue;
|
|
}
|
|
|
|
// if the chosen property is already on the item, try again
|
|
if (!iStopAfterFirst && // we don't need this check if we only apply one property
|
|
(strItem.BaseItem != BASE_ITEM_BOOK && strIP.PropID != CI_IP_CastSpell) && // Books can have more spells to cast
|
|
(strItem.BaseItem != BASE_ITEM_MAGICSTAFF && strIP.PropID != CI_IP_CastSpell) && // Staves can have more spells to cast
|
|
GetItemHasItemProperty(oItem, GetItemPropertyType(strIP.IP)))
|
|
{
|
|
//SendMessageToAllDMs("Chosen property already exists... Trying again");
|
|
continue;
|
|
}
|
|
IPSafeAddItemProperty(oItem, strIP.IP, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
|
|
iPropCount++;
|
|
iPositiveProps++;
|
|
if (CI_IP_EPIC_ALLOWED_POSITIVE_DEVIATION == -1 ||
|
|
iActualLevel >= (iMaxMagicLevel - CI_IP_EPIC_ALLOWED_POSITIVE_DEVIATION))
|
|
iPositivePropsWithinEpicDeviation++;
|
|
if (CI_IP_RARE_ALLOWED_POSITIVE_DEVIATION == -1 ||
|
|
iActualLevel >= (iMaxMagicLevel - CI_IP_RARE_ALLOWED_POSITIVE_DEVIATION))
|
|
iPositivePropsWithinRareDeviation++;
|
|
|
|
// Store this property on the item as variables
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "ID", strIP.PropID);
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "Var1", strIP.Var1);
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "Var2", strIP.Var2);
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "Var3", strIP.Var3);
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "Lvl", iActualLevel);
|
|
|
|
// If this is a one-property item, stop looping
|
|
if (iStopAfterFirst)
|
|
break;
|
|
|
|
iAnotherProp = d100();
|
|
iActualLevel -= Random(CI_IP_ADDITIONAL_POSITIVE_PROPERTY_LEVEL_MODIFIER_RANDOM) + CI_IP_ADDITIONAL_POSITIVE_PROPERTY_LEVEL_MODIFIER_BASE;
|
|
if (iActualLevel < 1)
|
|
iActualLevel = 1;
|
|
}
|
|
|
|
if (strItem.MainCategory == CI_EGS_ITEM_MAIN_MONSTERRING)
|
|
iStopAfterFirst = TRUE;
|
|
|
|
// Get back the saved actual level
|
|
iActualLevel = iSavedLevel;
|
|
// Get Negative properties
|
|
iMaxProps = iPropCount + CI_IP_MAX_NEGATIVE;
|
|
iAnotherProp = Random(100);
|
|
|
|
if (!iStopAfterFirst &&
|
|
!iIncludeMonsterOnly) // if the gear is set to be undroppable monster equipment, skip negative properties
|
|
while (
|
|
(iTries < iMaxProps) &&
|
|
(iAnotherProp <= iPositiveProps * (CI_IP_ADDITIONAL_NEGATIVE_PROPERTY_CHANCE_BASE - (iPropCount - iPositiveProps) * CI_IP_ADDITIONAL_NEGATIVE_PROPERTY_CHANCE_REDUCTION)) &&
|
|
(iPropCount < iMaxProps)
|
|
)
|
|
{
|
|
iTries++;
|
|
strIP = ip_GetProperty(strItem.MainCategory, strItem.SubCategory, strItem.BaseItem, iActualLevel, CI_IP_TYPE_NEGATIVE, iIncludeMonsterOnly);
|
|
if (strIP.PropID == CI_IP_Invalid)
|
|
{
|
|
//SendMessageToAllDMs("Error getting negative property for: " + GetName(oItem) + "\nLevel: " + IntToString(iActualLevel));
|
|
continue;
|
|
}
|
|
// if the chosen property is already on the item, try again
|
|
if (GetItemHasItemProperty(oItem, GetItemPropertyType(strIP.IP)))
|
|
{
|
|
//SendMessageToAllDMs("Chosen property already exists... Trying again");
|
|
continue;
|
|
}
|
|
IPSafeAddItemProperty(oItem, strIP.IP, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
|
|
iPropCount++;
|
|
iNegativeProps++;
|
|
|
|
// Store this property on the item as variables
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "ID", strIP.PropID);
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "Var1", strIP.Var1);
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "Var2", strIP.Var2);
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "Var3", strIP.Var3);
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "Lvl", iActualLevel);
|
|
|
|
iAnotherProp = Random(100);
|
|
iActualLevel -= Random(CI_IP_ADDITIONAL_NEGATIVE_PROPERTY_LEVEL_MODIFIER_RANDOM) + CI_IP_ADDITIONAL_NEGATIVE_PROPERTY_LEVEL_MODIFIER_BASE;
|
|
if (iActualLevel < 1)
|
|
iActualLevel = 1;
|
|
}
|
|
|
|
// Get back the saved actual level
|
|
iActualLevel = iSavedLevel;
|
|
// Get Restrictive properties
|
|
iMaxProps = iPropCount + CI_IP_MAX_RESTRICTIVE;
|
|
iAnotherProp = Random(100) - iAddedRestrictiveChance;
|
|
|
|
if (!iStopAfterFirst &&
|
|
!iIncludeMonsterOnly) // if the gear is set to be undroppable monster equipment, skip restrictive properties
|
|
while (
|
|
(iTries < iMaxProps) &&
|
|
(iAnotherProp <= iPositiveProps * CI_IP_CHANCE_RESTRICTIVE ) && (iPropCount < iMaxProps)
|
|
)
|
|
{
|
|
iTries++;
|
|
strIP = ip_GetProperty(strItem.MainCategory, strItem.SubCategory, strItem.BaseItem, iActualLevel, CI_IP_TYPE_RESTRICTIVE, iIncludeMonsterOnly);
|
|
if (strIP.PropID == CI_IP_Invalid)
|
|
{
|
|
//SendMessageToAllDMs("Error getting restrictive property for: " + GetName(oItem) + "\nLevel: " + IntToString(iActualLevel));
|
|
continue;
|
|
}
|
|
// if the chosen property is already on the item, try again
|
|
if (GetItemHasItemProperty(oItem, GetItemPropertyType(strIP.IP)))
|
|
{
|
|
//SendMessageToAllDMs("Chosen property already exists... Trying again");
|
|
continue;
|
|
}
|
|
IPSafeAddItemProperty(oItem, strIP.IP, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING);
|
|
iPropCount++;
|
|
iRestrictiveProps++;
|
|
|
|
// Store this property on the item as variables
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "ID", strIP.PropID);
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "Var1", strIP.Var1);
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "Var2", strIP.Var2);
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "Var3", strIP.Var3);
|
|
SetLocalInt(oItem, "Property" + IntToString(iPropCount) + "Lvl", iActualLevel);
|
|
|
|
iAnotherProp = Random(100);
|
|
iActualLevel -= Random(CI_IP_ADDITIONAL_RESTRICTIVE_PROPERTY_LEVEL_MODIFIER_RANDOM) + CI_IP_ADDITIONAL_RESTRICTIVE_PROPERTY_LEVEL_MODIFIER_BASE;
|
|
if (iActualLevel < 1)
|
|
iActualLevel = 1;
|
|
}
|
|
|
|
// EVALUATE WHAT WE ADDED
|
|
if (iNameItem)
|
|
ip_EvaluateItem(oItem, iPositiveProps, iNegativeProps, iRestrictiveProps, iPositivePropsWithinRareDeviation, iPositivePropsWithinEpicDeviation);
|
|
|
|
/*
|
|
// DEBUG Stuff
|
|
itemproperty ipProperty = GetFirstItemProperty(oItem);
|
|
int iType;
|
|
int iSubType;
|
|
int iParam1;
|
|
int iParam1Value;
|
|
string sItemInfo = "Info for " + GetName(oItem) + " (Level " + IntToString(iActualLevel) + "):\n";
|
|
while (GetIsItemPropertyValid(ipProperty))
|
|
{
|
|
iType = GetItemPropertyType(ipProperty);
|
|
iSubType = GetItemPropertySubType(ipProperty);
|
|
iParam1 = GetItemPropertyParam1(ipProperty);
|
|
iParam1Value = GetItemPropertyParam1Value(ipProperty);
|
|
sItemInfo += "Type: " + IntToString(iType) + " (" + Get2DAString("itempropdef", "Label", iType) + ")\nSubType: " + IntToString(iSubType) + " (" + Get2DAString(Get2DAString("itempropdef", "SubTypeResRef", iType), "Label", iSubType) + ")\nParam1: " + IntToString(iParam1) + " | Value: " + IntToString(iParam1Value) + ".\n";
|
|
ipProperty = GetNextItemProperty(oItem);
|
|
}
|
|
SendMessageToAllDMs(sItemInfo);
|
|
*/
|
|
|
|
// Save Version and original iLevel on Item
|
|
SetLocalInt(oItem, CS_IP_VAR_CREATION_VERSION, CI_IP_VERSION);
|
|
SetLocalInt(oItem, CS_IP_VAR_CREATION_LEVEL, iSavedLevel);
|
|
|
|
// Set Identified Flag
|
|
SetIdentified(oItem, iIdentified);
|
|
}
|
|
|
|
struct STRUCT_IP_PropertyDetails ip_GetSpecificProperty(int iBaseItem, int iProperty, int iVar1 = 0, int iVar2 = 0, int iVar3 = 0)
|
|
{
|
|
itemproperty ipResult;
|
|
struct STRUCT_IP_PropertyDetails strResult;
|
|
int iRandomizer;
|
|
int iHelper;
|
|
int iHelperI;
|
|
switch (iProperty)
|
|
{
|
|
// Ability Bonus
|
|
// For Ability Bonus, the Ability is randomized, the strength of the boost
|
|
// is set by iVar1
|
|
case CI_IP_AbilityBonus:
|
|
iHelper = ip_GetRandomAbility(iBaseItem, FALSE);
|
|
ipResult = ItemPropertyAbilityBonus(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Armor Class Bonus
|
|
// Here, the AC Bonus is set by iVar1
|
|
case CI_IP_ACBonus:
|
|
ipResult = ItemPropertyACBonus(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Armor Bonus vs. Specific Alignment
|
|
// The alignment group is randomized, the strenght is set by iVar1
|
|
// Value "All Alignments" Excluded in this one
|
|
case CI_IP_ACBonusVsAlign:
|
|
iHelper = ip_GetRandomAlignmentGroup(FALSE);
|
|
ipResult = ItemPropertyACBonusVsAlign(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Armor Bonus vs. Specific Alignment
|
|
// The alignment group is randomized, the strenght is set by iVar1
|
|
// Value "All Alignments" Included in this one
|
|
/*case CI_IP_ACBonusVsAlignAllIncluded:
|
|
iHelper = ip_GetRandomAlignmentGroup(TRUE);
|
|
ipResult = ItemPropertyACBonusVsAlign(iHelper, iVar1);
|
|
break;*/
|
|
|
|
// Armor Bonus vs. Damage Type
|
|
// Damage Type is randomized, strength is set by iVar1
|
|
case CI_IP_ACBonusVsDmgType:
|
|
iHelper = ip_GetRandomDamageType(0);
|
|
ipResult = ItemPropertyACBonusVsDmgType(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Armor Bonus vs. Race
|
|
// Race is randomized, strength is set by iVar1
|
|
case CI_IP_ACBonusVsRace:
|
|
iHelper = ip_GetRandomRacialType();
|
|
ipResult = ItemPropertyACBonusVsRace(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Armor Bonus vs. Specific Alignment
|
|
// Alignment is randomized, strength set by iVar1
|
|
case CI_IP_ACBonusVsSAlign:
|
|
iHelper = ip_GetRandomSpecificAlignment();
|
|
ipResult = ItemPropertyACBonusVsSAlign(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Arcane Spell Failure
|
|
// iVar1 must hold IP_CONST_ARCANE_SPELL_FAILURE_*
|
|
case CI_IP_ArcaneSpellFailure:
|
|
ipResult = ItemPropertyArcaneSpellFailure(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Attack Bonus
|
|
// iVar1 holds the strength
|
|
case CI_IP_AttackBonus:
|
|
ipResult = ItemPropertyAttackBonus(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
case CI_IP_AttackBonusVsAlign:
|
|
iHelper = ip_GetRandomAlignmentGroup(FALSE);
|
|
ipResult = ItemPropertyAttackBonusVsAlign(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
/*case CI_IP_AttackBonusVsAlignAllIncluded:
|
|
iHelper = ip_GetRandomAlignmentGroup(TRUE);
|
|
ipResult = ItemPropertyAttackBonusVsAlign(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;*/
|
|
|
|
case CI_IP_AttackBonusVsRace:
|
|
iHelper = ip_GetRandomRacialType();
|
|
ipResult = ItemPropertyAttackBonusVsRace(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
case CI_IP_AttackBonusVsSAlign:
|
|
iHelper = ip_GetRandomSpecificAlignment();
|
|
ipResult = ItemPropertyAttackBonusVsSAlign(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
case CI_IP_AttackPenalty:
|
|
ipResult = ItemPropertyAttackPenalty(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Bonus Feat
|
|
// Entirely Random Feat is selected
|
|
case CI_IP_BonusFeat:
|
|
iHelper = ip_GetRandomBonusFeat();
|
|
ipResult = ItemPropertyBonusFeat(iHelper);
|
|
strResult.Var1 = iHelper;
|
|
break;
|
|
|
|
// Bonus Spell Level
|
|
// The Casting Class is randomized, iVar1 holds the spell level
|
|
case CI_IP_BonusLevelSpell:
|
|
iHelper = ip_GetRandomClass(TRUE);
|
|
ipResult = ItemPropertyBonusLevelSpell(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Bonus Saving Throw
|
|
// Save-Type is random, iVar1 holds the strength of the bonus
|
|
case CI_IP_BonusSavingThrow:
|
|
iHelper = ip_GetRandomSaveBaseType();
|
|
ipResult = ItemPropertyBonusSavingThrow(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Bonus Saving Throw vs. Specific Effect or Damage Type
|
|
// Effect/Damage Type is randomized, iVar1 holds the amount of bonus
|
|
// Universal Save excluded
|
|
case CI_IP_BonusSavingThrowVsX:
|
|
iHelper = ip_GetRandomSavingThrowVS(FALSE);
|
|
ipResult = ItemPropertyBonusSavingThrowVsX(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Bonus Saving Throw vs. Specific Effect or Damage Type
|
|
// Effect/Damage Type is randomized, iVar1 holds the amount of bonus
|
|
// Universal Save included
|
|
case CI_IP_BonusSavingThrowVsXUniversalIncluded:
|
|
iHelper = ip_GetRandomSavingThrowVS(TRUE);
|
|
ipResult = ItemPropertyBonusSavingThrowVsX(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Spell Resistance
|
|
// iVar1 holds IP_CONST_SPELLRESISTANCEBONUS_*
|
|
case CI_IP_BonusSpellResistance:
|
|
ipResult = ItemPropertyBonusSpellResistance(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Cast Spell (all items except wands/potions
|
|
// iVar1 holds the Caster Level (1-20) of the spell
|
|
// iVar 2 holds IP_CONST_CASTSPELL_NUMUSES_*
|
|
case CI_IP_CastSpell:
|
|
iHelper = ip_GetRandomSpell(iVar1);
|
|
ipResult = ItemPropertyCastSpell(iHelper, iVar2);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar2;
|
|
break;
|
|
|
|
// Cast Spell (Potion)
|
|
// iVar1 holds the Caster Level (0-20) of the spell
|
|
case CI_IP_CastSpellPotion:
|
|
iHelper = ip_GetRandomPotionSpell(iVar1);
|
|
ipResult = ItemPropertyCastSpell(iHelper, IP_CONST_CASTSPELL_NUMUSES_SINGLE_USE);
|
|
strResult.Var1 = iHelper;
|
|
break;
|
|
|
|
// Cast Spell (Wand)
|
|
// iVar1 holds the Caster Level (0-20) of the spell
|
|
// iVar 2 holds IP_CONST_CASTSPELL_NUMUSES_*
|
|
case CI_IP_CastSpellWand:
|
|
iHelper = ip_GetRandomWandSpell(iVar1);
|
|
ipResult = ItemPropertyCastSpell(iHelper, iVar2);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar2;
|
|
break;
|
|
|
|
// Container Reduced Weight
|
|
// iVar1 must hold IP_CONST_CONTAINERWEIGHTRED_*
|
|
case CI_IP_ContainerReducedWeight:
|
|
ipResult = ItemPropertyContainerReducedWeight(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Damage Bonus
|
|
// DamageType is randomized, iVar1 has to be IP_CONST_DAMAGEBONUS_*
|
|
case CI_IP_DamageBonus:
|
|
iHelper = ip_GetRandomDamageType(1);
|
|
ipResult = ItemPropertyDamageBonus(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Damage Bonus vs. Alignment Group
|
|
// Damage Type and Alignment Group are randomized,
|
|
// iVar1 holds IP_CONST_DAMAGEBONUS_*
|
|
case CI_IP_DamageBonusVsAlign:
|
|
iHelper = ip_GetRandomAlignmentGroup(FALSE);
|
|
iHelperI = ip_GetRandomDamageType(1);
|
|
ipResult = ItemPropertyDamageBonusVsAlign(iHelper, iHelperI, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iHelperI;
|
|
strResult.Var3 = iVar1;
|
|
break;
|
|
|
|
// Damage Bonus vs. Alignment Group
|
|
// Damage Type and Alignment Group are randomized,
|
|
// iVar1 holds IP_CONST_DAMAGEBONUS_*
|
|
/*case CI_IP_DamageBonusVsAlignAllIncluded:
|
|
iHelper = ip_GetRandomAlignmentGroup(TRUE);
|
|
iHelperI = ip_GetRandomDamageType(TRUE);
|
|
ipResult = ItemPropertyDamageBonusVsAlign(iHelper, iHelperI, iVar1);
|
|
break;*/
|
|
|
|
// Damage Bonus vs. Race
|
|
// Damage Type and Race are randomized, iVar1 holds IP_CONST_DAMAGEBONUS_*
|
|
case CI_IP_DamageBonusVsRace:
|
|
iHelper = ip_GetRandomRacialType();
|
|
iHelperI = ip_GetRandomDamageType(1);
|
|
ipResult = ItemPropertyDamageBonusVsRace(iHelper, iHelperI, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iHelperI;
|
|
strResult.Var3 = iVar1;
|
|
break;
|
|
|
|
// Damage Bonus vs. Specific Alignment
|
|
// Damage Type and Alignment are randomized,
|
|
// iVar1 holds IP_CONST_DAMAGEBONUS_*
|
|
case CI_IP_DamageBonusVsSAlign:
|
|
iHelper = ip_GetRandomSpecificAlignment();
|
|
iHelperI = ip_GetRandomDamageType(1);
|
|
ipResult = ItemPropertyDamageBonusVsSAlign(iHelper, iHelperI, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iHelperI;
|
|
strResult.Var3 = iVar1;
|
|
break;
|
|
|
|
// Damage Immunity
|
|
// Damage Type is randomized, iVar1 holds IP_CONST_DAMAGEIMMUNITY_*
|
|
case CI_IP_DamageImmunity:
|
|
iHelper = ip_GetRandomDamageType(1);
|
|
ipResult = ItemPropertyDamageImmunity(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Damage Penalty
|
|
// iVar1 = 1 to 5
|
|
case CI_IP_DamagePenalty:
|
|
ipResult = ItemPropertyDamagePenalty(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Damage Reduction
|
|
// iVar1 holds IP_CONST_DAMAGEREDUCTION_*, iVar2 holds IP_CONST_DAMAGESOAK_*
|
|
case CI_IP_DamageReduction:
|
|
ipResult = ItemPropertyDamageReduction(iVar1, iVar2);
|
|
strResult.Var1 = iVar1;
|
|
strResult.Var2 = iVar2;
|
|
break;
|
|
|
|
// Damage Resistance
|
|
// Damage Type is randomized, iVar1 holds IP_CONST_DAMAGERESIST_*
|
|
case CI_IP_DamageResistance:
|
|
iHelper = ip_GetRandomDamageType(2);
|
|
ipResult = ItemPropertyDamageResistance(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Damage Vulnerability
|
|
// Damage Type is randomized, iVar1 holds IP_CONST_DAMAGEVULNERABILITY_*
|
|
case CI_IP_DamageVulnerability:
|
|
iHelper = ip_GetRandomDamageType(2);
|
|
ipResult = ItemPropertyDamageVulnerability(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
case CI_IP_Darkvision:
|
|
ipResult = ItemPropertyDarkvision();
|
|
break;
|
|
|
|
// Decrease Ability
|
|
// Ability is randomized, iVar1 is 1-10
|
|
case CI_IP_DecreaseAbility:
|
|
iHelper = ip_GetRandomAbility(iBaseItem, TRUE);
|
|
ipResult = ItemPropertyDecreaseAbility(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Decrease Armor Class
|
|
// Modifier Type is random, iVar1 holds the strength of the modification
|
|
case CI_IP_DecreaseAC:
|
|
iHelper = ip_GetRandomACModifierType();
|
|
ipResult = ItemPropertyDecreaseAC(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Decrease Skill
|
|
// Skill is randomized, iVar1 holds the strength of the decrease (1-10)
|
|
// The ALLSKILLS skill is included in this one
|
|
case CI_IP_DecreaseSkill:
|
|
iHelper = ip_GetRandomSkill(TRUE);
|
|
ipResult = ItemPropertyDecreaseSkill(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
/* Deactivated
|
|
// Decrease Skill
|
|
// Skill is randomized, iVar1 holds the strength of the decrease (1-10)
|
|
// The ALLSKILLS skill is included in this one
|
|
case CI_IP_DecreaseSkillAllSkillsIncluded:
|
|
iHelper = ip_GetRandomSkill(TRUE);
|
|
ipResult = ItemPropertyDecreaseSkill(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
*/
|
|
|
|
// Enhancement Bonus
|
|
// iVar1 is the Bonus (1-20)
|
|
case CI_IP_EnhancementBonus:
|
|
ipResult = ItemPropertyEnhancementBonus(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Enhancement Bonus vs. Alignment Group
|
|
// Alignment Group is randomized, the bonus is iVar1
|
|
// ALL Alignments not included
|
|
case CI_IP_EnhancementBonusVsAlign:
|
|
iHelper = ip_GetRandomAlignmentGroup(FALSE);
|
|
ipResult = ItemPropertyEnhancementBonusVsAlign(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Enhancement Bonus vs. Alignment Group
|
|
// Alignment Group is randomized, the bonus is iVar1
|
|
// ALL Alignments included
|
|
/*case CI_IP_EnhancementBonusVsAlignAllIncluded:
|
|
iHelper = ip_GetRandomAlignmentGroup(TRUE);
|
|
ipResult = ItemPropertyEnhancementBonusVsAlign(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;*/
|
|
|
|
// Enhancement Bonus vs. Racial Group
|
|
// Racial Group is randomized, the bonus is iVar1
|
|
case CI_IP_EnhancementBonusVsRace:
|
|
iHelper = ip_GetRandomRacialType();
|
|
ipResult = ItemPropertyEnhancementBonusVsRace(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Enhancement Bonus vs. Specific Alignment
|
|
// Alignment randomized, iVar1 is the bonus
|
|
case CI_IP_EnhancementBonusVsSAlign:
|
|
iHelper = ip_GetRandomSpecificAlignment();
|
|
ipResult = ItemPropertyEnhancementBonusVsSAlign(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
/* Deactivated
|
|
// Enhancement Penalty
|
|
// iVar1 = 1-5
|
|
case CI_IP_EnhancementPenalty:
|
|
ipResult = ItemPropertyEnhancementPenalty(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
*/
|
|
|
|
// Extra Melee Damage Type
|
|
// All randomized here
|
|
case CI_IP_ExtraMeleeDamageType:
|
|
iHelper = ip_GetRandomExtraDamageType();
|
|
ipResult = ItemPropertyExtraMeleeDamageType(iHelper);
|
|
strResult.Var1 = iHelper;
|
|
break;
|
|
|
|
// Extra Ranged Damage Type
|
|
// All randomized here
|
|
case CI_IP_ExtraRangeDamageType:
|
|
iHelper = ip_GetRandomExtraDamageType();
|
|
ipResult = ItemPropertyExtraRangeDamageType(iHelper);
|
|
strResult.Var1 = iHelper;
|
|
break;
|
|
|
|
/* Non-Existant
|
|
// Free Action
|
|
case CI_IP_FreeAction:
|
|
ipResult = ItemPropertyFreeAction();
|
|
break;
|
|
*/
|
|
|
|
// Haste
|
|
case CI_IP_Haste:
|
|
ipResult = ItemPropertyHaste();
|
|
break;
|
|
|
|
// Healers Kit
|
|
// iVar 1 holds the strength (1-12)
|
|
case CI_IP_HealersKit:
|
|
ipResult = ItemPropertyHealersKit(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Holy Avenger
|
|
case CI_IP_HolyAvenger:
|
|
ipResult = ItemPropertyHolyAvenger();
|
|
break;
|
|
|
|
// Miscellaneous Immunity
|
|
// iVar1 holds IP_CONST_IMMUNITYMISC_*
|
|
case CI_IP_ImmunityMisc:
|
|
ipResult = ItemPropertyImmunityMisc(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Immunity to Spell Level
|
|
// iVar1 holds the spell level
|
|
case CI_IP_ImmunityToSpellLevel:
|
|
ipResult = ItemPropertyImmunityToSpellLevel(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Improved Evasion
|
|
case CI_IP_ImprovedEvasion:
|
|
ipResult = ItemPropertyImprovedEvasion();
|
|
break;
|
|
|
|
// Keen
|
|
case CI_IP_Keen:
|
|
ipResult = ItemPropertyKeen();
|
|
break;
|
|
|
|
// Light
|
|
// iVar1 holds the intensity -> IP_CONST_LIGHTBRIGHTNESS_*
|
|
case CI_IP_Light:
|
|
iHelper = ip_GetRandomLightColor();
|
|
ipResult = ItemPropertyLight(iVar1, iHelper);
|
|
strResult.Var1 = iVar1;
|
|
strResult.Var2 = iHelper;
|
|
break;
|
|
|
|
// Limit use By Align
|
|
case CI_IP_LimitUseByAlign:
|
|
iHelper = ip_GetRandomAlignmentGroup(FALSE);
|
|
ipResult = ItemPropertyLimitUseByAlign(iHelper);
|
|
strResult.Var1 = iHelper;
|
|
break;
|
|
|
|
// Limit Use By Class
|
|
case CI_IP_LimitUseByClass:
|
|
iHelper = ip_GetRandomClass(FALSE);
|
|
ipResult = ItemPropertyLimitUseByClass(iHelper);
|
|
strResult.Var1 = iHelper;
|
|
break;
|
|
|
|
// Limit Use By Race
|
|
case CI_IP_LimitUseByRace:
|
|
iHelper = ip_GetRandomRacialType(TRUE);
|
|
ipResult = ItemPropertyLimitUseByRace(iHelper);
|
|
strResult.Var1 = iHelper;
|
|
break;
|
|
|
|
// Limit Use by Specific Alignment
|
|
case CI_IP_LimitUseBySAlign:
|
|
iHelper = ip_GetRandomSpecificAlignment();
|
|
ipResult = ItemPropertyLimitUseBySAlign(iHelper);
|
|
strResult.Var1 = iHelper;
|
|
break;
|
|
|
|
// Massive Damage
|
|
// iVar1 holds IP_CONST_DAMAGEBONUS_*
|
|
case CI_IP_MassiveCritical:
|
|
ipResult = ItemPropertyMassiveCritical(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Mighty
|
|
// iVar1 = 1-20
|
|
case CI_IP_MaxRangeStrengthMod:
|
|
ipResult = ItemPropertyMaxRangeStrengthMod(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Monster Damage only works on Monster Items
|
|
// Therefor, this property is not included
|
|
case CI_IP_MonsterDamage:
|
|
//ipResult = ;
|
|
break;
|
|
|
|
// No Damage
|
|
case CI_IP_NoDamage:
|
|
ipResult = ItemPropertyNoDamage();
|
|
break;
|
|
|
|
// On Hit: Cast Spell
|
|
// Not done yet
|
|
case CI_IP_OnHitCastSpell:
|
|
//ipResult = ;
|
|
break;
|
|
|
|
// On Hit Properties
|
|
// iVar1 holds IP_CONST_ONHIT_*
|
|
// iVar2 holds IP_CONST_ONHIT_SAVEDC_*
|
|
// iVar3 holds the Special Variable Duration (all other special variables
|
|
// are randomized)
|
|
case CI_IP_OnHitProps:
|
|
switch (iVar1)
|
|
{
|
|
case IP_CONST_ONHIT_ABILITYDRAIN: iVar3 = ip_GetRandomAbility(iBaseItem, TRUE); break;
|
|
case IP_CONST_ONHIT_DISEASE: iVar3 = ip_GetRandomDisease(); break;
|
|
case IP_CONST_ONHIT_ITEMPOISON: iVar3 = ip_GetRandomItemPoison(); break;
|
|
case IP_CONST_ONHIT_SLAYRACE: iVar3 = ip_GetRandomRacialType(); break;
|
|
case IP_CONST_ONHIT_SLAYALIGNMENTGROUP: iVar3 = ip_GetRandomAlignmentGroup(); break;
|
|
case IP_CONST_ONHIT_SLAYALIGNMENT: iVar3 = ip_GetRandomSpecificAlignment(); break;
|
|
}
|
|
ipResult = ItemPropertyOnHitProps(iVar1, iVar2, iVar3);
|
|
strResult.Var1 = iVar1;
|
|
strResult.Var2 = iVar2;
|
|
strResult.Var3 = iVar3;
|
|
break;
|
|
|
|
// Unused
|
|
case CI_IP_OnMonsterHitProperties:
|
|
//ipResult = ;
|
|
break;
|
|
|
|
// Reduced Saving Throw
|
|
// SaveBase Type is randomized, iVar1 = 1-20
|
|
case CI_IP_ReducedSavingThrow:
|
|
iHelper = ip_GetRandomSaveBaseType();
|
|
ipResult = ItemPropertyReducedSavingThrow(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// Reduced Saving Throw vs. Specific Effect/Damage
|
|
// Effect/Damage is randomized, iVar1 holds the value
|
|
// Universal is included
|
|
case CI_IP_ReducedSavingThrowVsX:
|
|
iHelper = ip_GetRandomSavingThrowVS(TRUE);
|
|
ipResult = ItemPropertyReducedSavingThrowVsX(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
/* Deactivated
|
|
// Reduced Saving Throw vs. Specific Effect/Damage
|
|
// Effect/Damage is randomized, iVar1 holds the value
|
|
// Universal included
|
|
case CI_IP_ReducedSavingThrowVsXUniversalIncluded:
|
|
iHelper = ip_GetRandomSavingThrowVS(TRUE);
|
|
ipResult = ItemPropertyReducedSavingThrowVsX(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
*/
|
|
|
|
// Regeneration
|
|
// iVar1 holds the amount of regeneration (1-20)
|
|
case CI_IP_Regeneration:
|
|
ipResult = ItemPropertyRegeneration(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Skill Bonus
|
|
// Skill is randomized, iVar1 holds the boost (1-50)
|
|
// "All Skills" not included
|
|
case CI_IP_SkillBonus:
|
|
iHelper = ip_GetRandomSkill(FALSE);
|
|
ipResult = ItemPropertySkillBonus(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
/* Deactivated
|
|
// Skill Bonus
|
|
// Skill is randomized, iVar1 holds the boost (1-50)
|
|
// "All Skills" included
|
|
case CI_IP_SkillBonusAllIncluded:
|
|
iHelper = ip_GetRandomSkill(TRUE);
|
|
ipResult = ItemPropertySkillBonus(iHelper, iVar1);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
*/
|
|
|
|
// Special Walk (Zombie)
|
|
case CI_IP_SpecialWalk:
|
|
ipResult = ItemPropertySpecialWalk();
|
|
break;
|
|
|
|
// Immunity vs. SpellSchool
|
|
case CI_IP_SpellImmunitySchool:
|
|
iHelper = ip_GetRandomSpellSchool();
|
|
ipResult = ItemPropertySpellImmunitySchool(iHelper);
|
|
strResult.Var1 = iHelper;
|
|
break;
|
|
|
|
// unused
|
|
case CI_IP_SpellImmunitySpecific:
|
|
//ipResult = ;
|
|
break;
|
|
|
|
// Thieves Tools
|
|
// iVar1 holds the bonus (1-12)
|
|
case CI_IP_ThievesTools:
|
|
ipResult = ItemPropertyThievesTools(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Trap
|
|
// Trap Type is randomized, iVar1 holds IP_CONST_TRAPSTRENGTH_*
|
|
case CI_IP_Trap:
|
|
iHelper = ip_GetRandomTrapType();
|
|
ipResult = ItemPropertyTrap(iVar1, iHelper);
|
|
strResult.Var1 = iHelper;
|
|
strResult.Var2 = iVar1;
|
|
break;
|
|
|
|
// True Seeing
|
|
case CI_IP_TrueSeeing:
|
|
ipResult = ItemPropertyTrueSeeing();
|
|
break;
|
|
|
|
// Turn Resistance
|
|
// iVar1 holds the strength of the resistance (1-50)
|
|
case CI_IP_TurnResistance:
|
|
ipResult = ItemPropertyTurnResistance(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Unlimited Ammo
|
|
// iVar1 holds IP_CONST_UNLIMITEDAMMO_*
|
|
case CI_IP_UnlimitedAmmo:
|
|
ipResult = ItemPropertyUnlimitedAmmo(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Vampiric Regeneration
|
|
// iVar1 holds the amount (1-20)
|
|
case CI_IP_VampiricRegeneration:
|
|
ipResult = ItemPropertyVampiricRegeneration(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Adds a random Visual Effect to melee weapons
|
|
case CI_IP_VisualEffect:
|
|
iHelper = ip_GetRandomItemVisualEffect();
|
|
ipResult = ItemPropertyVisualEffect(iHelper);
|
|
strResult.Var1 = iHelper;
|
|
break;
|
|
|
|
// Weight Increase
|
|
// iVar1 holds IP_CONST_WEIGHTINCREASE_*
|
|
case CI_IP_WeightIncrease:
|
|
ipResult = ItemPropertyWeightIncrease(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
|
|
// Weight Reduction
|
|
// iVar1 holds IP_CONST_REDUCEDWEIGHT_*
|
|
case CI_IP_WeightReduction:
|
|
ipResult = ItemPropertyWeightReduction(iVar1);
|
|
strResult.Var1 = iVar1;
|
|
break;
|
|
}
|
|
|
|
strResult.IP = ipResult;
|
|
return (strResult);
|
|
}
|