Author Topic: Prevent mobs form getting loot from the standard palette  (Read 2696 times)

Legacy_paradogz

  • Newbie
  • *
  • Posts: 30
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« on: July 11, 2016, 12:20:10 pm »


               

Hi,



How could I prevent items from the standard palette to be looted ?


Many thanks



               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #1 on: July 11, 2016, 03:36:15 pm »


               

You need to change the "loot system" that you use from the NWN default to something else. Or you can edit the NWN default loot system and add different items to it.


 


To change the loot system:


For creatures:


Edit the death script of the creature and replace craft_drop_items() with another function.


 


I use my loot scripts for this which is accomplished by replacing craft_drop_items() with my function LootCreatureDeath(). At the top of the NPC death script is: #include "_inc_loot"


I also set local variables on the creature to indicate which merchant(s) to pull loot from.


 


For placeables:


look at the onOpen and onDeath events. They likely have a script which begins with nw_02_generallow  or something similar.


You'll want to replace those with a script that uses a different loot system or rewrite them.



               
               

               
            

Legacy_paradogz

  • Newbie
  • *
  • Posts: 30
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #2 on: July 11, 2016, 05:04:16 pm »


               

Hi,


Thanks a lot for your help, some of the standard item are a major problem for the pvp balance of my module.


I really appreciate that the community helps really quickly... I cannot pin point where the problem is, maybe somebody nice could have a loot in my scripts, that would be very kind. 


 


 


9mRQfze.png


 


 



 


//::///////////////////////////////////////////////////

//:: X0_O2_ANYMED.NSS

//:: OnOpened/OnDeath script for a treasure container.

//:: Treasure type: Any, random selection from whatever is in base container

//:: Treasure level: TREASURE_TYPE_MED

//::

//:: Copyright © 2002 Floodgate Entertainment

//:: Created By: Naomi Novik

//:: Created On: 11/21/2002

//::///////////////////////////////////////////////////


#include "x0_i0_treasure"


void main()

{


    CTG_CreateTreasure(TREASURE_TYPE_MED, GetLastOpener(), OBJECT_SELF);


}

 



 



 


//:://////////////////////////////////////////////////

//:: X0_I0_TREASURE


/*

Include library for XP1 treasure generation system.


--------------------------------------------------


MAIN CONCEPT:


The module builder creates some base containers and fills them

with instances of the treasure items that s/he wants to appear

randomly. The actual treasure containers then randomly pick from

the contents of these base containers to generate their own

contents.


--------------------------------------------------


SETUP:


Create four module-wide base containers (for low, medium, high,

and unique treasure items) and place them anywhere in your

module. Make sure that they are in locations inaccessible to the

players, though!


Give these module-wide base containers these tags (or just use the

blueprints):


    X0_MOD_TREASURE_LOW       - low-level treasure

    X0_MOD_TREASURE_MED       - medium-level treasure

    X0_MOD_TREASURE_HIGH      - high-level treasure

    X0_MOD_TREASURE_UNIQ      - unique treasure items


Fill the instances of these base containers with appropriate treasure

for your module.


For any areas where you want finer control over the treasure,

simply create additional base containers (you don't need all four

-- any one that you skip will fall back to the module-wide version)

and place them in the area. Give them these tags (same just without

the "MOD"):


    X0_TREASURE_LOW       - low-level treasure

    X0_TREASURE_MED       - medium-level treasure

    X0_TREASURE_HIGH      - high-level treasure

    X0_TREASURE_UNIQ      - unique treasure items


For any treasure container, use one of the following scripts

as BOTH the OnOpen/OnDeath handler:


Any Treasure: x0_o2_any{low,med,high,uniq}

Books (book, scroll): x0_o2_book{low,med,high,uniq}

Potions: x0_o2_potn{low,med,high,uniq}

Armor (armor, shield, helm, boots, etc): x0_o2_arm{low,med,high,uniq}

Weapon: x0_o2_weap{low,med,high,uniq}

Gold: x0_o2_gold{low,med,high,uniq}


Others may also be added.


MONSTER/NPC TREASURE

--------------------

If you would like to have special monster treasure (monster treasure

defaults to low treasure otherwise), you can also add any of these

base chests:


X0_TREASURE_MONSTER_<monster tag> - treasure found on monsters with

                                    the given tag. This will strip off

                                    any trailing digits, so for instance,

                                    NW_KOBOLD1, NW_KOBOLD2, NW_KOBOLD005

                                    would all end up checking the chest

                                    X0_TREASURE_MONSTER_NW_KOBOLD.


X0_TREASURE_MONSTER_<racialtype> - treasure found on monsters of the given

                                   racialtype. Ex:

                                   X0_TREASURE_MONSTER_ELF

                                   X0_TREASURE_MONSTER_UNDEAD

                                   The spelling matches that used in the

                                   RACIALTYPE_* constants.


X0_TREASURE_MONSTER       - generic treasure found on all monsters/NPCs

                            in the module.


To use monster treasure, use the default OnSpawn script nw_c2_default9

or modify the OnSpawn script as follows:


- Replace #include "nw_o2_coninclude" with #include "x0_i0_treasure"

- Replace GenerateNPCTreasure(); with CTG_GenerateNPCTreasure();

- If you prefer to generate monster treasure from the general chests,

  you can also add a parameter to CTG_GenerateNPCTreasure(); to

  specify whether the treasure generated should be low/medium/high/uniq.

  See the comments to that function for details.


--------------------------------------------------


DETAILS:


Each treasure container has a script that looks for the

nearest object with the tag matching the type of

treasure.


When the treasure-generating scripts look for a container,

they will take the nearest container in the local area, then

fall back to the module-wide container. If no container can

be found, they will fall back on the standard random treasure

generation system.


The treasure generation system will randomly select from

1-3 items from whatever items are in the nearest container.

Each item has a 50/50 chance of being replaced by a random

amount of coin based on the standard treasure generation

system.


IMPORTANT NOTE ON PROBABILITY:

Each item in the chest has an equal probability of being

selected. To control the probability of any given item

appearing, simply place multiple copies of it in the container.


Because of the stacking rules, there is a slight modification

to this. Ammunition/throwing weapons will have a probability

equal to the number of stacks in the chest, since the max stack

size is the default stack size. Potions, scrolls, and gems, however,

will be counted individually to determine the probability even if

they are stacked, since their default stack size is 1.


To control the size of the stack that actually gets created, you

should create a blueprint that has the appropriate stack size.

You can adjust the stack size of the instance you stuff into the

base container to whatever you want afterwards; the blueprint's

stack size will control what


There are scripts that will cause only specific types of items

to be selected from the container of the specified level --

eg, only books/scrolls, or only weapons or armor, etc -- useful

for bookcases or for weapon racks, & so on.


The unique treasure chest will only place each item in the

chest once, will never place more than one item, and will

never replace the item with coin.


Advantages of this system:

- Complete control over which items can appear in a

  module or in an area.


- Thematically-appropriate treasure can be placed in each

  area.


- Easy for module builders to set up.


- Trivial to add new items to the treasure distribution.


- Trivial to adjust probabilities of items appearing.


- Easy to have unique treasure items showing up randomly.


Disadvantages of this system:

- No level-specific treasure generation. This system is thus

  NOT appropriate for an area that is intended to scale to

  radically-different levels. Rather, it is appropriate for

  use where the levels of the characters are roughly known

  to the module designer and the treasure can be designed to

  match.


- No class-specific treasure generation planned for now.

  (However, I may add something to increase probability of

  certain items popping up, optionally. TBD.)


For XP1, we feel this is a good tradeoff, but this should

be kept in mind when deciding whether to use this system or

the original treasure generation system in user-made modules.


-- NN


 */

//:://////////////////////////////////////////////////

//:: Copyright © 2002 Floodgate Entertainment

//:: Created By: Naomi Novik

//:: Created On: 11/16/2002

//:://////////////////////////////////////////////////


// For legacy treasure generation

#include "nw_o2_coninclude"


/**********************************************************************

 * CONSTANTS

 **********************************************************************/


// * this is the percent chance that no treasure will be spawned by a creature dying

const int BK_CHANCE_OF_N0_MONSTERTREASURE = 80;



