Expanded Item Tooltips

Started by LoveLess, July 08, 2023, 09:58:04 PM

Previous topic - Next topic

LoveLess



This is for the script to rename the object. I am unsure how taxing reading 2da's will be when someone's items get converted for the first time. Items will keep any customized name they currently have, this script doesn't ever touch what the object was originally named. It saves it as is.
void main()
{
    object oTarget = GetModuleItemAcquired();
    string sTooltip, sBaseItemType, sPrename, s2daLookup;

    //turn this to FALSE when not testing
    int nFeedback = TRUE;

    if(GetLocalInt(oTarget, "nTooltipName") == FALSE)
        sPrename = GetName(oTarget, FALSE);
    else
        sPrename = GetLocalString(oTarget, "sTooltipPrename");

    itemproperty iprpTarget = GetFirstItemProperty(oTarget);

    // whatever method you use for aspect string name goes here
    // string sAspect;
    // sTooltip += "\n" + sAspect;

    s2daLookup = Get2DAString("baseitems", "Name", GetBaseItemType(oTarget));
    sBaseItemType = GetStringByStrRef(StringToInt(s2daLookup));

    sTooltip += "\n" + "Item Type: " + sBaseItemType;

    float fWeight = IntToFloat(GetWeight(oTarget)) * 0.1f;
    sTooltip += "\n" + "Weight: " + FloatToString(fWeight, 4, 1);

    int nCharges = GetItemCharges(oTarget);
    if(nCharges > 0)
        sTooltip = "\n" + "Charges: " + IntToString(nCharges);

    while(GetIsItemPropertyValid(iprpTarget))
    {
        if(GetItemPropertyDurationRemaining(iprpTarget))
        {
            iprpTarget = GetNextItemProperty(oTarget);
            continue;
        }

        int nType = GetItemPropertyType(iprpTarget);

        switch(nType){
            // additional weight
            case 81 : iprpTarget = GetNextItemProperty(oTarget); continue;
            // secret properties
            case 87 : iprpTarget = GetNextItemProperty(oTarget); continue;
        }

        int nSubtype = GetItemPropertySubType(iprpTarget);
        int nCostTable = GetItemPropertyCostTable(iprpTarget);
        int nCostTableValue = GetItemPropertyCostTableValue(iprpTarget);
        int nParam1 = GetItemPropertyParam1(iprpTarget);
        int nParam1Value = GetItemPropertyParam1Value(iprpTarget);

        string sParam1, sParam1Value, sType, sCostTable, sCostTableValue, sSubtype;
        string sBadstrref = "Bad Strref";

        sType = Get2DAString("ItemProps", "StringRef", nType);

        sSubtype = Get2DAString("itempropdef", "SubTypeResRef", nType);

        sSubtype = Get2DAString(sSubtype, "Name", nSubtype);
        sParam1 = Get2DAString("iprp_paramtable", "TableResRef", nParam1);
        sParam1Value = Get2DAString(sParam1, "Name", nParam1Value);

        sCostTable = Get2DAString("iprp_costtable", "Name", nCostTable);
        sCostTableValue = Get2DAString(sCostTable, "Name", nCostTableValue);

        // formatting for the new string that will be saved
        sTooltip += "\n";
        sTooltip += GetStringByStrRef(StringToInt(sType));

        string sFeedback;
        sFeedback += "nType: " + IntToString(nType) + " = " + GetStringByStrRef(StringToInt(sType)) + "\n";

        if((nSubtype != 255 && nSubtype != 0) ||
           (nParam1Value != 255 && nParam1Value != 0) ||
           (nCostTableValue != 255 && nCostTableValue != 0))
        {
            sTooltip += ": ";

            if(nSubtype != 255)
            {
                string sSubtypestrref = GetStringByStrRef(StringToInt(sSubtype));
                if(FindSubString(sSubtypestrref, sBadstrref, 0) != 0)
                {
                    sTooltip += sSubtypestrref;
                    sTooltip += " ";
                }
            }

            if(nParam1Value != 255 && nParam1Value != 0)
            {
                sTooltip += GetStringByStrRef(StringToInt(sParam1Value));
                sTooltip += " ";
            }

            if(nCostTableValue != 255 && nCostTableValue != 0)
            {
                sTooltip += GetStringByStrRef(StringToInt(sCostTableValue));
            }


            sFeedback += "nSubtype: " + IntToString(nSubtype) + " = " + GetStringByStrRef(StringToInt(sSubtype)) + "\n";
            sFeedback += "nCostTable: " + IntToString(nCostTable) + " = " + GetStringByStrRef(StringToInt(sCostTable)) + "\n";
            sFeedback += "nCostTableValue: " + IntToString(nCostTableValue) + " = " + GetStringByStrRef(StringToInt(sCostTableValue)) + "\n";
            sFeedback += "nParam1: " + IntToString(nParam1) + " = " + GetStringByStrRef(StringToInt(sParam1)) + "\n";
            sFeedback += "nParam1Value: " + IntToString(nParam1Value) + " = " + GetStringByStrRef(StringToInt(sParam1Value));
        }
        //end, loop back with next property
        iprpTarget = GetNextItemProperty(oTarget);

        if(nFeedback == TRUE)
            SendMessageToPC(GetFirstPC(), sFeedback);
    }

    SetLocalInt(oTarget, "nTooltipName", TRUE);
    SetLocalString(oTarget, "sTooltipName", sTooltip);
    SetLocalString(oTarget, "sTooltipPrename", sPrename);

    SetName(oTarget, sPrename + "\n" + sTooltip);

}

