HasAnyItemOfBaseType not working


#1

Sorry if I’m overdoing with the threads today, but I tested it like 50 times and I’m going crazy.

I’m trying to use the HasAnyItemOfBaseType function and it’s not working. The idea is to test whether the mushroom placeable has any mushroom in its inventory (not matter what type of mushroom exactly, as long as it’s “misc small”) and if the function returns false, the placeable is destroyed.

Here’s the breakdown:

So the base item type is definitely misc small

And the object is supposed to destroy itself once its inventory it self (I couldn’t find a function for “if inventory is empty”)

This is placed on the OnClosed event of the placeable and from some reason the object is always destroyed, despite having several misc small mushroom items when I close it.

The script did however work when I used HasItem and specified the tag of the object that should be in the inventory. However I wanted to make this script more general which is why I’m using “HasAnyItemOfBaseType”.

//if the mushroom does not have any mushrooms in its inventory it self-destructs
#include "nw_i0_plot"
#include "nw_o0_itemmaker"

void main()
{
    object oSelf = OBJECT_SELF;
        if (HasAnyItemOfBaseType(BASE_ITEM_MISCSMALL, FALSE, oSelf)==FALSE)
        {
        DestroyObject(oSelf);
        }

}

#2

Looking it up, it looks like this is another case where the Lexicon is missing some vital information. This is HasAnyItemOfBaseType():

HasAnyItemOfBaseType()
//::///////////////////////////////////////////////
//:: HasAnyItemOfBaseType
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
      Returns true if the basetype (and if basetype
      is armor, the AC) matches.
*/
//:://////////////////////////////////////////////
//:: Created By:
//:: Created On:
//:://////////////////////////////////////////////
int HasAnyItemOfBaseType(int nBaseType, int nAC,object oPC)
{
    // * needs to cycle through all inventory items
    // * and compare basetype with AC
    // * will ignore equipped items -- I think
    object oItem =  GetFirstItemInInventory(oPC);
    int bReturnValue = FALSE;
    int bValid = GetIsObjectValid(oItem);

    while (bValid == TRUE)
    {
        // * A base type match!
       if ((GetBaseItemType(oItem) == nBaseType) && (GetIsMagical(oItem)))
       {
          //dbSpeak("318: here");
          if (nBaseType == BASE_ITEM_ARMOR)
          {
            // * does AC match?
            if (nAC == GetItemACValue(oItem))
            {
                bReturnValue = TRUE;
            }
          }
          else
          {
            bReturnValue = TRUE;
          }
       }
           oItem =  GetNextItemInInventory(oPC);
           bValid = GetIsObjectValid(oItem);
    }
    return bReturnValue;
}

So. it looks like this function wasn’t set up for exactly what you are trying to do right now. I think in this case, it’s likely failing at the “GetIsMagical” check, which is a little bit further up in the library and checks for specific itemproperties.

GetIsMagical()
//::///////////////////////////////////////////////
//:: GetIsMagical
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Returns True if item has 'magical' properties

*/
//:://////////////////////////////////////////////
//:: Created By:
//:: Created On:
//:://////////////////////////////////////////////

int GetIsMagical(object oItem)
{
    return   ( (GetItemHasItemProperty(oItem, ITEM_PROPERTY_ENHANCEMENT_BONUS) == TRUE) ||
              (GetItemHasItemProperty(oItem, ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_ALIGNMENT_GROUP) == TRUE) ||
              (GetItemHasItemProperty(oItem, ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_RACIAL_GROUP) == TRUE) ||
              (GetItemHasItemProperty(oItem, ITEM_PROPERTY_ENHANCEMENT_BONUS_VS_ALIGNMENT_GROUP) == TRUE) ||
              (GetItemHasItemProperty(oItem, ITEM_PROPERTY_ATTACK_BONUS) == TRUE)    ||
              (GetItemHasItemProperty(oItem, ITEM_PROPERTY_ATTACK_BONUS_VS_ALIGNMENT_GROUP) == TRUE) ||
              (GetItemHasItemProperty(oItem, ITEM_PROPERTY_ATTACK_BONUS_VS_RACIAL_GROUP) == TRUE) ||
              (GetItemHasItemProperty(oItem, ITEM_PROPERTY_ATTACK_BONUS_VS_SPECIFIC_ALIGNMENT) == TRUE) ||
             (GetItemHasItemProperty(oItem, ITEM_PROPERTY_AC_BONUS) == TRUE ));
}

If what you really want to know is whether the inventory contains any object at all (i.e., “Is the inventory empty?”), though, you can check for whether the first item in the inventory is a valid object:

    if (!GetIsObjectValid(GetFirstItemInInventory(OBJECT_SELF)))
        DestroyObject(OBJECT_SELF);

#3

That’s actually a brilliant use of GetFirstItemInInventory!

:smiley:

(though I’m not exactly sure why HasAnyItemOfBaseType requires an additional magical check; I’ll ignore it for now since my problem is solved!)


#4

That function is not really a general library function. It’s more of a helper for the magic item smith that the itemmaker include was written for. Many of the routines that you find are generally useful, but there are some that are, to varying degrees, specific to bioware’s modules.