// Tags for the module-wide containers

string sModContLow  =     "X0_MOD_TREASURE_LOW";

string sModContMed  =     "X0_MOD_TREASURE_MED";

string sModContHigh =     "X0_MOD_TREASURE_HIGH";

string sModContUniq =     "X0_MOD_TREASURE_UNIQ";


// Tags for the area-specific containers

string sContLow  =     "X0_TREASURE_LOW";

string sContMed  =     "X0_TREASURE_MED";

string sContHigh =     "X0_TREASURE_HIGH";

string sContUniq =     "X0_TREASURE_UNIQ";


// Tag for the monster-specific containers

string sContMonster =     "X0_TREASURE_MONSTER";


// Gold item ResRef

string sGoldResRef = "NW_IT_GOLD001";


// Varname holding the number of treasure items

string sNumTreasureItemsVarname = "X0_NUM_TREASURE_ITEMS";


// Varname holding the base type of each treasure item

string sBaseTypeVarname = "X0_BASE_TYPE_TREASURE";


// Varname holding a reference to each treasure item

string sTreasureItemVarname = "X0_TREASURE_ITEM";


// Varname indicating that the treasure container has been filled

string sTreasureGeneratedVarname = "X0_TREASURE_HAS_BEEN_GENERATED";



// Major treasure categories


int TREASURE_TYPE_LOW    = 1;

int TREASURE_TYPE_MED    = 2;

int TREASURE_TYPE_HIGH   = 3;

int TREASURE_TYPE_UNIQUE = 4;

int TREASURE_TYPE_MONSTER = 5;



// Special generalized base types.

// Giving these large values to make sure they never

// conflict with the actual base type values -- that

// would cause those base types to be non-specifiable.

int TREASURE_BASE_TYPE_WEAPON = 13000;

int TREASURE_BASE_TYPE_WEAPON_NOAMMO = 13001;

int TREASURE_BASE_TYPE_WEAPON_RANGED = 13002;

int TREASURE_BASE_TYPE_WEAPON_MELEE = 13003;

int TREASURE_BASE_TYPE_ARMOR = 13004;

int TREASURE_BASE_TYPE_CLOTHING = 13005;


// Probability of a single item being generated,

// in percentage

int TREASURE_PROBABILITY_1 = 70;


// Probability of two items being generated,

// in percentage

int TREASURE_PROBABILITY_2 = 20;


// Probability of an item being converted to gold

int TREASURE_GOLD_PROBABILITY = 35;


// Multiplier to use on the value of an item to convert it to gold

float X0_GOLD_MODIFIER = 0.50;


/**********************************************************************

 * FUNCTION PROTOTYPES

 *

 * All functions prefixed with CTG for "container treasure generation".

 **********************************************************************/


// Get the number of items to generate

// Returns an integer from 1-3, probabilities

// determined by the values of the constants

// TREASURE_PROBABILITY_1 & _2.

int CTG_GetNumItems();


// Get the number of items in a base container.

int CTG_GetNumItemsInBaseContainer(object oBaseCont);


// Determine whether an item should actually just be gold.

// Returns TRUE or FALSE.

// Probability controlled by constant TREASURE_GOLD_PROBABILITY

int CTG_IsItemGold();


// Find and return the right monster container, if

// available.

object CTG_GetMonsterBaseContainer(object oSource=OBJECT_SELF);


// Locate the base container of the appropriate type closest to

// oSource.

// Possible values for nTreasureType:

//     TREASURE_TYPE_LOW

//     TREASURE_TYPE_MED

//     TREASURE_TYPE_HIGH

//     TREASURE_TYPE_UNIQUE

object CTG_GetNearestBaseContainer(int nTreasureType, object oSource=OBJECT_SELF);


// Get the module-wide base container of the appropriate type.

// Possible values for nTreasureType:

//     TREASURE_TYPE_LOW

//     TREASURE_TYPE_MED

//     TREASURE_TYPE_HIGH

//     TREASURE_TYPE_UNIQUE

object CTG_GetModuleBaseContainer(int nTreasureType);


// Get the specified item out of the given base container's inventory

object CTG_GetTreasureItem(object oBaseCont, int nItemNum);


// Test if treasure has been generated in the given object

int CTG_GetIsTreasureGenerated(object oCont);


// Set whether treasure has been generated

void CTG_SetIsTreasureGenerated(object oCont, int bGenerated=TRUE);


// Create random treasure items of the appropriate type

// in the specified container. Will typically be called

// by a script on a treasure container.

//

// Possible values for nTreasureType:

//     TREASURE_TYPE_LOW

//     TREASURE_TYPE_MED

//     TREASURE_TYPE_HIGH

//     TREASURE_TYPE_UNIQUE

void CTG_CreateTreasure(int nTreasureType, object oAdventurer, object oCont=OBJECT_SELF);


// Starting from the specified item position, return the first

// item that matches one of the three base types.

//

// nBaseType1 may also be passed in as a special custom type,

// which will OVERRIDE any other specified base types:

//

//  TREASURE_BASE_TYPE_WEAPON (for any weapon type)

//  TREASURE_BASE_TYPE_WEAPON_NOAMMO (for any weapon but ammunition)

//  TREASURE_BASE_TYPE_WEAPON_RANGED (for any ranged weapon)

//  TREASURE_BASE_TYPE_WEAPON_MELEE (for any melee weapon)

//  TREASURE_BASE_TYPE_ARMOR (for armor, shields)

//  TREASURE_BASE_TYPE_CLOTHING (for belts, boots, bracers,

//                              cloaks, helms, gloves)

object CTG_GetSpecificBaseTypeTreasureItem(object oBaseCont, int nItemNum, int nBaseType1=BASE_ITEM_INVALID, int nBaseType2=BASE_ITEM_INVALID, int nBaseType3=BASE_ITEM_INVALID);



// Create treasure of the appropriate treasure level and matching one

// of up to three different base types in the specified container.

//

// Possible values for nTreasureType:

//     TREASURE_TYPE_LOW

//     TREASURE_TYPE_MED

//     TREASURE_TYPE_HIGH

//     TREASURE_TYPE_UNIQUE

//

// Possible values for nBaseType1/2/3: any BASE_ITEM_* constant.

//

// If nBaseType1 is passed in as invalid, NO TYPE CHECKING WILL BE DONE.

//

// nBaseType1 may also be passed in as a special custom type,

// which will OVERRIDE any other specified base types:

//

//  TREASURE_BASE_TYPE_WEAPON (for any weapon type)

//  TREASURE_BASE_TYPE_WEAPON_NOAMMO (for any weapon but ammunition)

//  TREASURE_BASE_TYPE_WEAPON_RANGED (for any ranged weapon)

//  TREASURE_BASE_TYPE_WEAPON_MELEE (for any melee weapon)

//  TREASURE_BASE_TYPE_ARMOR (for armor, shields)

//  TREASURE_BASE_TYPE_CLOTHING (for belts, boots, bracers,

//                              cloaks, helms, gloves)

//

void CTG_CreateSpecificBaseTypeTreasure(int nTreasureType, object oAdventurer, object oCont, int nBaseType1=BASE_ITEM_INVALID, int nBaseType2=BASE_ITEM_INVALID, int nBaseType3=BASE_ITEM_INVALID);


// Create gold treasure in the specified container.

void CTG_CreateGoldTreasure(int nTreasureType, object oAdventurer, object oCont=OBJECT_SELF);


// Create treasure on an NPC.

// This function will typically be called from within the

// NPC's OnSpawn handler.

// Note that this defaults to TREASURE_TYPE_MONSTER, which uses

// the monster-specific treasure chests and falls back to low-

// level treasure if none exist.

void CTG_GenerateNPCTreasure(int nTreasureType=5, object oNPC=OBJECT_SELF);


// Check if the item's base type is of the given base type

int CTG_GetIsBaseType(int nItemBaseType, int nBaseType1=BASE_ITEM_INVALID, int nBaseType2=BASE_ITEM_INVALID, int nBaseType3=BASE_ITEM_INVALID);


// Check if the item's base type is a weapon

int CTG_GetIsWeapon(int nItemBaseType);


// Check if the item's base type is a weapon but not ammunition