You will need a guievent for when someone examines an item, so the name doesn't overflow into the examine window.

void main()
{

    int nEventType = GetLastGuiEventType();
    object oExaminer = GetLastGuiEventPlayer();
    object oTarget = GetLastGuiEventObject();

    string sPrename = GetLocalString(oTarget, "sTooltipPrename");
    string sTooltip = GetLocalString(oTarget, "sTooltipName");

    if(nEventType == GUIEVENT_EXAMINE_OBJECT &&
       GetLocalInt(oTarget, "nTooltipName") == TRUE)
    {
        SetName(oTarget, sPrename);


        DelayCommand(0.3f, AssignCommand(oExaminer, ActionExamine(oTarget)));

        DelayCommand(1.0f, SetName(oTarget, sPrename + "\n" + sTooltip));

    }
}

https://cdn.discordapp.com/attachments/486428345781714950/1117920600770498642/Tooltip_Tester.mod

LoveLess

Forgot to mention the one issue, is that the name will need to get changed before it gets dropped as well. So it will require NWNX's ability to detect when someone is dropping an item before it happens.

LoveLess

A bit of a change from the first script, as it was essentially just a function.

void ExpandItemTooltip(object oTarget )
{
    string sTooltip, sBaseItemType, sPrename, s2daLookup;

    //turn this to FALSE when not testing
    int nFeedback = TRUE;

    if(GetLocalInt(oTarget, "nTooltipName") == FALSE)
        sPrename = GetName(oTarget, FALSE);
    else
        sPrename = GetLocalString(oTarget, "sTooltipPrename");

    itemproperty iprpTarget = GetFirstItemProperty(oTarget);

    // whatever method you use for aspect string name goes here
    // string sAspect;
    // sTooltip += "\n" + sAspect;

    s2daLookup = Get2DAString("baseitems", "Name", GetBaseItemType(oTarget));
    sBaseItemType = GetStringByStrRef(StringToInt(s2daLookup));

    sTooltip += "\n" + "Item Type: " + sBaseItemType;

    float fWeight = IntToFloat(GetWeight(oTarget)) * 0.1f;
    sTooltip += "\n" + "Weight: " + FloatToString(fWeight, 4, 1);

    int nCharges = GetItemCharges(oTarget);
    if(nCharges > 0)
        sTooltip = "\n" + "Charges: " + IntToString(nCharges);

    while(GetIsItemPropertyValid(iprpTarget))
    {
        if(GetItemPropertyDurationRemaining(iprpTarget))
        {
            iprpTarget = GetNextItemProperty(oTarget);
            continue;
        }

        int nType = GetItemPropertyType(iprpTarget);

        switch(nType){
            // additional weight
            case 81 : iprpTarget = GetNextItemProperty(oTarget); continue;
            // secret properties
            case 87 : iprpTarget = GetNextItemProperty(oTarget); continue;
        }

        int nSubtype = GetItemPropertySubType(iprpTarget);
        int nCostTable = GetItemPropertyCostTable(iprpTarget);
        int nCostTableValue = GetItemPropertyCostTableValue(iprpTarget);
        int nParam1 = GetItemPropertyParam1(iprpTarget);
        int nParam1Value = GetItemPropertyParam1Value(iprpTarget);

        string sParam1, sParam1Value, sType, sCostTable, sCostTableValue, sSubtype;
        string sBadstrref = "Bad Strref";

        sType = Get2DAString("ItemProps", "StringRef", nType);

        sSubtype = Get2DAString("itempropdef", "SubTypeResRef", nType);

        sSubtype = Get2DAString(sSubtype, "Name", nSubtype);
        sParam1 = Get2DAString("iprp_paramtable", "TableResRef", nParam1);
        sParam1Value = Get2DAString(sParam1, "Name", nParam1Value);

        sCostTable = Get2DAString("iprp_costtable", "Name", nCostTable);
        sCostTableValue = Get2DAString(sCostTable, "Name", nCostTableValue);

        // formatting for the new string that will be saved
        sTooltip += "\n";
        sTooltip += GetStringByStrRef(StringToInt(sType));

        string sFeedback;
        sFeedback += "nType: " + IntToString(nType) + " = " + GetStringByStrRef(StringToInt(sType)) + "\n";

        if((nSubtype != 255 && nSubtype != 0) ||
           (nParam1Value != 255 && nParam1Value != 0) ||
           (nCostTableValue != 255 && nCostTableValue != 0))
        {
            sTooltip += ": ";

            if(nSubtype != 255)
            {
                string sSubtypestrref = GetStringByStrRef(StringToInt(sSubtype));
                if(FindSubString(sSubtypestrref, sBadstrref, 0) != 0)
                {
                    sTooltip += sSubtypestrref;
                    sTooltip += " ";
                }
            }

            if(nParam1Value != 255 && nParam1Value != 0)
            {
                sTooltip += GetStringByStrRef(StringToInt(sParam1Value));
                sTooltip += " ";
            }

            if(nCostTableValue != 255 && nCostTableValue != 0)
            {
                sTooltip += GetStringByStrRef(StringToInt(sCostTableValue));
            }


            sFeedback += "nSubtype: " + IntToString(nSubtype) + " = " + GetStringByStrRef(StringToInt(sSubtype)) + "\n";
            sFeedback += "nCostTable: " + IntToString(nCostTable) + " = " + GetStringByStrRef(StringToInt(sCostTable)) + "\n";
            sFeedback += "nCostTableValue: " + IntToString(nCostTableValue) + " = " + GetStringByStrRef(StringToInt(sCostTableValue)) + "\n";
            sFeedback += "nParam1: " + IntToString(nParam1) + " = " + GetStringByStrRef(StringToInt(sParam1)) + "\n";
            sFeedback += "nParam1Value: " + IntToString(nParam1Value) + " = " + GetStringByStrRef(StringToInt(sParam1Value));
        }
        //end, loop back with next property
        iprpTarget = GetNextItemProperty(oTarget);

        if(nFeedback == TRUE)
            SendMessageToPC(GetFirstPC(), sFeedback);
    }

    SetLocalInt(oTarget, "nTooltipName", TRUE);
    SetLocalString(oTarget, "sTooltipName", sTooltip);
    SetLocalString(oTarget, "sTooltipPrename", sPrename);

    SetName(oTarget, sPrename + "\n" + sTooltip);

}

