Here is the beast, it ran fine all day in Hala, no strange drop.
Just a few comments.
I put the area instead of the server name in the DB tracking code. We only have one server in Hala, and the area is a valuable information to find a buggy drop.
There is a double logging system. First, each drop (yes *each*) is logged in the DB, table item_tracking, I havent touched its structure. Second, each drop is logged in the server log file, with a bit more info, and infos in case of a buggy read in the DB.
To switch off server logs, one needs to comment all the WriteStamped... lines. To switch off DB logs, one needs to comment the call to the addTrackingItem function call.
Here is the SQL request that must be launched to get the drops with the items names and values.
Code: Select all
#include "aps_include"
//::///////////////////////////////////////////////
//:: NW_O2_CONINCLUDE.nss
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
This include file handles the random treasure
distribution for treasure from creatures and containers
[ ] Documented
*/
//:://////////////////////////////////////////////
//:: Created By: Brent, Andrew
//:: Created On: November - May
//:://////////////////////////////////////////////
// :: MODS
// April 23 2002: Removed animal parts. They were silly.
// May 6 2002: Added Undead to the EXCLUSION treasure list (they drop nothing now)
// - redistributed treasure (to lessen amoun t of armor and increase 'class specific treasure'
// - Rangers with heavy armor prof. will be treated as Fighters else as Barbarians
// - Gave wizards, druids and monk their own function
// MAY 29 2002: Removed the heal potion from treasure
// Moved nymph cloak +4 to treasure bracket 6
// Added Monk Enhancement items to random treasure
//:://////////////////////////////////////////////
//:: Modified By: Colon, Adam (silk@blackdagger.com)
//:: Modified On: February 2003
//:://////////////////////////////////////////////
// :: MODS
// February 20, 2003: Rewrote all Treasure Generators to use the Treasure Tables in the External Database using NWNX
// * ---------
// * CONSTANTS
// * ---------
// * tweaking constants
// * SIX LEVEL RANGES
int RANGE_1_MIN = 0;
int RANGE_1_MAX = 5;
int RANGE_2_MIN = 6;
int RANGE_2_MAX = 8;
int RANGE_3_MIN = 9;
int RANGE_3_MAX = 10;
int RANGE_4_MIN = 11;
int RANGE_4_MAX = 13;
int RANGE_5_MIN = 14;
int RANGE_5_MAX = 16;
int RANGE_6_MIN = 17;
int RANGE_6_MAX = 100;
// * NUMBER OF ITEMS APPEARING
int NUMBER_LOW_ONE = 100; int NUMBER_MED_ONE = 60; int NUMBER_HIGH_ONE = 40; int NUMBER_BOSS_ONE = 100;
int NUMBER_LOW_TWO = 0; int NUMBER_MED_TWO = 30; int NUMBER_HIGH_TWO = 40; int NUMBER_BOSS_TWO = 0;
int NUMBER_LOW_THREE = 0; int NUMBER_MED_THREE = 10; int NUMBER_HIGH_THREE = 20; int NUMBER_BOSS_THREE = 0;
int NUMBER_BOOK_ONE = 75;
int NUMBER_BOOK_TWO = 20;
int NUMBER_BOOK_THREE = 5;
// * AMOUNT OF GOLD BY VALUE
float LOW_MOD_GOLD = GetLocalFloat(GetModule(), "LowModGold"); // 5
float MEDIUM_MOD_GOLD = GetLocalFloat(GetModule(), "MedModGold"); // 8
float HIGH_MOD_GOLD = GetLocalFloat(GetModule(), "HiModGold"); // 10
// * limites pour les categories de mobs
int HD_BOSS = 30 ;
int HD_HIGH = 20 ;
int HD_MEDIUM = 10 ;
// * FREQUENCY OF ITEM TYPE APPEARING BY TREASURE TYPE
int LOW_PROB_BOOK = 1; int MEDIUM_PROB_BOOK = 1; int HIGH_PROB_BOOK = 1;
int LOW_PROB_ANIMAL = 0; int MEDIUM_PROB_ANIMAL = 0; int HIGH_PROB_ANIMAL = 0;
int LOW_PROB_JUNK = 0; int MEDIUM_PROB_JUNK = 0; int HIGH_PROB_JUNK = 0;
int LOW_PROB_GOLD = 45; int MEDIUM_PROB_GOLD = 35; int HIGH_PROB_GOLD = 15;
int LOW_PROB_GEM = 19; int MEDIUM_PROB_GEM = 25; int HIGH_PROB_GEM = 36;
int LOW_PROB_JEWEL = 9; int MEDIUM_PROB_JEWEL = 6; int HIGH_PROB_JEWEL = 15;
int LOW_PROB_ARCANE = 3; int MEDIUM_PROB_ARCANE = 3; int HIGH_PROB_ARCANE = 3;
int LOW_PROB_DIVINE = 3; int MEDIUM_PROB_DIVINE = 3; int HIGH_PROB_DIVINE = 3;
int LOW_PROB_AMMO = 10; int MEDIUM_PROB_AMMO = 5; int HIGH_PROB_AMMO = 3;
int LOW_PROB_KIT = 5; int MEDIUM_PROB_KIT = 5; int HIGH_PROB_KIT = 5;
int LOW_PROB_POTION = 12; int MEDIUM_PROB_POTION = 10; int HIGH_PROB_POTION = 9;
int LOW_PROB_TABLE2 = 2; int MEDIUM_PROB_TABLE2 = 5; int HIGH_PROB_TABLE2 = 10;
// * readability constants
int TREASURE_LOW = 1;
int TREASURE_MEDIUM = 2;
int TREASURE_HIGH = 3;
int TREASURE_BOSS = 4;
int TREASURE_BOOK = 5;
// * JUMP_LEVEL is used in a Specific item function
// * in the case where a generic item is called for within that function
// * it will create a generic item by adding JUMP_LEVEL to the character's
// * hit die for the purposes of the treasure evaluation.
// * May 2002: Lowered JUMP_LEVEL from 3 to 2
int JUMP_LEVEL = 0;
//* Declarations
void CreateGold(object oTarget, object oAdventurer, int nTreasureType, int nModifier = 0);
void CreateGenericExotic(object oTarget, object oAdventurer, int nModifier = 0);
void CreateGenericMonkWeapon(object oTarget, object oAdventurer, int nModifier = 0);
void CreateSpecificMonkWeapon(object oTarget, object oAdventurer, int nModifier = 0);
void CreateGenericDruidWeapon(object oTarget, object oAdventurer, int nModifier = 0);
void CreateSpecificDruidWeapon(object oTarget, object oAdventurer, int nModifier = 0);
void CreateGenericWizardWeapon(object oTarget, object oAdventurer, int nModifier = 0);
void CreateSpecificWizardWeapon(object oTarget, object oAdventurer, int nModifier = 0);
int nDetermineClassToUse(object oCharacter);
// *
// * IMPLEMENTATION
// *
// Add item to Database
void addTrackingItem(string sAccount, string sName, string sServer, string sHitDice, string sResRef){
string sSQL;
sAccount = SQLEncodeSpecialChars(sAccount) ;
sName = SQLEncodeSpecialChars(sName) ;
sSQL = "INSERT INTO item_tracking (player,charname,server,hd,resref) VALUES ";
sSQL += "('" + sAccount + "'";
sSQL += ",'" + sName + "'";
sSQL += ",'" + sServer + "'";
sSQL += "," + sHitDice;
sSQL += ",'" + sResRef + "')";
WriteTimestampedLogEntry("Item tracking : " + sSQL) ;
SQLExecDirect(sSQL);
}
//* made this function to help with debugging
void dbCreateItemOnObject(string sItemTemplate, object oPlayer, object oTarget = OBJECT_SELF, int nStackSize = 1) {
if (sItemTemplate == "")
WriteTimestampedLogEntry("Probleme : blank item passed into dbCreateItemOnObject.") ;
if (nStackSize == 1) {
// * checks to see if this is an arrow or throwing item and if it is
// * it creates more
string sRoot = GetSubString(sItemTemplate, 0, 6);
if (GetStringLowerCase(sRoot) == "nw_wam" || GetStringLowerCase(sRoot) == "nw_wth")
nStackSize = Random(30) + 1;
}
object oItem = CreateItemOnObject(sItemTemplate, oTarget, nStackSize);
// Item Tracking Code
if (GetIsPC(oPlayer)) {
string sAccount = GetPCPlayerName(oPlayer);
string sName = GetName(oPlayer);
string sHitDice = IntToString(GetHitDice(oPlayer));
string sArea = GetName(GetArea(oPlayer)) ;
WriteTimestampedLogEntry("Treasure Drop, " + sName + "[" + sAccount + "] in " + sArea + " : " + sItemTemplate) ;
addTrackingItem(sAccount, sName, sArea, sHitDice, sItemTemplate) ;
} else {
string sName = GetName(oPlayer);
string sArea = GetName(GetArea(oPlayer)) ;
WriteTimestampedLogEntry("Treasure Drop, " + sName + " in " + sArea + " : " + sItemTemplate) ;
addTrackingItem("", sName, sArea, "", sItemTemplate) ;
}
}
// *
// * GET FUNCTIONS
// *
// * Returns the object that either last opened the container or destroyed it
object GetLastOpener() {
if (GetIsObjectValid(GetLastOpenedBy()) == TRUE)
return GetLastOpenedBy();
else if (GetIsObjectValid(GetLastKiller()) == TRUE)
return GetLastKiller();
return OBJECT_INVALID;
}
//::///////////////////////////////////////////////
//:: GetRange
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
Returns true if nHD matches the correct
level range for the indicated nCategory.
(i.e., First to Fourth level characters
are considered Range1)
*/
//:://////////////////////////////////////////////
//:: Created By: Brent
//:: Created On:
//:://////////////////////////////////////////////
int GetRange(int nCategory, int nHD) {
int nMin = 0; int nMax = 0;
switch (nCategory) {
case 6: nMin = RANGE_6_MIN; nMax = RANGE_6_MAX; break;
case 5: nMin = RANGE_5_MIN; nMax = RANGE_5_MAX; break;
case 4: nMin = RANGE_4_MIN; nMax = RANGE_4_MAX; break;
case 3: nMin = RANGE_3_MIN; nMax = RANGE_3_MAX; break;
case 2: nMin = RANGE_2_MIN; nMax = RANGE_2_MAX; break;
case 1: nMin = RANGE_1_MIN; nMax = RANGE_1_MAX;
}
return nHD >= nMin && nHD <= nMax ;
}
//::///////////////////////////////////////////////
//:: GetNumberOfItems
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
Returns the number of items to create.
*/
//:://////////////////////////////////////////////
//:: Created By: Brent
//:: Created On:
//:://////////////////////////////////////////////
int GetNumberOfItems(int nTreasureType) {
int nRandom = d100();
if (nTreasureType == TREASURE_LOW) {
if (nRandom <= NUMBER_LOW_THREE) return 3 ;
else if (nRandom <= NUMBER_LOW_TWO) return 2 ;
else return 1 ;
} else if (nTreasureType == TREASURE_MEDIUM) {
if (nRandom <= NUMBER_MED_THREE) return 3 ;
else if (nRandom <= NUMBER_MED_TWO) return 2 ;
else return 1 ;
} else if (nTreasureType == TREASURE_HIGH) {
if (nRandom <= NUMBER_HIGH_THREE) return 3 ;
else if (nRandom <= NUMBER_HIGH_TWO) return 2 ;
else return 1 ;
} else if (nTreasureType == TREASURE_BOSS) {
if (nRandom <= NUMBER_BOSS_THREE) return 3 ;
else if (nRandom <= NUMBER_BOSS_TWO) return 2 ;
else return 1 ;
} else if (nTreasureType == TREASURE_BOOK) {
if (nRandom <= NUMBER_BOOK_THREE) return 3 ;
else if (nRandom <= NUMBER_BOOK_TWO) return 2 ;
else return 1 ;
}
return 1 ;
}
// *
// * TREASURE GENERATION FUNCTIONS
// *
// * ---------
// * Start Code Additions by Adam Colon
// * ---------
string TREASURE_DBNAME = "treasure";
int TREASURE_VALUE_MAX_LOW = 1700;
int TREASURE_VALUE_MAX_MEDIUM = 8000;
int TREASURE_VALUE_MAX_HIGH = 12500;
int TREASURE_VALUE_MAX_BOSS = 23500;
string GetRandomFromTreasureTable(string sWhere) {
string sSQL ;
string sRes = "" ;
sWhere += " AND dropable=1";
string sSQLCount = "SELECT count(*) FROM " + TREASURE_DBNAME + " " + sWhere + " ;" ;
SQLExecDirect(sSQLCount);
int rc = SQLFirstRow();
if (rc == SQL_SUCCESS) {
int iCount = StringToInt(SQLGetData(1));
if (iCount > 0){
int iRandom = Random(iCount);
sSQL = "SELECT resref FROM " + TREASURE_DBNAME + " " +
sWhere + " order by name LIMIT " + IntToString(iRandom) + ", 1 ;" ;
SQLExecDirect(sSQL);
rc = SQLFirstRow();
if (rc == SQL_SUCCESS) {
sRes = SQLGetData(1) ;
}
}
}
if (sRes == "") {
WriteTimestampedLogEntry("Probleme lecture table de loot") ;
WriteTimestampedLogEntry(" sSQLCount = " + sSQLCount) ;
WriteTimestampedLogEntry(" sSQL = " + sSQL) ;
sRes = "NW_IT_GOLD001" ;
}
return sRes;
}
// Determine Treasure modifier, valued doubled on 2/23/03
int GetTreasureModifier(int nHD) {
if (nHD >= RANGE_6_MIN) return 12 ;
if (nHD >= RANGE_5_MIN) return 10 ;
if (nHD >= RANGE_4_MIN) return 8 ;
if (nHD >= RANGE_3_MIN) return 6 ;
if (nHD >= RANGE_2_MIN) return 4 ;
return 2 ;
}
int GetTreasureMaxValueByHD(object oTarget) {
int nHD = GetHitDice(oTarget);
if (nHD >= HD_BOSS) return TREASURE_VALUE_MAX_BOSS ;
if (nHD >= HD_HIGH) return TREASURE_VALUE_MAX_HIGH ;
if (nHD >= HD_MEDIUM) return TREASURE_VALUE_MAX_MEDIUM ;
return TREASURE_VALUE_MAX_LOW ;
}
void CreateItemFinal(object oTarget, object oAdventurer, int nModifier, string sWhere) {
int iMaxValue = GetTreasureMaxValueByHD(oTarget) ;
sWhere += IntToString(iMaxValue) ;
string sRes = GetRandomFromTreasureTable(sWhere);
dbCreateItemOnObject(sRes, oAdventurer, oTarget);
}
void CreateItemByClass(object oTarget, object oAdventurer, int nModifier, string sClass) {
string sWhere = "WHERE class LIKE '%" + sClass + "%' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
// * ---------
// * End Code Additions by Adam Colon
// * ---------
// *
// * Non-Scaling Treasure
// *
void CreateBook(object oTarget, object oPlayer) {
string sWhere = "WHERE type='BOOK' ";
string sRes = GetRandomFromTreasureTable(sWhere);
dbCreateItemOnObject(sRes, oPlayer, oTarget);
}
void CreateAnimalPart(object oTarget, object oPlayer) {
string sWhere = "WHERE type='ANIMAL_PART' ";
string sRes = GetRandomFromTreasureTable(sWhere);
dbCreateItemOnObject(sRes, oPlayer, oTarget) ;
}
void CreateJunk(object oTarget, object oPlayer) {
string sWhere = "WHERE type='MISCELLANEOUS' ";
string sRes = GetRandomFromTreasureTable(sWhere);
dbCreateItemOnObject(sRes, oPlayer, oTarget);
}
// *
// * Scaling Treasure
// *
void CreateGold(object oTarget, object oAdventurer, int nTreasureType, int nModifier = 0) {
int nHD = GetHitDice(oAdventurer) + nModifier;
int iTreasureModifier = GetTreasureModifier(nHD);
int nAmount = d20(iTreasureModifier);
float nMod = LOW_MOD_GOLD ;
if (nTreasureType == TREASURE_MEDIUM)
nMod = MEDIUM_MOD_GOLD;
else if (nTreasureType == TREASURE_HIGH)
nMod = HIGH_MOD_GOLD;
// * always at least 1gp is created
nAmount = FloatToInt(nAmount * nMod) ;
nAmount = (nAmount > 0) ? nAmount : 1 ;
dbCreateItemOnObject("NW_IT_GOLD001", oAdventurer, oTarget, nAmount);
}
void CreateGem(object oTarget, object oAdventurer, int nTreasureType, int nModifier = 0) {
string sWhere = "WHERE type = 'GEM' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateJewel(object oTarget, object oAdventurer, int nTreasureType, int nModifier = 0) {
string sWhere = "WHERE type = 'JEWEL' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
// * returns the valid upper limit for any arcane spell scroll
int TrimLevel(int nScroll, int nLevel) {
int nMax = 5;
switch (nLevel) {
case 0: nMax = 4; break;
case 1: nMax = 13; break;
case 2: nMax = 21; break;
case 3: nMax = 15; break;
case 4: nMax = 17; break;
case 5: nMax = 13; break;
case 6: nMax = 14; break;
case 7: nMax = 8; break;
case 8: nMax = 9; break;
case 9: nMax = 12;
}
return (nScroll < nMax) ? nScroll : nMax;
}
// * nModifier is to 'raise' the level of the oAdventurer
void CreateArcaneScroll(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'SCROLL' AND subtype like '%ARCANE%' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateDivineScroll(object oTarget, object oAdventurer, int nModifier=0){
string sWhere = "WHERE type = 'SCROLL' AND subtype like '%DIVINE%' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateAmmo(object oTarget, object oAdventurer, int nModifier=0) {
string sWhere = "WHERE type = 'AMMUNITION' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateTrapKit(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'KIT' AND subtype = 'TRAP' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateHealingKit(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'KIT' AND subtype = 'HEALING' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateLockPick(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'MISCELLANEOUS' AND subtype = 'LOCKPICK' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateKit(object oTarget, object oAdventurer, int nModifier = 0) {
switch (Random(8)) {
case 0: CreateTrapKit(oTarget, oAdventurer, nModifier); break;
case 1:
case 2:
case 3:
case 4: CreateHealingKit(oTarget, oAdventurer, nModifier); break;
case 5:
case 6:
case 7: CreateLockPick(oTarget, oAdventurer, nModifier);
}
}
void CreatePotion(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'POTION' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
//::///////////////////////////////////////////////
//:: CreateTable2GenericItem
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
Creates an item based upon the class of
oAdventurer
*/
//:://////////////////////////////////////////////
//:: Created By: Brent
//:: Created On:
//:://////////////////////////////////////////////
void CreateGenericMiscItem(object oTarget, object oAdventurer, int nModifier=0) {
string sWhere = "WHERE magical = 0 " ;
string sRes = GetRandomFromTreasureTable(sWhere);
dbCreateItemOnObject(sRes, oAdventurer, oTarget);
}
// * this function just returns an item that is more appropriate
// * for this class. Only wizards, sorcerers, clerics, monks, rogues and bards get this
void CreateGenericClassItem(object oTarget, object oAdventurer, int nSpecific =0) {
switch (GetLevelByPosition(1, oAdventurer)) {
case CLASS_TYPE_DRUID:
if (nSpecific == 0)
CreateGenericDruidWeapon(oTarget, oAdventurer);
else
CreateSpecificDruidWeapon(oTarget, oAdventurer);
break;
case CLASS_TYPE_WIZARD:
case CLASS_TYPE_SORCERER:
// * 30% chance of getting a magic scroll else get a weapon suited for a wizard
if (Random(100) + 1 > 70)
// * grab an arcane scroll as if the wizard had +4 levels
CreateArcaneScroll(oTarget, oAdventurer, 4);
else if (nSpecific == 0)
CreateGenericWizardWeapon(oTarget, oAdventurer);
else
CreateSpecificWizardWeapon(oTarget, oAdventurer);
break;
case CLASS_TYPE_CLERIC:
CreateHealingKit(oTarget, oAdventurer);
break;
case CLASS_TYPE_MONK:
if (nSpecific == 0)
CreateGenericMonkWeapon(oTarget, oAdventurer);
else
CreateSpecificMonkWeapon(oTarget, oAdventurer);
break;
case CLASS_TYPE_ROGUE:
if (d100() <= 60)
CreateLockPick(oTarget, oAdventurer);
else
CreateItemByClass(oTarget, oAdventurer, 0, "ROGUE");
break;
case CLASS_TYPE_BARD:
if (d100() <= 30)
CreateLockPick(oTarget, oAdventurer);
else
CreateItemByClass(oTarget, oAdventurer, 0, "BARD");
break;
}
}
void CreateGenericRodStaffWand(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'WEAPON' AND subtype = 'WAND' OR subtype = 'ROD' OR subtype = 'STAFF' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateGenericMonkWeapon(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'WEAPON' AND class LIKE '%MONK%' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateSpecificMonkWeapon(object oTarget, object oAdventurer, int nModifier = 0) {
CreateGenericMonkWeapon(oTarget, oAdventurer, JUMP_LEVEL);
}
void CreateGenericDruidWeapon(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'WEAPON' AND class LIKE '%DRUID%' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateSpecificDruidWeapon(object oTarget, object oAdventurer, int nModifier = 0) {
CreateGenericDruidWeapon(oTarget, oAdventurer, JUMP_LEVEL);
}
void CreateGenericWizardWeapon(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'WEAPON' AND class LIKE '%WIZARD%' OR class LIKE '%SORCERER%' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateSpecificWizardWeapon(object oTarget, object oAdventurer, int nModifier = 0) {
CreateGenericWizardWeapon(oTarget, oAdventurer, JUMP_LEVEL);
}
void CreateGenericSimple(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'WEAPON' AND feat = 'SIMPLE' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateGenericMartial(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'WEAPON' AND feat = 'MARTIAL' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateGenericExotic(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'WEAPON' AND feat = 'EXOTIC' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateGenericLightArmor(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'ARMOR' AND feat = 'LIGHT' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateGenericMediumArmor(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'ARMOR' AND feat = 'MEDIUM' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
void CreateGenericHeavyArmor(object oTarget, object oAdventurer, int nModifier = 0) {
string sWhere = "WHERE type = 'ARMOR' AND feat = 'HEAVY' AND value < " ;
CreateItemFinal(oTarget, oAdventurer, nModifier, sWhere) ;
}
// *
// * SPECIC TREASURE ITEMS (re: Named Items)
// *
void CreateSpecificMiscItem(object oTarget,object oAdventurer) {
CreateGenericMiscItem(oTarget, oAdventurer, JUMP_LEVEL);
}
void CreateSpecificRodStaffWand(object oTarget, object oAdventurer) {
CreateGenericRodStaffWand(oTarget, oAdventurer, JUMP_LEVEL);
}
void CreateSpecificSimple(object oTarget, object oAdventurer) {
CreateGenericSimple(oTarget, oAdventurer, JUMP_LEVEL);
}
void CreateSpecificMartial(object oTarget, object oAdventurer) {
CreateGenericMartial(oTarget, oAdventurer, JUMP_LEVEL);
}
void CreateSpecificExotic(object oTarget, object oAdventurer) {
CreateGenericExotic(oTarget, oAdventurer, JUMP_LEVEL);
}
void CreateSpecificLightArmor(object oTarget, object oAdventurer) {
CreateGenericLightArmor(oTarget, oAdventurer, JUMP_LEVEL);
}
void CreateSpecificMediumArmor(object oTarget, object oAdventurer) {
CreateGenericMediumArmor(oTarget, oAdventurer, JUMP_LEVEL);
}
void CreateSpecificHeavyArmor(object oTarget, object oAdventurer) {
CreateGenericHeavyArmor(oTarget, oAdventurer, JUMP_LEVEL);
}
// * if nSpecific is = 1 then spawn in 'named' items at the higher levels
void CreateTable2Item(object oTarget, object oAdventurer, int nSpecific=0) {
string sItem = "NW_IT_GOLD001" ;
// 2 Means to treat the ranger as a barbarian. A 1 is to treat it as a fighter
int nSpecialRanger = 0 ;
// * May 2002: Changed using Preston's multiclass function
// * it randomly chooses one of your classes
int nClass = nDetermineClassToUse(oAdventurer);
// * SPECIAL RANGER BEHAVIOR
// * If the ranger has the Heavy Armor proficiency, will treat the ranger
if ( nClass == CLASS_TYPE_RANGER && GetHasFeat(FEAT_ARMOR_PROFICIENCY_HEAVY))
nSpecialRanger = 1;
else if (nClass == CLASS_TYPE_RANGER)
nSpecialRanger = 2;
//* SETUP probabilities based on Class
// if ( nClass == CLASS_TYPE_FIGHTER || nClass == CLASS_TYPE_PALADIN || nSpecialRanger == 1) {
int nProbMisc = 20;
int nProbClass = 0;
int nProbRodStaffWand = 5;
int nProbSimple = 5;
int nProbMartial = 20;
int nProbExotic = 10;
int nProbLight = 5;
int nProbMedium = 15;
int nProbHeavy = 20;
if (nClass == CLASS_TYPE_WIZARD || nClass == CLASS_TYPE_SORCERER) {
nProbMisc = 40;
nProbClass = 30;
nProbRodStaffWand = 15;
nProbSimple = 3;
nProbMartial = 3;
nProbExotic = 3;
nProbLight = 2;
nProbMedium = 2;
nProbHeavy = 2;
} else if (nClass == CLASS_TYPE_BARBARIAN || nSpecialRanger == 2) {
nProbMisc = 20;
nProbClass = 0;
nProbRodStaffWand = 5;
nProbSimple = 17;
nProbMartial = 27;
nProbExotic = 15;
nProbLight = 8;
nProbMedium = 5;
nProbHeavy = 3;
} else if (nClass == CLASS_TYPE_CLERIC) {
nProbMisc = 20;
nProbClass = 10;
nProbRodStaffWand = 10;
nProbSimple = 25;
nProbMartial = 7;
nProbExotic = 5;
nProbLight = 5;
nProbMedium = 8;
nProbHeavy = 10;
} else if (nClass == CLASS_TYPE_DRUID) {
nProbMisc = 20;
nProbClass = 25;
nProbRodStaffWand = 15;
nProbSimple = 10;
nProbMartial = 5;
nProbExotic = 5;
nProbLight = 10;
nProbMedium = 5;
nProbHeavy = 5;
} else if (nClass == CLASS_TYPE_MONK) {
nProbMisc = 20;
nProbClass = 50;
nProbRodStaffWand = 2;
nProbSimple = 7;
nProbMartial = 2;
nProbExotic = 7;
nProbLight = 4;
nProbMedium = 4;
nProbHeavy = 4;
} else if (nClass == CLASS_TYPE_ROGUE) {
nProbMisc = 25;
nProbClass = 10;
nProbRodStaffWand = 10;
nProbSimple = 25;
nProbMartial = 5;
nProbExotic = 5;
nProbLight = 10;
nProbMedium = 5;
nProbHeavy = 5;
} else if (nClass == CLASS_TYPE_BARD) {
nProbMisc = 25;
nProbClass = 5;
nProbRodStaffWand = 5;
nProbSimple = 25;
nProbMartial = 10;
nProbExotic = 10;
nProbLight = 10;
nProbMedium = 5;
nProbHeavy = 5;
}
//* Create Items based on Probabilities
int nRandom = d100() ;
if (nRandom <= nProbMisc) {
if (nSpecific == 0)
CreateGenericMiscItem(oTarget, oAdventurer);
else
CreateSpecificMiscItem(oTarget, oAdventurer);
return ;
}
nRandom -= nProbMisc ;
if (nRandom <= nProbClass) {
CreateGenericClassItem(oTarget, oAdventurer, nSpecific);
return ;
}
nRandom -= nProbClass ;
if (nRandom <= nProbRodStaffWand) {
if (nSpecific == 0)
CreateGenericRodStaffWand(oTarget, oAdventurer) ;
else
CreateSpecificRodStaffWand(oTarget, oAdventurer);
return ;
}
nRandom -= nProbRodStaffWand ;
if (nRandom <= nProbSimple) {
if (nSpecific == 0)
CreateGenericSimple(oTarget, oAdventurer);
else
CreateSpecificSimple(oTarget, oAdventurer);
return ;
}
nRandom -= nProbSimple ;
if (nRandom <= nProbMartial) {
if (nSpecific == 0)
CreateGenericMartial(oTarget, oAdventurer);
else
CreateSpecificMartial(oTarget, oAdventurer);
return ;
}
nRandom -= nProbMartial ;
if (nRandom <= nProbExotic) {
if (nSpecific == 0)
CreateGenericExotic(oTarget, oAdventurer);
else
CreateSpecificExotic(oTarget, oAdventurer);
return ;
}
nRandom -= nProbExotic ;
if (nRandom <= nProbLight) {
if (nSpecific == 0)
CreateGenericLightArmor(oTarget, oAdventurer);
else
CreateSpecificLightArmor(oTarget, oAdventurer);
return ;
}
nRandom -= nProbLight ;
if (nRandom <= nProbMedium) {
if (nSpecific == 0)
CreateGenericMediumArmor(oTarget, oAdventurer);
else
CreateSpecificMediumArmor(oTarget, oAdventurer);
return ;
}
nRandom -= nProbMedium ;
if (nRandom <= nProbHeavy) {
if (nSpecific == 0)
CreateGenericHeavyArmor(oTarget, oAdventurer);
else
CreateSpecificHeavyArmor(oTarget, oAdventurer);
return ;
}
}
//::///////////////////////////////////////////////
//:: GenerateTreasure
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Generate Treasure
NOTE: When used by NPCs, the treasure is scaled
to how powerful the NPC is.
If used by containers, it is scaled by how
powerful the PC is.
PARAMETERS
oLastOpener = The creature that opened the container
oCreateOn = The place to put the treasure. If this is
invalid then the treasure is placed on oLastOpener
*/
//:://////////////////////////////////////////////
//:: Created By: Andrew
//:: Created On:
//:://////////////////////////////////////////////
void GenerateTreasure(int nTreasureType, object oLastOpener, object oCreateOn) {
WriteTimestampedLogEntry("Generation de drop : ") ;
WriteTimestampedLogEntry(" player = " + GetName(oLastOpener) + " [" + GetPCPlayerName(oLastOpener) + "]") ;
WriteTimestampedLogEntry(" niveau = " + IntToString(GetHitDice(oLastOpener))) ;
WriteTimestampedLogEntry(" niveau du mob = " + IntToString(GetHitDice(oCreateOn))) ;
// * abort treasure if no one opened the container
if (GetIsObjectValid(oLastOpener) == FALSE) {
return;
}
// * if no valid create on object, then create on oLastOpener
if (oCreateOn == OBJECT_INVALID) {
oCreateOn = oLastOpener;
}
// * VARIABLES
int nProbBook = LOW_PROB_BOOK;
int nProbAnimal = LOW_PROB_ANIMAL;
int nProbJunk = LOW_PROB_JUNK;
int nProbGold = LOW_PROB_GOLD;
int nProbGem = LOW_PROB_GEM;
int nProbJewel = LOW_PROB_JEWEL;
int nProbArcane = LOW_PROB_ARCANE;
int nProbDivine = LOW_PROB_DIVINE;
int nProbAmmo = LOW_PROB_AMMO ;
int nProbKit = LOW_PROB_KIT;
int nProbPotion = LOW_PROB_POTION;
int nProbTable2 = LOW_PROB_TABLE2;
int nSpecific = 0;
int i = 0;
int nNumberItems = GetNumberOfItems(nTreasureType);
// * Set Treasure Type Values
if (nTreasureType == TREASURE_MEDIUM) {
nProbBook = MEDIUM_PROB_BOOK;
nProbAnimal = MEDIUM_PROB_ANIMAL;
nProbJunk = MEDIUM_PROB_JUNK;
nProbGold = MEDIUM_PROB_GOLD;
nProbGem = MEDIUM_PROB_GEM;
nProbJewel = MEDIUM_PROB_JEWEL;
nProbArcane = MEDIUM_PROB_ARCANE;
nProbDivine = MEDIUM_PROB_DIVINE;
nProbAmmo = MEDIUM_PROB_AMMO ;
nProbKit = MEDIUM_PROB_KIT;
nProbPotion = MEDIUM_PROB_POTION;
nProbTable2 = MEDIUM_PROB_TABLE2;
} else if (nTreasureType == TREASURE_HIGH) {
nProbBook = HIGH_PROB_BOOK;
nProbAnimal = HIGH_PROB_ANIMAL;
nProbJunk = HIGH_PROB_JUNK;
nProbGold = HIGH_PROB_GOLD;
nProbGem = HIGH_PROB_GEM;
nProbJewel = HIGH_PROB_JEWEL;
nProbArcane = HIGH_PROB_ARCANE;
nProbDivine = HIGH_PROB_DIVINE;
nProbAmmo = HIGH_PROB_AMMO ;
nProbKit = HIGH_PROB_KIT;
nProbPotion = HIGH_PROB_POTION;
nProbTable2 = HIGH_PROB_TABLE2;
} else if (nTreasureType == TREASURE_BOSS) {
nProbTable2 = 100;
nSpecific = 1;
} else if (nTreasureType == TREASURE_BOOK) {
nProbBook = 90;
nProbArcane = 6;
nProbDivine = 4;
}
for (i = 1; i <= nNumberItems; i++) {
int nRandom = d100();
if (nRandom <= nProbAnimal) {
CreateAnimalPart(oCreateOn, oLastOpener) ;
return ;
}
nRandom -= nProbAnimal ;
if (nRandom <= nProbJunk) {
CreateJunk(oCreateOn, oLastOpener) ;
return ;
}
nRandom -= nProbJunk ;
if (nRandom <= nProbGold + nProbBook) {
CreateGold(oCreateOn, oLastOpener, nTreasureType);
return ;
}
nRandom -= nProbGold + nProbBook ;
if (nRandom <= nProbGem) {
CreateGem(oCreateOn, oLastOpener, nTreasureType) ;
return ;
}
nRandom -= nProbGem ;
if (nRandom <= nProbJewel) {
CreateJewel(oCreateOn, oLastOpener, nTreasureType) ;
return ;
}
nRandom -= nProbJewel ;
if (nRandom <= nProbArcane) {
CreateArcaneScroll(oCreateOn, oLastOpener, nTreasureType) ;
return ;
}
nRandom -= nProbArcane ;
if (nRandom <= nProbDivine) {
CreateDivineScroll(oCreateOn, oLastOpener);
return ;
}
nRandom -= nProbDivine ;
if (nRandom <= nProbAmmo) {
CreateAmmo(oCreateOn, oLastOpener);
return ;
}
nRandom -= nProbAmmo ;
if (nRandom <= nProbKit) {
CreateKit(oCreateOn, oLastOpener);
return ;
}
nRandom -= nProbKit ;
if (nRandom <= nProbPotion) {
CreatePotion(oCreateOn, oLastOpener) ;
return ;
}
nRandom -= nProbTable2 ;
if (nRandom <= nProbTable2) {
CreateTable2Item(oCreateOn, oLastOpener, nSpecific) ;
return ;
}
}
}
void GenerateLowTreasure(object oLastOpener, object oCreateOn=OBJECT_INVALID) {
GenerateTreasure(TREASURE_LOW, oLastOpener, oCreateOn);
}
void GenerateMediumTreasure(object oLastOpener, object oCreateOn=OBJECT_INVALID) {
GenerateTreasure(TREASURE_MEDIUM, oLastOpener, oCreateOn);
}
void GenerateHighTreasure(object oLastOpener, object oCreateOn=OBJECT_INVALID) {
GenerateTreasure(TREASURE_HIGH, oLastOpener, oCreateOn);
}
void GenerateBossTreasure(object oLastOpener, object oCreateOn=OBJECT_INVALID) {
GenerateTreasure(TREASURE_BOSS, oLastOpener, oCreateOn);
}
void GenerateBookTreasure(object oLastOpener, object oCreateOn=OBJECT_INVALID) {
GenerateTreasure(TREASURE_BOOK, oLastOpener, oCreateOn);
}
//::///////////////////////////////////////////////
//:: GenerateNPCTreasure
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Preferrably called from OnSpawn scripts.
Use the random treasure functions to generate
appropriate treasure for the creature to drop.
*/
//:://////////////////////////////////////////////
//:: Created By: Brent
//:: Created On: January 2002
//:://////////////////////////////////////////////
void GenerateNPCTreasure(int nTreasureValue=1,
object oTreasureGetter=OBJECT_SELF,
object oKiller=OBJECT_SELF) {
//DestroyObject(OBJECT_SELF);
// * if I am an animal ,then give me animal stuff instead
if (GetObjectType(oTreasureGetter) == OBJECT_TYPE_CREATURE) {
if (
(GetRacialType(oTreasureGetter) == RACIAL_TYPE_UNDEAD) ||
(GetRacialType(oTreasureGetter) == RACIAL_TYPE_ANIMAL) ||
(GetRacialType(oTreasureGetter) == RACIAL_TYPE_BEAST) ||
(GetRacialType(oTreasureGetter) == RACIAL_TYPE_MAGICAL_BEAST) ||
(GetRacialType(oTreasureGetter) == RACIAL_TYPE_VERMIN)
) {
// CreateAnimalPart(oTreasureGetter);
// April 23 2002: Removed animal parts. They are silly.
return ;
}
}
if (nTreasureValue == 1) {
// April 2002: 30% chance of not getting any treasure now
// if a creature
if (Random(100) + 1 >= 75) {
GenerateTreasure(TREASURE_LOW, oTreasureGetter, oKiller);
}
} else if (nTreasureValue == 2) {
GenerateTreasure(TREASURE_MEDIUM, oTreasureGetter, oKiller);
} else if (nTreasureValue == 3) {
GenerateTreasure(TREASURE_HIGH, oTreasureGetter, oKiller);
} else if (nTreasureValue == 4) {
GenerateBossTreasure(oKiller, oTreasureGetter);
}
}
// *
// * Theft Prevention
// *
//::///////////////////////////////////////////////
//:: ShoutDisturbed
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
*/
//:://////////////////////////////////////////////
//:: Created By:
//:: Created On:
//:://////////////////////////////////////////////
// * Container shouts if disturbed
void ShoutDisturbed() {
if (GetIsDead(OBJECT_SELF) == TRUE) {
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
// Cycle through the targets within the spell shape until an invalid object is captured.
while (GetIsObjectValid(oTarget)) {
if (GetFactionEqual(oTarget, OBJECT_SELF) == TRUE) {
// * Make anyone who is a member of my faction hostile if I am violated
object oAttacker = GetLastAttacker();
SetIsTemporaryEnemy(oAttacker,oTarget);
AssignCommand(oTarget, ActionAttack(oAttacker));
}
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
}
} else if (GetIsOpen(OBJECT_SELF) == TRUE) {
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
// Cycle through the targets within the spell shape until an invalid object is captured.
while (GetIsObjectValid(oTarget)) {
if (GetFactionEqual(oTarget, OBJECT_SELF) == TRUE) {
// * Make anyone who is a member of my faction hostile if I am violated
object oAttacker = GetLastOpener();
SetIsTemporaryEnemy(oAttacker,oTarget);
AssignCommand(oTarget, ActionAttack(oAttacker));
}
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_LARGE, GetLocation(OBJECT_SELF), TRUE, OBJECT_TYPE_CREATURE);
}
}
}
//::///////////////////////////////////////////////
//:: Determine Class to Use
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
Determines which of a NPCs three classes to
use in the random treasure system
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: April 4, 2002
//:://////////////////////////////////////////////
int nDetermineClassToUse(object oCharacter) {
int nClass;
int nTotal = GetHitDice(oCharacter);
if (nTotal < 1) {
nTotal = 1;
}
float fTotal = IntToFloat(nTotal) ;
int nClass1 = GetClassByPosition(1, oCharacter);
int nState1 = FloatToInt((IntToFloat(GetLevelByClass(nClass1, oCharacter)) / fTotal) * 100);
int nClass2 = GetClassByPosition(2, oCharacter);
int nState2 = FloatToInt((IntToFloat(GetLevelByClass(nClass2, oCharacter)) / fTotal) * 100) + nState1;
int nClass3 = GetClassByPosition(3, oCharacter);
int nState3 = FloatToInt((IntToFloat(GetLevelByClass(nClass3, oCharacter)) / fTotal) * 100) + nState2;
int nUseClass = d100();
if(nUseClass <= nState1) {
nClass = nClass1;
} else if(nUseClass > nState1 && nUseClass <= nState2) {
nClass = nClass2;
} else {
nClass = nClass3;
}
return nClass;
}