int CTG_GetIsWeaponNoammo(int nItemBaseType);


// Check if the item's base type is a ranged weapon

int CTG_GetIsRangedWeapon(int nItemBaseType);


// Check if the item's base type is a melee weapon

int CTG_GetIsMeleeWeapon(int nItemBaseType);


// Check if the item's base type is armor

int CTG_GetIsArmor(int nItemBaseType);


// Check if the item's base type is clothing

int CTG_GetIsClothing(int nItemBaseType);


// Tack on the appropriate racialtype suffix

string CTG_GetRacialtypeChestTag(string sBaseTag, object oSource);


/**********************************************************************

 * PRIVATE FUNCTION DEFINITIONS

 * These functions are deliberately not prototyped and not intended

 * for use outside this library.

 **********************************************************************/


// This function deliberately not prototyped. Should not be used

// outside this library.

// Test whether a treasure container has been initialized for

// specific base treasure type use.

int CTG_GetIsContainerInitialized(object oBaseCont)

{

    return GetLocalInt(oBaseCont, "X0_CONTAINER_INITIALIZED");

}


// This function deliberately not prototyped. Should not be used

// outside this library.

// Set whether a treasure container has been initialized for

// specific base treasure type use.

void CTG_SetIsContainerInitialized(object oBaseCont, int bInit=TRUE)

{

    SetLocalInt(oBaseCont, "X0_CONTAINER_INITIALIZED", bInit);

}


// This function deliberately not prototyped. Should not be used

// outside this library.

// Initialize a treasure container to store the items contained

// inside as local variables on the container.

void CTG_InitContainer(object oBaseCont)

{

    // don't do this twice

    if (CTG_GetIsContainerInitialized(oBaseCont)) {return;}


    // initialize

    int nItems = CTG_GetNumItemsInBaseContainer(oBaseCont);


    int i;

    object oTmp = OBJECT_INVALID;

    oTmp = GetFirstItemInInventory(oBaseCont);

    for (i=0; i < nItems && GetIsObjectValid(oTmp); i++) {

        // Store the item and its base type as local vars on

        // the container object itself.

        string sIndex = IntToString(i);

        string sVar = sBaseTypeVarname + sIndex;

        SetLocalInt(oBaseCont, sVar, GetBaseItemType(oTmp));

        sVar = sTreasureItemVarname + sIndex;

        SetLocalObject(oBaseCont, sVar, oTmp);


        oTmp = GetNextItemInInventory(oBaseCont);

    }


    // mark as initialized

    CTG_SetIsContainerInitialized(oBaseCont);

}



/**********************************************************************

 * FUNCTION DEFINITIONS

 **********************************************************************/


// Get the number of items to generate

// Returns an integer from 1-3, probabilities

// determined by the values of the constants

// TREASURE_PROBABILITY_1 & _2.

int CTG_GetNumItems()

{

    int nRoll = d100();


    if (nRoll < TREASURE_PROBABILITY_1) {

        return 1;

    } else if (nRoll < (TREASURE_PROBABILITY_1 + TREASURE_PROBABILITY_2)) {

        return 2;

    }

    return 3;

}



// Get the number of items in a base container

int CTG_GetNumItemsInBaseContainer(object oBaseCont)

{

    int nItems = GetLocalInt(oBaseCont, sNumTreasureItemsVarname);

    if (nItems != 0) {

        return nItems;

    }


    // Haven't initialized the number of items yet

    object oTmp = GetFirstItemInInventory(oBaseCont);

    while (GetIsObjectValid(oTmp)) {

        nItems++;

        oTmp = GetNextItemInInventory(oBaseCont);

    }

    SetLocalInt(oBaseCont, sNumTreasureItemsVarname, nItems);

    return nItems;

}



// Determine whether an item should actually just be gold.

// Returns TRUE or FALSE.

// Probability controlled by constant TREASURE_GOLD_PROBABILITY

int CTG_IsItemGold()

{

    int nRoll = d100();

    if (nRoll < TREASURE_GOLD_PROBABILITY)

        return TRUE;

    return FALSE;

}


int GetIsInteger(string sChar)

{

    return (sChar == "0"

            || sChar == "1"

            || sChar == "2"

            || sChar == "3"

            || sChar == "4"

            || sChar == "5"

            || sChar == "6"

            || sChar == "7"

            || sChar == "8"

            || sChar == "9");

}


// Find and return the right monster container, if

// available.

object CTG_GetMonsterBaseContainer(object oSource=OBJECT_SELF)

{

    object oCont = OBJECT_INVALID;

    string sContTag = "";


    // For monster treasure, we first check for

    // a chest with a tag matching the specific

    // monster.

    // We strip numbers off the end of the tag first

    string sCreatureTag = GetTag(oSource);

    while ( GetIsInteger(GetStringRight(sCreatureTag, 1)) ) {

        sCreatureTag = GetStringLeft(sCreatureTag,

                                     GetStringLength(sCreatureTag)-1);

    }


    sContTag = sContMonster + "_" + sCreatureTag;

    oCont = GetObjectByTag(sContTag);

    if (GetIsObjectValid(oCont)) {

        return oCont;

    }


    // Didn't find that -- check for a chest for the

    // appropriate racialtype.

    sContTag = CTG_GetRacialtypeChestTag(sContMonster, oSource);

    oCont = GetObjectByTag(sContTag);

    if (GetIsObjectValid(oCont)) {

        return oCont;

    }


    // Didn't find that -- check for a module-wide

    // monster chest

    oCont = GetObjectByTag(sContMonster);

    return oCont;

}



// Locate the nearest base container of the appropriate type.

// Possible values for nTreasureType:

//     TREASURE_TYPE_MONSTER

//     TREASURE_TYPE_LOW

//     TREASURE_TYPE_MED

//     TREASURE_TYPE_HIGH

//     TREASURE_TYPE_UNIQUE

object CTG_GetNearestBaseContainer(int nTreasureType,

                                   object oSource=OBJECT_SELF)

{

    object oCont = OBJECT_INVALID;

    int nType = nTreasureType;

    string sContTag = "";


    if (nType == TREASURE_TYPE_MONSTER) {

        oCont = CTG_GetMonsterBaseContainer(oSource);

        if (GetIsObjectValid(oCont))

            return oCont;


        // no monster-specific treasure set up

        nType = TREASURE_TYPE_LOW;

    }


    if (nType == TREASURE_TYPE_LOW) {

        sContTag = sContLow;

    } else if (nType == TREASURE_TYPE_MED) {

        sContTag = sContMed;

    } else if (nType == TREASURE_TYPE_HIGH) {

        sContTag = sContHigh;

    } else if (nType == TREASURE_TYPE_UNIQUE) {

        sContTag = sContUniq;

    } else {

        // Invalid treasure type

        return oCont;

    }


    oCont = GetNearestObjectByTag(sContTag);

    if (!GetIsObjectValid(oCont)) {

        // No area chest -- return the module-wide one

        return CTG_GetModuleBaseContainer(nType);

    }

    return oCont;

}


// Get the module-wide base container of the appropriate type.

// Possible values for nTreasureType:

//     TREASURE_TYPE_LOW

//     TREASURE_TYPE_MED

//     TREASURE_TYPE_HIGH

//     TREASURE_TYPE_UNIQUE

object CTG_GetModuleBaseContainer(int nTreasureType)

{

    object oCont = OBJECT_INVALID;

    string sContTag = "";


    if (nTreasureType == TREASURE_TYPE_LOW) {

        sContTag = sModContLow;

    } else if (nTreasureType == TREASURE_TYPE_MED) {

        sContTag = sModContMed;

    } else if (nTreasureType == TREASURE_TYPE_HIGH) {

        sContTag = sModContHigh;

    } else if (nTreasureType == TREASURE_TYPE_UNIQUE) {

        sContTag = sModContUniq;

    } else {

        // Invalid treasure type

        return oCont;

    }


    oCont = GetObjectByTag(sContTag);

    return oCont;

}



// Generate treasure using default method.

// Not prototyped -- this function should not be used outside

// this library.

void CTG_CreateDefaultTreasure(int nTreasureType, object oAdventurer, object oCont)