LoveLess

// gets their name, even if they have a tooltip
// replaces GetName()
string GetNameExpanded();

string GetNameExpanded()
{
    string sName;

    if(GetLocalInt(oTarget, "nTooltipName") == FALSE)
        sName = GetName(oTarget, FALSE);
    else
        sName = GetLocalString(oTarget, "sTooltipPrename");

   return sName;
}

LoveLess

This was added tentatively to EFU, so if you see any issues or errors with it, please post here so I can try to fix them

This also includes any suggestions regarding it, or what is bad about the design/change.

There's nothing I can do about how wide or tall the box can get, unfortunately. That's always been an issue with long named objects.

Walrus Warwagon

It works for me only in the inventory, when container is opened. In inventory without opened container it doesn't work. It doesn't work on the ground as well. It behaves like this for other people, but for some it works properly and displays the expanded tooltips while item is on the ground.

Any ideas why?

LoveLess

This is because some people are still running 8193.35, which will not show these expanded tooltips in an inventory. If they are on 8193.36, it will show on both the ground and in inventories. They would need to update to the latest version of Enhanced Edition.

LoveLess

//expands tooltip of the selected item
void ExpandItemTooltip(object oTarget);

void ExpandItemTooltip(object oTarget)
{
    string sTooltip, sBaseItemType, s2daLookup, sAspect, sPrename;
    int nAspectID;

    //turn this to FALSE when not testing
    int nFeedback = FALSE;

    if(GetLocalInt(oTarget, "nTooltipName") == FALSE)
        sPrename = GetName(oTarget, FALSE);
    else
        sPrename = GetLocalString(oTarget, "sTooltipPrename");

    if(!JsonGetLength(RegExpMatch("</c>", sPrename))) {
        sPrename = ColorString(sPrename, Orange());
    }

    itemproperty iprpTarget = GetFirstItemProperty(oTarget);

    // base item type
    // moved above aspect to break the color between name/aspect
    // removed extra padding
    s2daLookup = Get2DAString("baseitems", "Name", GetBaseItemType(oTarget));
    sBaseItemType = GetStringByStrRef(StringToInt(s2daLookup));
    sTooltip += "Item Type: " + sBaseItemType;

    if (GetLocalInt(oTarget, "nAspectID"))
    {
        // We want to skip no aspect given and "None" entirely
        if(nAspectID > 1)
        {
            string sAspect = GetAspectName(GetLocalInt(oTarget, "nAspectID"));
            sTooltip += "\n" + sAspect;
        }
    }

    float fWeight = IntToFloat(GetWeight(oTarget)) * 0.1f;
    if(fWeight > 0.1) // dont show weight if it's 0.1 or less
        sTooltip += "\n" + "Weight: " + FloatToString(fWeight, 4, 1);

    int nCharges = GetItemCharges(oTarget);
    if(nCharges > 0)
        sTooltip += "\n" + "Charges: " + IntToString(nCharges);

    while(GetIsItemPropertyValid(iprpTarget))
    {
        if(GetItemPropertyDurationRemaining(iprpTarget))
        {
            iprpTarget = GetNextItemProperty(oTarget);
            continue;
        }

        int nType = GetItemPropertyType(iprpTarget);

        // item types we want to skip and not print to the tooltip
        switch(nType){
            // base item weight reduction
            case 11 : iprpTarget = GetNextItemProperty(oTarget); continue;
            // additional weight
            case 81 : iprpTarget = GetNextItemProperty(oTarget); continue;
            // secret properties
            case 87 : iprpTarget = GetNextItemProperty(oTarget); continue;
        }

        int nSubtype = GetItemPropertySubType(iprpTarget);
        int nCostTable = GetItemPropertyCostTable(iprpTarget);
        int nCostTableValue = GetItemPropertyCostTableValue(iprpTarget);
        int nParam1 = GetItemPropertyParam1(iprpTarget);
        int nParam1Value = GetItemPropertyParam1Value(iprpTarget);

        string sParam1, sParam1Value, sType, sCostTable, sCostTableValue, sSubtype;
        string sBadstrref = "Bad Strref";

        sType = Get2DAString("ItemProps", "StringRef", nType);

        sSubtype = Get2DAString("itempropdef", "SubTypeResRef", nType);

        sSubtype = Get2DAString(sSubtype, "Name", nSubtype);
        sParam1 = Get2DAString("iprp_paramtable", "TableResRef", nParam1);
        sParam1Value = Get2DAString(sParam1, "Name", nParam1Value);

        sCostTable = Get2DAString("iprp_costtable", "Name", nCostTable);
        sCostTableValue = Get2DAString(sCostTable, "Name", nCostTableValue);

        // formatting for the new string that will be saved
        // define exceptions here that you want to rename/alter
        sTooltip += "\n";
        if((nType == 65) ||
           (nType == 64) ||
           (nType == 63))  // only useable by for class, alignment, race
        {
            sTooltip += "Only Useable By";
        }
        else if(nType == 13) // spell slot for classes
        {
            sTooltip += "Bonus Spell Slot";
        }
        else if(nType == 15) // cast spell iprp
        {
            sTooltip += "Use";
        }
        else
        {
            sTooltip += GetStringByStrRef(StringToInt(sType));
        }

        string sFeedback;
        sFeedback += "nType: " + IntToString(nType) + " = " + GetStringByStrRef(StringToInt(sType)) + "\n";

        if((nSubtype != 255) ||
           (nParam1Value != 255) ||
           (nCostTableValue != 255))
        {
            sTooltip += ": ";

            if(nSubtype == 335)
            {
                sTooltip += "Unique Power (Self Only)";
            }
            else if(nSubtype != 255)
            {
                string sSubtypestrref = GetStringByStrRef(StringToInt(sSubtype));
                if(FindSubString(sSubtypestrref, sBadstrref, 0) != 0)
                {
                    sTooltip += sSubtypestrref;
                }

                if(nSubtype == 329)
                    sTooltip += ",";
            }

            if(nParam1Value != 255)
            {
                string sParamstrref = GetStringByStrRef(StringToInt(sParam1Value));
                if(FindSubString(sParamstrref, sBadstrref, 0) != 0)
                {
                    sTooltip += " ";
                    sTooltip += GetStringByStrRef(StringToInt(sParam1Value));
                }
            }

            if(nCostTableValue != 255)
            {
                string sCoststrref = GetStringByStrRef(StringToInt(sCostTableValue));
                if(FindSubString(sCoststrref, sBadstrref, 0) != 0)
                {
                    sTooltip += " ";
                    sTooltip += GetStringByStrRef(StringToInt(sCostTableValue));
                }
            }

            sFeedback += "nSubtype: " + IntToString(nSubtype) + " = " + GetStringByStrRef(StringToInt(sSubtype)) + "\n";
            sFeedback += "nCostTable: " + IntToString(nCostTable) + " = " + GetStringByStrRef(StringToInt(sCostTable)) + "\n";
            sFeedback += "nCostTableValue: " + IntToString(nCostTableValue) + " = " + GetStringByStrRef(StringToInt(sCostTableValue)) + "\n";
            sFeedback += "nParam1: " + IntToString(nParam1) + " = " + GetStringByStrRef(StringToInt(sParam1)) + "\n";
            sFeedback += "nParam1Value: " + IntToString(nParam1Value) + " = " + GetStringByStrRef(StringToInt(sParam1Value));
        }
        //end, loop back with next property
        iprpTarget = GetNextItemProperty(oTarget);

        if(nFeedback == TRUE)
            SendMessageToAllDMs(sFeedback);
    }

    SetObjectTextBubbleOverride(oTarget, OBJECT_UI_TEXT_BUBBLE_OVERRIDE_REPLACE, sPrename + "\n" + sTooltip);

}

