//:://////////////////////////////////////////////////// //:: NW_O2_CONINCLUDE.nss //:: Copyright (c) 2001 Bioware Corp. //:://////////////////////////////////////////////// /* This include file handles the random treasure distribution for treasure from 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 amount 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 // * --------- // * CONSTANTS // * --------- // * tweaking constants // * SIX LEVEL RANGES const int RANGE_1_MIN = 0; const int RANGE_1_MAX = 5; const int RANGE_2_MIN = 6; const int RANGE_2_MAX = 8; const int RANGE_3_MIN = 9; const int RANGE_3_MAX = 10; const int RANGE_4_MIN = 11; const int RANGE_4_MAX = 13; const int RANGE_5_MIN = 14; const int RANGE_5_MAX = 16; const int RANGE_6_MIN = 17; const int RANGE_6_MAX = 100; // * NUMBER OF ITEMS APPEARING const int NUMBER_LOW_ONE = 100; const int NUMBER_MED_ONE = 60; const int NUMBER_HIGH_ONE = 40; const int NUMBER_BOSS_ONE = 100; const int NUMBER_LOW_TWO = 0; const int NUMBER_MED_TWO = 30; const int NUMBER_HIGH_TWO = 40; const int NUMBER_BOSS_TWO = 0; const int NUMBER_LOW_THREE = 0; const int NUMBER_MED_THREE = 10; const int NUMBER_HIGH_THREE = 20; const int NUMBER_BOSS_THREE = 0; const int NUMBER_BOOK_ONE = 75; const int NUMBER_BOOK_TWO = 20; const int NUMBER_BOOK_THREE = 5; // * AMOUNT OF GOLD BY VALUE const float LOW_MOD_GOLD = 0.5; const float MEDIUM_MOD_GOLD = 1.0; const float HIGH_MOD_GOLD = 3.0; // * FREQUENCY OF ITEM TYPE APPEARING BY TREASURE TYPE const int LOW_PROB_BOOK = 1; const int MEDIUM_PROB_BOOK = 1; const int HIGH_PROB_BOOK =1; const int LOW_PROB_ANIMAL = 0; const int MEDIUM_PROB_ANIMAL = 0; const int HIGH_PROB_ANIMAL = 0; const int LOW_PROB_JUNK = 2; const int MEDIUM_PROB_JUNK = 1; const int HIGH_PROB_JUNK = 1; const int LOW_PROB_GOLD = 43; const int MEDIUM_PROB_GOLD = 38; const int HIGH_PROB_GOLD = 15; const int LOW_PROB_GEM = 9; const int MEDIUM_PROB_GEM = 15; const int HIGH_PROB_GEM = 15; const int LOW_PROB_JEWEL = 4; const int MEDIUM_PROB_JEWEL = 6; const int HIGH_PROB_JEWEL = 15; const int LOW_PROB_ARCANE = 3; const int MEDIUM_PROB_ARCANE = 3; const int HIGH_PROB_ARCANE = 3; const int LOW_PROB_DIVINE = 3; const int MEDIUM_PROB_DIVINE = 3; const int HIGH_PROB_DIVINE = 3; const int LOW_PROB_AMMO = 10; const int MEDIUM_PROB_AMMO = 5; const int HIGH_PROB_AMMO = 3; const int LOW_PROB_KIT = 5; const int MEDIUM_PROB_KIT = 5; const int HIGH_PROB_KIT = 5; const int LOW_PROB_POTION =17; const int MEDIUM_PROB_POTION = 20; const int HIGH_PROB_POTION= 9; const int LOW_PROB_TABLE2 = 3; const int MEDIUM_PROB_TABLE2 = 3; const int HIGH_PROB_TABLE2= 30; // * readability constants const int TREASURE_LOW = 1; const int TREASURE_MEDIUM = 2; const int TREASURE_HIGH = 3; const int TREASURE_BOSS = 4; const 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 const int JUMP_LEVEL = 2; //* Declarations 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); // * Returns the object that either last opened the container or destroyed it object GetLastOpener(); // Removes every item from the chest void RemoveItems(object oChest); // * // * IMPLEMENTATION // * // * Comment the speakstring in to debug treasure generation void dbSpeak(string s) { // SpeakString(s); } void RemoveItems(object oChest) { object oItem; object oStrip; oItem=GetFirstItemInInventory(oChest); while (GetIsObjectValid(oItem)) { oStrip=oItem; DestroyObject(oStrip); oItem=GetNextItemInInventory(oChest); } } //* made this function to help with debugging void dbCreateItemOnObject(string sItemTemplate, object oTarget = OBJECT_SELF, int nStackSize = 1) { /* if (sItemTemplate == "") { PrintString("blank item passed into dbCreateItemOnObject. Please report as bug to Brent."); } dbSpeak(sItemTemplate); */ //sItemTemplate = GetStringLowerCase if (nStackSize == 1) { // * checks to see if this is a throwing item and if it is // * it creates more string sRoot = GetSubString(sItemTemplate, 0, 6); //dbSpeak("ROOT: " + sRoot); if (GetStringLowerCase(sRoot) == "nw_wth") { nStackSize = Random(30) + 1; } } object oItem = CreateItemOnObject(sItemTemplate, oTarget, nStackSize); /* if (GetIsObjectValid(oItem) == FALSE && sItemTemplate != "NW_IT_GOLD001") { // * check to see if item is there in a stack, if not give warning if (GetIsObjectValid(GetItemPossessedBy(oTarget, GetStringUpperCase(sItemTemplate))) == FALSE && GetIsObjectValid(GetItemPossessedBy(oTarget, GetStringLowerCase(sItemTemplate))) == FALSE) { PrintString("**DESIGN***"); PrintString("******" + sItemTemplate + " is an invalid item template. Please report as bug to Brent."); PrintString("*******"); } } */ } // * // * GET FUNCTIONS // * // * Returns the object that either last opened the container or destroyed it object GetLastOpener() { if (GetIsObjectValid(GetLastOpenedBy()) == TRUE) { //dbSpeak("LastOpener: GetLastOpenedBy " + GetTag(GetLastOpenedBy())); return GetLastOpenedBy(); } else if (GetIsObjectValid(GetLastKiller()) == TRUE) { //dbSpeak("LastOpener: GetLastAttacker"); return GetLastKiller(); } //dbSpeak("LastOpener: The Object is Invalid you weenie!"); 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; break; } //dbSpeak("nMin = " + IntToString(nMin)); //dbSpeak("nMax = " + IntToString(nMax)); //dbSpeak("GetRange.nHD = " + IntToString(nHD)); if (nHD >= nMin && nHD <= nMax) { return TRUE; } return FALSE; } //:://///////////////////////////////////////////// //:: GetNumberOfItems //:: Copyright (c) 2002 Bioware Corp. //::////////////////////////////////////////////// /* Returns the number of items to create. */ //::////////////////////////////////////////////// //:: Created By: Brent //:: Created On: //::////////////////////////////////////////////// int GetNumberOfItems(int nTreasureType) { int nItems = 0; int nRandom = 0; int nProbThreeItems = 0; int nProbTwoItems = 0; int nProbOneItems = 0; if (nTreasureType == TREASURE_LOW) { nProbThreeItems = NUMBER_LOW_THREE; nProbTwoItems = NUMBER_LOW_TWO; nProbOneItems = NUMBER_LOW_ONE; } else if (nTreasureType == TREASURE_MEDIUM) { nProbThreeItems = NUMBER_MED_THREE; nProbTwoItems = NUMBER_MED_TWO; nProbOneItems = NUMBER_MED_ONE; } else if (nTreasureType == TREASURE_HIGH) { nProbThreeItems = NUMBER_HIGH_THREE; nProbTwoItems = NUMBER_HIGH_TWO; nProbOneItems = NUMBER_HIGH_ONE; } else if (nTreasureType == TREASURE_BOSS) { nProbThreeItems = NUMBER_BOSS_THREE; nProbTwoItems = NUMBER_BOSS_TWO; nProbOneItems = NUMBER_BOSS_ONE; } else if (nTreasureType == TREASURE_BOOK) { nProbThreeItems = NUMBER_BOOK_THREE; nProbTwoItems = NUMBER_BOOK_TWO; nProbOneItems = NUMBER_BOOK_ONE; } nRandom = d100(); if (nRandom <= nProbThreeItems) { nItems = 3; } else if (nRandom <= nProbTwoItems + nProbThreeItems) { nItems = 2; } else { nItems = 1; } int nSpotskill=GetSkillRank(SKILL_SEARCH, GetLastOpener()); if (nSpotskill>0) { if (GetIsSkillSuccessful(GetLastOpener(), SKILL_SEARCH,21)) { nItems=nItems+1; } } // * May 13 2002: Cap number of items, in case of logic error if (nItems > 3) { nItems = 3; } return nItems; } // * // * TREASURE GENERATION FUNCTIONS // * // * // * Non-Scaling Treasure // * void CreateBook(object oTarget) { string sRes; // Palmer - make our own books drop as loot // once I can find a way to stop it happening in // IWD areas if (1) { int nBook1 = Random(31) + 1; sRes = "NW_IT_BOOK01"; if (nBook1 < 10) { sRes = "NW_IT_BOOK00" + IntToString(nBook1); } else { sRes = "NW_IT_BOOK0" + IntToString(nBook1); } //dbSpeak("Create book"); dbCreateItemOnObject(sRes, oTarget); } else { int nResult=Random(12)+1; switch (nResult) { case 1: sRes = "jw_wildm_book"; break; case 2: sRes = "jw_book1"; break; case 3: sRes = "jw_book8"; break; case 4: sRes = "jw_dwarf_book1"; break; case 5: sRes = "jw_dwarf_book4"; break; case 6: sRes = "jw_book14"; break; case 7: sRes = "jw_book6"; break; case 8: sRes = "jw_book3"; break; case 9: sRes = "jw_book12"; break; case 10: sRes = "jw_book15"; break; case 11: sRes = "jw_book7"; break; case 12: sRes = "jw_dwarf_book5"; break; } } dbCreateItemOnObject(sRes, oTarget); } void CreateAnimalPart(object oTarget) { string sRes = ""; int nResult = Random(3) + 1; switch (nResult) { case 1: sRes = "NW_IT_MSMLMISC20"; break; case 2: sRes = "NW_IT_MMIDMISC05"; break; case 3: sRes = "NW_IT_MMIDMISC06"; break; } //dbSpeak("animal"); dbCreateItemOnObject(sRes, oTarget); } void CreateJunk(object oTarget) { string sRes = "NW_IT_TORCH001"; int NUM_ITEMS = 6; int nResult = Random(NUM_ITEMS) + 1; int nKit = 0; switch (nResult) { case 1: sRes = "NW_IT_MPOTION021"; break; //ale case 2: sRes = "NW_IT_MPOTION021"; break; // ale case 3: sRes = "NW_IT_MPOTION023"; break; // wine case 4: sRes = "NW_IT_MPOTION021"; break; // ale case 5: sRes = "NW_IT_MPOTION022"; break; // spirits case 6: sRes = "NW_IT_TORCH001"; break; //torch } //dbSpeak("CreateJunk"); dbCreateItemOnObject(sRes, oTarget); } // * // * Scaling Treasure // * void CreateGold(object oTarget, object oAdventurer, int nTreasureType, int nModifier = 0) { int nHD = GetHitDice(oAdventurer) + nModifier; if (GetObjectType(OBJECT_SELF)==OBJECT_TYPE_PLACEABLE) { if (GetWillSavingThrow(OBJECT_SELF)2) { sGem="nw_it_gem007"; } } if (sGem=="nk_rhodoliteuc") { if(d20()>2) { sGem="nw_it_gem013"; } } dbCreateItemOnObject(sGem, oTarget, 1); } void CreateJewel(object oTarget, object oAdventurer, int nTreasureType, int nModifier = 0) { int nHD = GetHitDice(oAdventurer) + nModifier; if (GetObjectType(OBJECT_SELF)==OBJECT_TYPE_PLACEABLE) { if (GetWillSavingThrow(OBJECT_SELF) nMax) nScroll = nMax; return nScroll; } // * nModifier is to 'raise' the level of the oAdventurer void CreateArcaneScroll(object oTarget, object oAdventurer, int nModifier = 0) { int nMaxSpells = 21; int nHD = GetHitDice(oAdventurer) + nModifier; if (GetObjectType(OBJECT_SELF)==OBJECT_TYPE_PLACEABLE) { if (GetWillSavingThrow(OBJECT_SELF) nState1 && nUseClass <= nState2) { nClass = nClass2; } else { nClass = nClass3; } return nClass; } //::void main (){}