{

    // generate treasure using default method from nw_o2_coninclude

    if (nTreasureType == TREASURE_TYPE_LOW) {

        GenerateLowTreasure(oAdventurer, oCont);

    } else if (nTreasureType == TREASURE_TYPE_MED) {

        GenerateMediumTreasure(oAdventurer, oCont);

    } else if (nTreasureType == TREASURE_TYPE_HIGH) {

        GenerateHighTreasure(oAdventurer, oCont);

    } else if (nTreasureType == TREASURE_TYPE_UNIQUE) {

        GenerateBossTreasure(oAdventurer, oCont);

    }

}


// Get the specified item out of the given base container's inventory

object CTG_GetTreasureItem(object oBaseCont, int nItemNum)

{

    if (!GetIsObjectValid(oBaseCont)) {return OBJECT_INVALID;}


    // initialize the container -- this will automatically

    // only happen once.

    CTG_InitContainer(oBaseCont);


    // Refs to the items are stored on the container itself

    string sVar = sTreasureItemVarname + IntToString(nItemNum);

    return GetLocalObject(oBaseCont, sVar);

}


// Starting from the specified item position, return the first

// item that matches one of the three base types.

// If nBaseType1 is passed in as invalid, NO TYPE CHECKING WILL BE DONE.

// nBaseType1 may also be passed in as a special custom type:

// TREASURE_BASE_TYPE_WEAPON (for any weapon type)

// TREASURE_BASE_TYPE_WEAPON_NOAMMO (for any weapon but ammunition)

// TREASURE_BASE_TYPE_WEAPON_RANGED (for any ranged weapon)

// TREASURE_BASE_TYPE_WEAPON_MELEE (for any melee weapon)

// TREASURE_BASE_TYPE_ARMOR (for armor, shields)

// TREASURE_BASE_TYPE_CLOTHING (for belts, boots, bracers,

//                              cloaks, helms, gloves)

object CTG_GetSpecificBaseTypeTreasureItem(object oBaseCont,

                                           int nItemNum,

                                           int nBaseType1=BASE_ITEM_INVALID,

                                           int nBaseType2=BASE_ITEM_INVALID,

                                           int nBaseType3=BASE_ITEM_INVALID)

{

    if (!GetIsObjectValid(oBaseCont)) {return OBJECT_INVALID;}


    // initialize the container -- this will automatically

    // only happen once.

    CTG_InitContainer(oBaseCont);


    int nRollOverNum = CTG_GetNumItemsInBaseContainer(oBaseCont);


    // If there are no items in the container, no chance of finding a matching one!

    if (nRollOverNum == 0) return OBJECT_INVALID;


    int i;

    string sVar;

    int nItemBaseType;

    int nLooped = 0;

    for (i=nItemNum; i != nItemNum || !nLooped ; i++) {


        // The base type of each item is stored on the container itself

        sVar = sBaseTypeVarname + IntToString(i);

        nItemBaseType = GetLocalInt(oBaseCont, sVar);


        // Check to see if the type matches our desired type.

        if (

            // Check for a weapon

            (nBaseType1 == TREASURE_BASE_TYPE_WEAPON

             &&

             CTG_GetIsWeapon(nItemBaseType))

            ||

            // non-ammo weapon

            (nBaseType1 == TREASURE_BASE_TYPE_WEAPON_NOAMMO

             &&

             CTG_GetIsWeaponNoammo(nItemBaseType))

            ||

            // ranged weapon

            (nBaseType1 == TREASURE_BASE_TYPE_WEAPON_RANGED

             &&

             CTG_GetIsRangedWeapon(nItemBaseType))

            ||

            // melee weapon

            (nBaseType1 == TREASURE_BASE_TYPE_WEAPON_MELEE

             &&

             CTG_GetIsMeleeWeapon(nItemBaseType))

            ||

            // armor

            (nBaseType1 == TREASURE_BASE_TYPE_ARMOR

             &&

             CTG_GetIsArmor(nItemBaseType))

            ||

            // clothing

            (nBaseType1 == TREASURE_BASE_TYPE_CLOTHING

             &&

             CTG_GetIsClothing(nItemBaseType))

            ||

            // other specific item type

            ( CTG_GetIsBaseType(nItemBaseType,

                                nBaseType1,

                                nBaseType2,

                                nBaseType3))

            ) // end of if statement

        {

            // we found a matching item -- return it

            return CTG_GetTreasureItem(oBaseCont, i);

        }


        // Handle the wrap-around case

        if ( (i+1) == nRollOverNum ) {

            // set i back to 0

            i = -1;

            nLooped = 1;

        }

    }


    // No matching item was found -- return null

    return OBJECT_INVALID;

}


// Test if treasure has been generated in the given object

int CTG_GetIsTreasureGenerated(object oCont)

{

    return GetLocalInt(oCont, sTreasureGeneratedVarname);

}


// Set whether treasure has been generated

void CTG_SetIsTreasureGenerated(object oCont, int bGenerated=TRUE)

{

    SetLocalInt(oCont, sTreasureGeneratedVarname, bGenerated);

}


// Create random treasure items of the appropriate type

// in the specified container. Should be called

// by a script on a treasure container.

//

// Possible values for nTreasureType:

//     TREASURE_TYPE_LOW

//     TREASURE_TYPE_MED

//     TREASURE_TYPE_HIGH

//     TREASURE_TYPE_UNIQUE

void CTG_CreateTreasure(int nTreasureType,

                        object oAdventurer,

                        object oCont=OBJECT_SELF)

{

    // To avoid code duplication, this actually just uses the specific

    // version and passes an invalid item type

    CTG_CreateSpecificBaseTypeTreasure(nTreasureType, oAdventurer, oCont);

}




// Create treasure of the appropriate treasure level and matching one

// of up to three different base types in the specified container.

//

// Possible values for nTreasureType:

//     TREASURE_TYPE_LOW

//     TREASURE_TYPE_MED

//     TREASURE_TYPE_HIGH

//     TREASURE_TYPE_UNIQUE

//

// Possible values for nBaseType1/2/3: any BASE_ITEM_* constant.

// Can also use these special values:

//  TREASURE_BASE_TYPE_WEAPON (for any weapon type)

//  TREASURE_BASE_TYPE_WEAPON_NOAMMO (for any weapon but ammunition)

//  TREASURE_BASE_TYPE_WEAPON_RANGED (for any ranged weapon)

//  TREASURE_BASE_TYPE_WEAPON_MELEE (for any melee weapon)

//  TREASURE_BASE_TYPE_ARMOR (for armor, shields)

//  TREASURE_BASE_TYPE_CLOTHING (for belts, boots, bracers,

//                              cloaks, helms, gloves)

//

void CTG_CreateSpecificBaseTypeTreasure(int nTreasureType,

                                        object oAdventurer,

                                        object oCont,

                                        int nBaseType1=BASE_ITEM_INVALID,

                                        int nBaseType2=BASE_ITEM_INVALID,

                                        int nBaseType3=BASE_ITEM_INVALID)