Updated with some exceptions and hopefully clean up a lot of the erroneous items that there are currently. Also moved Item Type to be above the aspect of an item, replacing the blank space that used to be there and it looks better there I think. Alternatively can comment it out.

Updated from the one Abala most recently posted to discord.

LoveLess

//expands tooltip of the selected item
void ExpandItemTooltip(object oTarget);

void ExpandItemTooltip(object oTarget)
{
    string sTooltip, sBaseItemType, s2daLookup, sAspect, sPrename;
    int nAspectID;

    int nBaseItemType = GetBaseItemType(oTarget);

    if (nBaseItemType == BASE_ITEM_BLANK_POTION || nBaseItemType == BASE_ITEM_BLANK_SCROLL ||  nBaseItemType == BASE_ITEM_BLANK_WAND
    ||  nBaseItemType == BASE_ITEM_ENCHANTED_POTION || nBaseItemType == BASE_ITEM_ENCHANTED_SCROLL || nBaseItemType == BASE_ITEM_ENCHANTED_WAND
    ||  nBaseItemType == BASE_ITEM_POTIONS || nBaseItemType == BASE_ITEM_SPELLSCROLL || nBaseItemType == BASE_ITEM_MAGICWAND) {
        return;
    }

    //turn this to FALSE when not testing
    int nFeedback = TRUE;

    if(GetLocalInt(oTarget, "nTooltipName") == FALSE)
        sPrename = GetName(oTarget, FALSE);
    else
        sPrename = GetLocalString(oTarget, "sTooltipPrename");

    if(!JsonGetLength(RegExpMatch("</c>", sPrename))) {
        //sPrename = ColorString(sPrename, Orange());
    }

    itemproperty iprpTarget = GetFirstItemProperty(oTarget);

    // base item type
    // moved above aspect to break the color between name/aspect
    // removed extra padding
    s2daLookup = Get2DAString("baseitems", "Name", GetBaseItemType(oTarget));
    sBaseItemType = GetStringByStrRef(StringToInt(s2daLookup));
    sTooltip += sBaseItemType;

    if (GetLocalInt(oTarget, "nAspectID"))
    {
        // We want to skip no aspect given and "None" entirely
        if(nAspectID > 1)
        {
            //string sAspect = GetAspectName(GetLocalInt(oTarget, "nAspectID"));
            sTooltip += "\n" + sAspect;
        }
    }

    float fWeight = IntToFloat(GetWeight(oTarget)) * 0.1f;
    if(fWeight > 0.5) // dont show weight if this or below
        sTooltip += "\n" + "Weight: " + FloatToString(fWeight, 4, 1);

    int nCharges = GetItemCharges(oTarget);
    if(nCharges > 0)
        sTooltip += "\n" + "Charges: " + IntToString(nCharges);

    while(GetIsItemPropertyValid(iprpTarget))
    {
        // if it has a duration, it is only temporary
        if(GetItemPropertyDurationRemaining(iprpTarget))
        {
            iprpTarget = GetNextItemProperty(oTarget);
            continue;
        }

        int nType = GetItemPropertyType(iprpTarget);

        // item types we want to skip and not print to the tooltip
        switch(nType){
            // base item weight reduction
            case 11 : iprpTarget = GetNextItemProperty(oTarget); continue;
            // additional weight
            case 81 : iprpTarget = GetNextItemProperty(oTarget); continue;
            // secret properties
            case 87 : iprpTarget = GetNextItemProperty(oTarget); continue;
        }

        int nSubtype = GetItemPropertySubType(iprpTarget);
        int nCostTable = GetItemPropertyCostTable(iprpTarget);
        int nCostTableValue = GetItemPropertyCostTableValue(iprpTarget);
        int nParam1 = GetItemPropertyParam1(iprpTarget);
        int nParam1Value = GetItemPropertyParam1Value(iprpTarget);

        string sParam1, sParam1Value, sType, sCostTable, sCostTableValue, sSubtype;
        string sBadstrref = "Bad Strref";

        sType = Get2DAString("ItemProps", "StringRef", nType);

        sSubtype = Get2DAString("itempropdef", "SubTypeResRef", nType);

        sSubtype = Get2DAString(sSubtype, "Name", nSubtype);
        sParam1 = Get2DAString("iprp_paramtable", "TableResRef", nParam1);
        sParam1Value = Get2DAString(sParam1, "Name", nParam1Value);

        sCostTable = Get2DAString("iprp_costtable", "Name", nCostTable);
        sCostTableValue = Get2DAString(sCostTable, "Name", nCostTableValue);

        // used for exceptions
        int nSkip = FALSE;

        // formatting for the new string that will be saved
        // define exceptions here that you want to rename/alter
        sTooltip += "\n";
        if((nType == 65) ||
           (nType == 64) ||
           (nType == 63)) 
        {
            // only useable by for class, alignment, race
            sTooltip += "OUB: ";
        }
        else if(nType == 1)
        {
            // armor class bonus
            nSkip = TRUE;
            sTooltip += GetStringByStrRef(StringToInt(sCostTableValue)) + " AC";
        }
        else if(nType == 2 || nType == 3 || nType == 4 || nType == 5)
        {
            // armor class bonus vs specific
            nSkip = TRUE;
            // bonus
            sTooltip += GetStringByStrRef(StringToInt(sCostTableValue)) + " AC";
            // versus what
            sTooltip += " vs. " + GetStringByStrRef(StringToInt(sSubtype));
        }
        else if(nType == 13) // spell slot for classes
        {
            sTooltip += "Spell Slot: ";
        }
        else if(nType == 15  || // cast spell iprp
                nType == 20) // damage immunity
        {
            // do nothing, leave blank
        }
        else if(nType == 37)
        {
            // used for broad immunities like crit, sneak, minda ffecting, etc
            sTooltip += "Immunity: ";
        }
        else if(nType == 40 || nType == 41)
        {
            // saves item property, comment out if you want it gone
            sTooltip += "Save vs. ";
        }
        else if(nType == 52)
        {
            // skills item property, comment out if you want it gone
            //sTooltip += "Skill: ";
        }
        else if(nType == 56)
        {
            // generic Attack Bonus
            nSkip = TRUE;
            sTooltip += GetStringByStrRef(StringToInt(sCostTableValue))  + " Attack Bonus";
        }
        else if(nType == 57 || nType == 58 ||nType == 59)
        {
            // Attack Bonus vs specific
            nSkip = TRUE;
            // bonus
            sTooltip += GetStringByStrRef(StringToInt(sCostTableValue)) + " AB";
            // versus what
            sTooltip += " vs. " + GetStringByStrRef(StringToInt(sSubtype));
        }
        else if(nType == 16)
        {
            // generic damage bonus
            nSkip = TRUE;
            // bonus
            string sDamageBonus = GetStringByStrRef(StringToInt(sCostTableValue));
            sTooltip += "+" + GetSubString(sDamageBonus, 0, FindSubString(sDamageBonus, "Damage"));
            // type
            sTooltip += GetStringByStrRef(StringToInt(sSubtype)) + " Damage";
        }
        else if(nType == 17 || nType == 18 ||nType == 19)
        {
            // specific damage bonus vs

            nSkip = TRUE;
            // bonus
            string sDamageBonus = GetStringByStrRef(StringToInt(sCostTableValue));
            sTooltip += "+" + GetSubString(sDamageBonus, 0, FindSubString(sDamageBonus, "Damage"));
            // type
            sTooltip += GetStringByStrRef(StringToInt(sParam1Value));
            // versus what
            sTooltip += " vs. " + GetStringByStrRef(StringToInt(sSubtype));
        }
        else
        {
            // non exception, print as tlk defines
            sTooltip += GetStringByStrRef(StringToInt(sType));

            if((nSubtype != 255)     ||
               (nParam1Value != 255) ||
               (nCostTableValue != 255) )
            {
                // add to anything with subtypes, excluding exceptions listed above
                sTooltip += ": ";
            }
        }

        string sFeedback;
        sFeedback += "nType: " + IntToString(nType) + " = " + GetStringByStrRef(StringToInt(sType)) + "\n";

        // find values assigned from 2das and tlk
        // this is everything from what alignment vs, to what value, and what spell is used
        if((nSubtype != 255 ||
           nParam1Value != 255 ||
           nCostTableValue != 255)
           && !nSkip)
        {

            if(nSubtype == 335)
            {
                sTooltip += "Unique Power (Self Only)";
            }
            else if(nSubtype != 255)
            {
                string sSubtypestrref = GetStringByStrRef(StringToInt(sSubtype));
                if(FindSubString(sSubtypestrref, sBadstrref, 0) != 0)
                {
                    sTooltip += sSubtypestrref;
                }

                if(nSubtype == 329)
                    sTooltip += "(Use)";
            }

            if(nParam1Value != 255)
            {
                string sParamstrref = GetStringByStrRef(StringToInt(sParam1Value));
                if(FindSubString(sParamstrref, sBadstrref, 0) != 0)
                {
                    sTooltip += " ";
                    sTooltip += sParamstrref;
                }
            }

            if(nCostTableValue != 255)
            {
                string sCoststrref = GetStringByStrRef(StringToInt(sCostTableValue));
                if(FindSubString(sCoststrref, sBadstrref, 0) != 0)
                {
                    sTooltip += " ";
                    sTooltip += sCoststrref;
                }
            }
        }

        sFeedback += "nSubtype: " + IntToString(nSubtype) + " = " + GetStringByStrRef(StringToInt(sSubtype)) + "\n";
        sFeedback += "nCostTable: " + IntToString(nCostTable) + " = " + GetStringByStrRef(StringToInt(sCostTable)) + "\n";
        sFeedback += "nCostTableValue: " + IntToString(nCostTableValue) + " = " + GetStringByStrRef(StringToInt(sCostTableValue)) + "\n";
        sFeedback += "nParam1: " + IntToString(nParam1) + " = " + GetStringByStrRef(StringToInt(sParam1)) + "\n";
        sFeedback += "nParam1Value: " + IntToString(nParam1Value) + " = " + GetStringByStrRef(StringToInt(sParam1Value));     

        if(nFeedback == TRUE)
            //SendMessageToAllDMs(sFeedback);
            SendMessageToPC(GetFirstPC(), sFeedback);

        //end, loop back with next property
        iprpTarget = GetNextItemProperty(oTarget);
    }

    SetObjectTextBubbleOverride(oTarget, OBJECT_UI_TEXT_BUBBLE_OVERRIDE_REPLACE, sPrename + "\n" + sTooltip);
}

Made more exceptions for the longest names I could find like Use, Attack Bonus, Armor Bonus, and Saves. Shorted up skills and more item properties. Will no longer show the weight of items that have a weight 0.5 or less.