{

    // Prevent duplicate treasure generation

    if (CTG_GetIsTreasureGenerated(oCont)) {return;}

    CTG_SetIsTreasureGenerated(oCont);


    // Locate the base container

    object oBaseCont = CTG_GetNearestBaseContainer(nTreasureType,

                                                   oCont);


    // Make sure we have a valid base container

    if (!GetIsObjectValid(oBaseCont)) {

        // if not, generate treasure using default method

        if (nBaseType1 == BASE_ITEM_BOOK

            || nBaseType1 == BASE_ITEM_SPELLSCROLL)

        {

            // Make book treasure

            GenerateBookTreasure(oAdventurer, oCont);

        } else {

            // Generate default treasure

            CTG_CreateDefaultTreasure(nTreasureType, oAdventurer, oCont);

        }

        return;

    }


    // Get the number of available items

    int nItemsInBaseCont = CTG_GetNumItemsInBaseContainer(oBaseCont);


    // Special case: unique treasure items

    if (nTreasureType == TREASURE_TYPE_UNIQUE) {

        // only give one item and only give it once

        int nRandom = Random(nItemsInBaseCont);


        object oItem;

        if (nBaseType1 == BASE_ITEM_INVALID) {

            // we're not checking base types

            oItem = CTG_GetTreasureItem(oBaseCont, nRandom);

        } else {

            oItem = CTG_GetSpecificBaseTypeTreasureItem(oBaseCont,

                                                        nRandom,

                                                        nBaseType1,

                                                        nBaseType2,

                                                        nBaseType3);

        }


        if (!GetIsObjectValid(oItem)) {

            CTG_CreateDefaultTreasure(nTreasureType, oAdventurer, oCont);

        } else {


            // Copy the item

//            CreateItemOnObject(GetResRef(oItem), oCont);

            // * do an actual copy BK Feb 2003. Less chance of resref errors

            CopyObject(oItem, GetLocation(oItem), oCont);

            // Destroy the original

            DestroyObject(oItem);

        }


        return;

    }


    // Otherwise, we generate 1-3 items, possibly convert some

    // to gold.

    int nItems = CTG_GetNumItems();

    int nItemsCreated = 0;

    object oItem = OBJECT_INVALID;


    // Keep track of items handed out to avoid dupes

    object oItem1 = OBJECT_INVALID;

    object oItem2 = OBJECT_INVALID;


    // Random number -- position of item to hand out

    int nRandom = 0;


    while (nItemsCreated < nItems) {

        nItemsCreated++;

        if (nBaseType1 == BASE_ITEM_INVALID &&  CTG_IsItemGold() )

        {

            CTG_CreateGoldTreasure(nTreasureType, oAdventurer, oCont);

        }

        else

        {

            nRandom = Random(nItemsInBaseCont);


            if (nBaseType1 == BASE_ITEM_INVALID)

            {

                // we're not checking base types

                oItem = CTG_GetTreasureItem(oBaseCont, nRandom);

            }

            else

            {

                oItem = CTG_GetSpecificBaseTypeTreasureItem(oBaseCont,

                                                            nRandom,

                                                            nBaseType1,

                                                            nBaseType2,

                                                            nBaseType3);

            }


            if (!GetIsObjectValid(oItem))

            {

                // Ugh, no matching item found!

                // Bad module designer, no cookie.

                CTG_CreateDefaultTreasure(nTreasureType, oAdventurer, oCont);

            }

            else if ( nItemsCreated > 1 &&

                        (GetTag(oItem) == GetTag(oItem1) || GetTag(oItem) == GetTag(oItem2)) )

            {

                // Ugh, duplicate item. Make gold instead.

                CTG_CreateGoldTreasure(nTreasureType, oAdventurer, oCont);

            }

            else

            {

                // Make the item

                CopyItem(oItem, oCont);

                if (nItemsCreated == 1) {

                    oItem1 = oItem;

                } else {

                    // if this is the third item, it doesn't matter

                    // anyway, so we might as well save the conditional.

                    oItem2 = oItem;

                }

            }

        }

    }

}


// Create gold treasure in the specified container.

void CTG_CreateGoldTreasure(int nTreasureType,

                            object oAdventurer,

                            object oCont=OBJECT_SELF)

{

    // Just use the default generation scripts

    CreateGold(oCont, oAdventurer, nTreasureType);

}



// Create treasure on an NPC.

// This function will typically be called from within the

// NPC's OnSpawn handler.

// Note that this defaults to TREASURE_TYPE_MONSTER, which uses

// the monster-specific treasure chests and falls back to low-

// level treasure if none exist.

void CTG_GenerateNPCTreasure(int nTreasureType=5, object oNPC=OBJECT_SELF)

{


    // Locate the base container

    object oBaseCont = CTG_GetNearestBaseContainer(nTreasureType,

                                                   oNPC);


    // Make sure we have a valid base container

    if (!GetIsObjectValid(oBaseCont)) {

        // if not, generate treasure using default method from

        // nw_o2_coninclude.

        if (nTreasureType == TREASURE_TYPE_MONSTER)

            GenerateNPCTreasure(TREASURE_TYPE_LOW, oNPC);

        else

            GenerateNPCTreasure(nTreasureType, oNPC);

        return;

    }


    // Now we determine whether we put treasure on the NPC

    int nRacialType = GetRacialType(oNPC);

    switch (nRacialType) {

    case RACIAL_TYPE_ANIMAL:

    case RACIAL_TYPE_BEAST:

    case RACIAL_TYPE_MAGICAL_BEAST:

    case RACIAL_TYPE_VERMIN:

        // No treasure, sorry.

        return;

    }


    if (nTreasureType == TREASURE_TYPE_MONSTER) {


        if (d100() < BK_CHANCE_OF_N0_MONSTERTREASURE) {

            return;

        }

    }


    // Otherwise, generate as usual

    CTG_CreateTreasure(nTreasureType, oNPC, oNPC);

}




/**********************************************************************

 * Boring type-checking functions.

 **********************************************************************/



// Check if the item's base type is of the given base type

int CTG_GetIsBaseType(int nItemBaseType,

                            int nBaseType1=BASE_ITEM_INVALID,

                            int nBaseType2=BASE_ITEM_INVALID,

                            int nBaseType3=BASE_ITEM_INVALID)

{

    return ( (nItemBaseType != BASE_ITEM_INVALID)

             && (

                 nItemBaseType == nBaseType1

                 || nItemBaseType == nBaseType2

                 || nItemBaseType == nBaseType3) );

}


// Check if the item's base type is a weapon

int CTG_GetIsWeapon(int nItemBaseType)

{

    return (

            nItemBaseType == BASE_ITEM_ARROW

            || nItemBaseType == BASE_ITEM_BASTARDSWORD

            || nItemBaseType == BASE_ITEM_BATTLEAXE

            || nItemBaseType == BASE_ITEM_BOLT

            || nItemBaseType == BASE_ITEM_BULLET

            || nItemBaseType == BASE_ITEM_CBLUDGWEAPON

            || nItemBaseType == BASE_ITEM_CLUB

            || nItemBaseType == BASE_ITEM_CPIERCWEAPON

            || nItemBaseType == BASE_ITEM_CSLASHWEAPON

            || nItemBaseType == BASE_ITEM_CSLSHPRCWEAP

            || nItemBaseType == BASE_ITEM_DAGGER

            || nItemBaseType == BASE_ITEM_DART

            || nItemBaseType == BASE_ITEM_DIREMACE

            || nItemBaseType == BASE_ITEM_DOUBLEAXE

            || nItemBaseType == BASE_ITEM_GREATAXE

            || nItemBaseType == BASE_ITEM_GREATSWORD

            || nItemBaseType == BASE_ITEM_GRENADE

            || nItemBaseType == BASE_ITEM_HALBERD

            || nItemBaseType == BASE_ITEM_HANDAXE

            || nItemBaseType == BASE_ITEM_HEAVYCROSSBOW

            || nItemBaseType == BASE_ITEM_HEAVYFLAIL

            || nItemBaseType == BASE_ITEM_KAMA

            || nItemBaseType == BASE_ITEM_KATANA

            || nItemBaseType == BASE_ITEM_KUKRI

            || nItemBaseType == BASE_ITEM_LIGHTCROSSBOW

            || nItemBaseType == BASE_ITEM_LIGHTFLAIL

            || nItemBaseType == BASE_ITEM_LIGHTHAMMER

            || nItemBaseType == BASE_ITEM_LIGHTMACE

            || nItemBaseType == BASE_ITEM_LONGBOW

            || nItemBaseType == BASE_ITEM_LONGSWORD

            || nItemBaseType == BASE_ITEM_MORNINGSTAR

            || nItemBaseType == BASE_ITEM_QUARTERSTAFF

            || nItemBaseType == BASE_ITEM_RAPIER

            || nItemBaseType == BASE_ITEM_SCIMITAR

            || nItemBaseType == BASE_ITEM_SCYTHE

            || nItemBaseType == BASE_ITEM_SHORTBOW

            || nItemBaseType == BASE_ITEM_SHORTSPEAR

            || nItemBaseType == BASE_ITEM_SHORTSWORD

            || nItemBaseType == BASE_ITEM_SHURIKEN

            || nItemBaseType == BASE_ITEM_SICKLE

            || nItemBaseType == BASE_ITEM_SLING

            || nItemBaseType == BASE_ITEM_THROWINGAXE

            || nItemBaseType == BASE_ITEM_TWOBLADEDSWORD

            || nItemBaseType == BASE_ITEM_WARHAMMER);

}


// Check if the item's base type is a weapon but not ammunition

int CTG_GetIsWeaponNoammo(int nItemBaseType)

{

    return ( CTG_GetIsWeapon(nItemBaseType)

             && (nItemBaseType != BASE_ITEM_ARROW

                 || nItemBaseType != BASE_ITEM_BOLT

                 || nItemBaseType != BASE_ITEM_BULLET)

             );

}


// Check if the item's base type is a ranged weapon

int CTG_GetIsRangedWeapon(int nItemBaseType)

{

    return (nItemBaseType == BASE_ITEM_DART

            || nItemBaseType == BASE_ITEM_GRENADE

            || nItemBaseType == BASE_ITEM_HEAVYCROSSBOW

            || nItemBaseType == BASE_ITEM_LIGHTCROSSBOW

            || nItemBaseType == BASE_ITEM_LONGBOW

            || nItemBaseType == BASE_ITEM_SHORTBOW

            || nItemBaseType == BASE_ITEM_SHURIKEN

            || nItemBaseType == BASE_ITEM_SLING

            || nItemBaseType == BASE_ITEM_THROWINGAXE);

}


// Check if the item's base type is a melee weapon

int CTG_GetIsMeleeWeapon(int nItemBaseType)

{

    return (

            nItemBaseType == BASE_ITEM_BASTARDSWORD

            || nItemBaseType == BASE_ITEM_BATTLEAXE

            || nItemBaseType == BASE_ITEM_CLUB

            || nItemBaseType == BASE_ITEM_DAGGER

            || nItemBaseType == BASE_ITEM_DIREMACE

            || nItemBaseType == BASE_ITEM_DOUBLEAXE

            || nItemBaseType == BASE_ITEM_GREATAXE

            || nItemBaseType == BASE_ITEM_GREATSWORD

            || nItemBaseType == BASE_ITEM_HALBERD

            || nItemBaseType == BASE_ITEM_HANDAXE

            || nItemBaseType == BASE_ITEM_HEAVYFLAIL

            || nItemBaseType == BASE_ITEM_KAMA

            || nItemBaseType == BASE_ITEM_KATANA

            || nItemBaseType == BASE_ITEM_KUKRI

            || nItemBaseType == BASE_ITEM_LIGHTFLAIL

            || nItemBaseType == BASE_ITEM_LIGHTHAMMER

            || nItemBaseType == BASE_ITEM_LIGHTMACE

            || nItemBaseType == BASE_ITEM_LONGSWORD

            || nItemBaseType == BASE_ITEM_MORNINGSTAR

            || nItemBaseType == BASE_ITEM_QUARTERSTAFF

            || nItemBaseType == BASE_ITEM_RAPIER

            || nItemBaseType == BASE_ITEM_SCIMITAR

            || nItemBaseType == BASE_ITEM_SCYTHE

            || nItemBaseType == BASE_ITEM_SHORTSPEAR

            || nItemBaseType == BASE_ITEM_SHORTSWORD

            || nItemBaseType == BASE_ITEM_SICKLE

            || nItemBaseType == BASE_ITEM_TWOBLADEDSWORD

            || nItemBaseType == BASE_ITEM_WARHAMMER);

}


// Check if the item's base type is armor

int CTG_GetIsArmor(int nItemBaseType)

{

    return (nItemBaseType == BASE_ITEM_ARMOR

            || nItemBaseType == BASE_ITEM_LARGESHIELD

            || nItemBaseType == BASE_ITEM_SMALLSHIELD

            || nItemBaseType == BASE_ITEM_TOWERSHIELD);

}


// Check if the item's base type is clothing

int CTG_GetIsClothing(int nItemBaseType)

{

        return (nItemBaseType == BASE_ITEM_BELT

            || nItemBaseType == BASE_ITEM_BOOTS

            || nItemBaseType == BASE_ITEM_BRACER

            || nItemBaseType == BASE_ITEM_CLOAK

            || nItemBaseType == BASE_ITEM_GLOVES);

}


// Tack on the appropriate racialtype suffix

string CTG_GetRacialtypeChestTag(string sBaseTag, object oSource)

{

    string sCont = sBaseTag + "_";

    switch (GetRacialType(oSource)) {

    case RACIAL_TYPE_INVALID: return "";

    case RACIAL_TYPE_ABERRATION: sCont = sCont + "ABERRATION"; break;

    case RACIAL_TYPE_ANIMAL: sCont = sCont + "ANIMAL"; break;

    case RACIAL_TYPE_BEAST: sCont = sCont + "BEAST"; break;

    case RACIAL_TYPE_CONSTRUCT: sCont = sCont + "CONSTRUCT"; break;

    case RACIAL_TYPE_DRAGON: sCont = sCont + "DRAGON"; break;

    case RACIAL_TYPE_DWARF: sCont = sCont + "DWARF"; break;

    case RACIAL_TYPE_ELEMENTAL: sCont = sCont + "ELEMENTAL"; break;

    case RACIAL_TYPE_ELF: sCont = sCont + "ELF"; break;

    case RACIAL_TYPE_FEY: sCont = sCont + "FEY"; break;

    case RACIAL_TYPE_GIANT: sCont = sCont + "GIANT"; break;

    case RACIAL_TYPE_GNOME: sCont = sCont + "GNOME"; break;

    case RACIAL_TYPE_HALFELF: sCont = sCont + "HALFELF"; break;

    case RACIAL_TYPE_HALFLING: sCont = sCont + "HALFLING"; break;

    case RACIAL_TYPE_HALFORC: sCont = sCont + "HALFORC"; break;

    case RACIAL_TYPE_HUMAN: sCont = sCont + "HUMAN"; break;

    case RACIAL_TYPE_HUMANOID_GOBLINOID: sCont = sCont + "GOBLINOID"; break;

    case RACIAL_TYPE_HUMANOID_MONSTROUS: sCont = sCont + "MONSTROUS"; break;

    case RACIAL_TYPE_HUMANOID_ORC: sCont = sCont + "ORC"; break;

    case RACIAL_TYPE_HUMANOID_REPTILIAN: sCont = sCont + "REPTILIAN"; break;

    case RACIAL_TYPE_MAGICAL_BEAST: sCont = sCont + "MAGICAL_BEAST"; break;

    case RACIAL_TYPE_OUTSIDER: sCont = sCont + "OUTSIDER"; break;

    case RACIAL_TYPE_SHAPECHANGER: sCont = sCont + "SHAPECHANGER"; break;

    case RACIAL_TYPE_UNDEAD: sCont = sCont + "UNDEAD"; break;

    case RACIAL_TYPE_VERMIN: sCont = sCont + "VERMIN"; break;

    }


    return sCont;

}



/*

void main() {}

/* */



G7wbkLc.png


 



 


// OnDeath

// Speeded up no end, when compiling, with seperate Include.

// I have witnessed no errors, so -Working-

// Cleans up all un-droppable items, all ints and all local things when destroyed.

#include "j_inc_ondeath"

//#include "ff_inc_common"


void main()

{

    OnDeath();

}




 


// Include for death, to speed it up.

#include "j_inc_const"

#include "ff_inc_common"

#include "give_custom_exp"

#include "nw_o2_coninclude"


// Returns True if the specific int is there.

//int GetSpawnInCondition(int nCondition, object oTarget=OBJECT_SELF);

// This will destroy the body, if still dead.

void DeathCheck(int FirstTime=TRUE);

// This will delete all things, local things, and un-droppable items, before they fade out.

void DeleteAllThings();

// Used in DeleteAllThings.

void ClearSlot(int iSlotID);

// This is for the spawn in conditions.

//const int NW_FLAG_DEATH_EVENT                     = 0x00020000;


/*int GetSpawnInCondition(int nCondition, object oTarget)

{

    int nPlot = GetLocalInt(oTarget, "NW_GENERIC_MASTER");

    if (nPlot & nCondition)

    {

        return TRUE;

    }

    return FALSE;

} */


void DeathCheck(int FirstTime)

{

    object oSelf = OBJECT_SELF;

    if (!GetIsObjectValid(oSelf)) return;


    if (!FirstTime || GetIsObjectValid(GetArea(oSelf)))// Trying to not crash limbo.

    {

        if(GetIsDead(oSelf) && GetLocalInt(oSelf, "IS_DEAD") > 0)

            {

            DeleteLocalInt(oSelf, "IS_DEAD");

            DeleteAllThings();

            SetIsDestroyable(TRUE, FALSE, FALSE);

            AssignCommand(GetModule(),DestroyObject(oSelf, 0.5));

            }

        else

            DeleteLocalInt(oSelf, "IS_DEAD");

    }

    else

      {

      if (FirstTime) DelayCommand(10.0, DeathCheck(FALSE));

      }

}


void ToBeDestroyed(object oItem)      // Si l'objet n'appartient pas un PC, il est detruit

    {

    if (!GetIsObjectValid(oItem)) return;

    object oPoss = GetItemPossessor(oItem);

    if (GetIsObjectValid(oPoss) && (GetObjectType(oPoss)==OBJECT_TYPE_CREATURE) && GetIsPC(oPoss)) return;

    SetPlotFlag(oItem, FALSE);

    DestroyObject(oItem);

    }


void ClearSlot(int iSlotID)

    {

    object oItem = GetItemInSlot(iSlotID);

    if (GetIsObjectValid(oItem))

        if (!GetDroppableFlag(oItem))

            {SetPlotFlag(oItem, FALSE);DestroyObject(oItem);}

        else

            if (GetPlotFlag(oItem) || Random(8)==1)

                DelayCommand(20.0, ToBeDestroyed(oItem));

            else

                DestroyObject(oItem);


    }


void DeleteAllThings()

{

    // Destroy all equipped slots - 0 to 17

    int iSlotID;

    float fDelay = 19.0+(Random(20)/10.0);

    for (iSlotID = 0; iSlotID < NUM_INVENTORY_SLOTS; iSlotID++)

    {

        ClearSlot(iSlotID);

    }

    // Destroy all inventory items

    object oItem = GetFirstItemInInventory();

    while(oItem!=OBJECT_INVALID)

    {

        if (GetIsObjectValid(oItem))

            {

            if (!GetDroppableFlag(oItem))

                {SetPlotFlag(oItem, FALSE);DestroyObject(oItem);}

            else

//            if (GetPlotFlag(oItem) || Random(4)==1)

                  {

                  DelayCommand(fDelay, ToBeDestroyed(oItem));

                  fDelay += 0.1;

                  }

            }

//            else

//                    ToBeDestroyed(oItem);

        oItem = GetNextItemInInventory();

    }


    // Delete all locals that should exsist, or may exsist, from my AI things.

    DeleteLocalObject(OBJECT_SELF, "TO_ATTACK");

    DeleteLocalObject(OBJECT_SELF, "TO_FLEE");

    DeleteLocalInt(OBJECT_SELF, "NW_GENERIC_DRAGONS_BREATH");

    DeleteLocalInt(OBJECT_SELF, "AI_WING_BUFFET");

    DeleteLocalInt(OBJECT_SELF, "NW_GENERIC_MASTER");

    DeleteLocalInt(OBJECT_SELF, "AI_MORALE");

    DeleteLocalInt(OBJECT_SELF, "AI_INTELLIGENCE");

    DeleteLocalInt(OBJECT_SELF, "AI_HEALING_ALLIES_PERCENT");

    DeleteLocalInt(OBJECT_SELF, "AI_CORPSE_DESTROY_TIME");

    DeleteLocalInt(OBJECT_SELF, "AI_ANIMATIONS");

    DeleteLocalInt(OBJECT_SELF, "ROUNDS_UNTIL_SPELL_TRIGGER_RELEASE");

    DeleteLocalInt(OBJECT_SELF, "AI_SPELL_TRIGGERS");

    DeleteLocalFloat(OBJECT_SELF, "RANGE_TO_MOVE_TO");

    // Time stop has up to 25

    int iCnt = 1;

    int iLast = GetLocalInt(OBJECT_SELF, "TIME_STOP_LAST_1");

    while(iCnt < 25 && iLast != 0)

    {

        DeleteLocalInt(OBJECT_SELF, "TIME_STOP_LAST_" + IntToString(iCnt));

        iCnt++;

        iLast = GetLocalInt(OBJECT_SELF, "TIME_STOP_LAST_" + IntToString(iCnt));

    }

}


int OnDeath()

{

    if( GetLocalInt( OBJECT_SELF, "AlreadyDyingEXP" ) == 1 )

      {

      // Since this is the second, and generally unwanted pass through the

      // death routines, we should return immediately.

      // A second line in the log file will be generated, but no other

      // artifacts will happen besides this.

      return FALSE;

      }


    // Always shout when we are attacked, if not fighting.

    SpeakString("I_WAS_ATTACKED", TALKVOLUME_SILENT_TALK);

    // Speaks the set death speak.

    string sDeathString = GetLocalString(OBJECT_SELF, "AI_TALK_ON_DEATH");

    if(sDeathString != "")

        SpeakString(sDeathString);



    // Sets that we should die. Used in the check.

    SetLocalInt(OBJECT_SELF, "IS_DEAD", TRUE);

    int iHD = GetHitDice(OBJECT_SELF);

    if (iHD<6)  // Destruction Rapide si < lv 6

        {

        DelayCommand(2.0, DeathCheck());

        }

    else

        {

            // We will actually dissapear after 30.0 seconds if not raised.

            int iTime = GetLocalInt(OBJECT_SELF, "AI_CORPSE_DESTROY_TIME");

            if(iTime > 0)

                {

                DelayCommand(IntToFloat(iTime), DeathCheck());

                }

            else

                {

                DelayCommand(2.0*IntToFloat(iHD), DeathCheck());

                }

            // object oKiller = GetLastKiller();

            // SpeakString("[AI] " + GetName(OBJECT_SELF) + " [Area] " + GetName(GetArea(OBJECT_SELF)) + " [Debug] Dead. Checking corpse status in " + IntToString(iTime) + " [Killer] " + GetName(oKiller), TALKVOLUME_SILENT_TALK);

            // WriteTimestampedLogEntry("[AI] " + GetName(OBJECT_SELF) + " [Area] " + GetName(GetArea(OBJECT_SELF)) + " [Debug] Dead. Checking corpse status in " + IntToString(iTime) + " [Killer] " + GetName(oKiller));

        }



    int iDeathEffect = GetLocalInt(OBJECT_SELF, "AI_DEATH_VISUAL_EFFECT");

    if(iDeathEffect > 0)

    {

        ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(iDeathEffect), GetLocation(OBJECT_SELF));

    }

    object oKiller = GetLastKiller();

    string sId = GetLocalString(oKiller,"PWId");

    int Penalite = 0;

    if (sId=="")

        {

        object oMaster = GetMaster(oKiller);

        if (GetIsObjectValid(oMaster))

            {

            int Penalite = 6;

            oKiller = oMaster;

            sId = GetLocalString(oKiller,"PWId");

            }

        }


    if (!GetIsAnim(oKiller))

        {

        if (GetSpawnInCondition(BOSS_MONSTER_SHOUT))

            {

            if (iHD>=20)

                GenerateBossTreasure(oKiller, OBJECT_SELF);

            else

            if (iHD>=10)

                if (Random(4)==1)

                    GenerateBossTreasure(oKiller, OBJECT_SELF);

                else

                    GenerateHighTreasure(oKiller, OBJECT_SELF);

            else

                GenerateMediumTreasure(oKiller, OBJECT_SELF);

            }

        else

          if (iHD>15 && (Random(20)==1))

                GenerateBossTreasure(oKiller, OBJECT_SELF);

        else

           if (Random(20)==1)

                GenerateNPCTreasure(1+Random(3), OBJECT_SELF, oKiller);


        if (sId=="")

            if (GetPlotFlag(oKiller)) sId = "9998";

                else                  sId = "9999";   // NPC Non plot


        int nClass = GetLevelByClass(CLASS_TYPE_COMMONER);

        int nAlign = GetAlignmentGoodEvil(OBJECT_SELF);


        if(nClass > 0 && (nAlign == ALIGNMENT_GOOD || nAlign == ALIGNMENT_NEUTRAL))

            AdjustAlignment(oKiller, ALIGNMENT_EVIL, 5);

        else

          if (nAlign == ALIGNMENT_GOOD && Random(4)==1)

              AdjustAlignment(oKiller, ALIGNMENT_EVIL, 1); // Comme il y a nettement plus de cratures Evil, le fait de tuer une creature GOOD  plus d'impact

          else

              if (GetAlignmentGoodEvil(oKiller) == ALIGNMENT_EVIL)

                 if (nAlign == ALIGNMENT_EVIL && Random(20)==1)

                     AdjustAlignment(oKiller, ALIGNMENT_GOOD, 1);



    // Mise  jour de la base de donnees comptabilisant les monstres tues




        string sTag = GetTag(OBJECT_SELF);

        int iNombre=1, iNombreLv=1;

        if (SQLLocalExecAndFetchDirect("SELECT Nombre,NombreOnLv FROM monster WHERE Id=" + sId + " AND MonsterTag='" + sTag+"'") != SQL_SUCCESS) // This player/CDKey pair doesn't exist yet

            SQLExecDirect("INSERT INTO monster (Id,MonsterTag) VALUES(" + sId + ",'" + sTag + "')");

        else

            {

            iNombre = StringToInt(SQLLocalEatData())+1;

            iNombreLv = StringToInt(SQLLocalEatData())+1;

            SQLExecDirect("UPDATE monster SET Nombre="+IntToString(iNombre)+",NombreOnLv="+IntToString(iNombreLv)+" WHERE Id=" + sId + " AND MonsterTag='" + sTag + "'");

            }


        if( !GetIsPC( OBJECT_SELF ) )

          give_custom_exp( GetLastKiller(), OBJECT_SELF, 0, iNombreLv+Penalite);


        }

    if (GetSpawnInCondition(NW_FLAG_DEATH_EVENT))

        {

        SignalEvent(OBJECT_SELF, EventUserDefined(1007));

        }


    // MobDeath!

    string sRefItem = GetLocalString(OBJECT_SELF, "BossDrop");


    if (sRefItem != "")

        {

        object oItem = MustHaveOneOf(oKiller, sRefItem);

        if (oItem != OBJECT_INVALID) SetLocalObject(oItem, "ats_obj_possessor", oKiller);

        DeleteLocalString(OBJECT_SELF, "BossDrop");

        }


    return TRUE;

}




               
               

               
            


Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #3 on: July 11, 2016, 05:09:03 pm »


               

Yes. That is another one of those nw_02_*  scripts.


 


You either need to go in there and change the loot resrefs then recompile, or use a different loot system.



               
               

               
            

Legacy_paradogz

  • Newbie
  • *
  • Posts: 30
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #4 on: July 11, 2016, 05:35:33 pm »


               

where can I change the loot resrefs in the script ? What do you mean by that ?


I cannot use a different loot system because of how NWN FF is build



               
               

               
            

Legacy_SHOVA

  • Hero Member
  • *****
  • Posts: 893
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #5 on: July 11, 2016, 05:37:08 pm »


               

the x_treasure system will work as you want it to, the problem you are getting is from the nw_o2_coninclude script. In it is all the standard items that will drop in the loot system. My fix was to go through the script and everywhere a resref of some item I didn't want I deleted the resref, and left the ""  for instance, it would have  int nRandom = Random(13) + 1;

                  switch (nRandom)

                  {

                       case 1: sItem = "nw_wbwmsl010"; break;

                       case 2: sItem = "nw_wbwmxh009"; break;

                       case 3: sItem = "nw_wbwmxl009"; break;

                       case 4: sItem = "nw_wblmcl010"; break;

                       case 5: sItem = "nw_wdbmqs008"; break;

                       case 6: sItem = "nw_wswmdg008"; break;

                       case 7: sItem = "nw_wspmka008"; break;

                       case 8: sItem = "nw_waxmhn010"; break;

                       case 9: sItem = "nw_wblmcl011"; break;

                       case 10: sItem = "nw_wdbmqs009"; break;

                       case 11: sItem = "nw_wswmdg009"; break;

                       case 12: sItem = "nw_wspmka009"; break;

                       case 13: sItem = "nw_waxmhn011"; break;

                   }


and I would change it to:


 int nRandom = Random(2) + 1;

                  switch (nRandom)

                  {

                       case 1: sItem = "coin01"; break;

                       case 2: sItem = "coin02"; break;

                      

                   }



               
               

               
            

Legacy_paradogz

  • Newbie
  • *
  • Posts: 30
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #6 on: July 11, 2016, 05:40:01 pm »


               

Thanks for your help, I have to look into that.


Problem is, I dont want any of them so maybe that is going to be a long list ?



               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #7 on: July 11, 2016, 05:42:53 pm »


               

you need to edit and resave every single one of the event scripts in the containers for this solution.


 


and since this is required I doubt this is true


"I cannot use a different loot system because of how NWN FF is build"



               
               

               
            

Legacy_SHOVA

  • Hero Member
  • *****
  • Posts: 893
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #8 on: July 11, 2016, 05:42:55 pm »


               

Just open nw_o2_coninclude and scroll down, whatever is in "something" is the resref of an item. You might want to open a notepad page and go and get all the resrefs of your custom items, and then you can copy paste them into the coninclude script and replace the standard NWN items.


I did not remove everything, I still wanted potions, traps, scrolls, and healing kits to drop.



               
               

               
            

Legacy_paradogz

  • Newbie
  • *
  • Posts: 30
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #9 on: July 11, 2016, 05:49:14 pm »


               

Understood, that is amazing thank you so much for your help


 


These forums are really helpful thanks again friends



               
               

               
            

Legacy_paradogz

  • Newbie
  • *
  • Posts: 30
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #10 on: July 11, 2016, 05:59:17 pm »


               

one last thing :


If I cannot find the tag in nw_o2_coninclude then it is safe to thank the item is not lootable?


 


T9UH3Gw.png



               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #11 on: July 11, 2016, 07:24:32 pm »


               

it is the resref you want not the tag. And to find the correct resref do not edit a copy as you are doing here.


 


instead you should use the little yellow magnifying glass/inspector thingy and click on the blueprint.



               
               

               
            

Legacy_paradogz

  • Newbie
  • *
  • Posts: 30
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #12 on: July 11, 2016, 08:49:16 pm »


               

Ok thanks a lot



               
               

               
            

Legacy_SHOVA

  • Hero Member
  • *****
  • Posts: 893
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #13 on: July 11, 2016, 08:53:42 pm »


               

if the resref is not in con_include, then it won't be generated in addition to the items in the area/module treasure placeables. (I take it from a previous response of yours you are using the x2 treasure system.)


 


If you want certain things to drop, you should put those things in the area/mod treasure chests. If you want other things to sometimes spawn, in addition to what is in the chests, then add those item resrefs in the con_include script.


 


As I said, other than healing kits, thief-tools, gems, scrolls, and potions, my con_include script has no other item resrefs- it was very easy to take those things out, as each treasure item type is listed in the con_include script.


 


Just a tip from someone who has been building in NWN since it came out, organization is your friend! I find it extremely helpful to have several notepad/spreadsheets for each module I build, in this case,  one would be for items, where every item I created is on it, with Tag, and the resref. I also tend to make my Tags the same as my resrefs (others may not agree) but I find there is no future confusion in the scripting when a tag, is the same as the resref of an item. I do the same for placeable objects that have interaction scripts, I also do this for transition triggers and waypoints. Sometimes I even make it further easy to use by breaking the items into several note/spreadsheets- one for crafting items, one for equipable items, one for treasure drops, etc. whatever works, is best


Good Luck!


               
               

               
            

Legacy_KMdS!

  • Sr. Member
  • ****
  • Posts: 364
  • Karma: +0/-0
Prevent mobs form getting loot from the standard palette
« Reply #14 on: July 18, 2016, 05:47:26 pm »


               

I still use NWN FF and use custom loot system, what is it in your implementation that doesn't permit modification?