Merchant Script

Could use some help with a merchant script.

If the player that opens the store is level 1 through level 5, then every item in the store gets the item property Attack Bonus +1 added to them.

If the player that opens the store is level 6 through level 10, then every item in the store gets the item property Attack Bonus +2 added to them.

If the player that opens the store is level 11 through level 15, then every item in the store gets the item property Attack Bonus +3 added to them.

etc…

#include "x2_inc_itemprop"

void main()
{
    object oItem;
    object oPC = GetLastOpenedBy();
    int nHitDice = GetHitDice(oPC);
    int nAttackBonus;

    // Determine attack bonus strength:
    if (nHitDice <= 5)
        nAttackBonus = 1;
    else if (nHitDice <= 10)
        nAttackBonus = 2;
    else if (nHitDice <= 15)
        nAttackBonus = 3;
    else
        nAttackBonus = 4;

    // Cycle through the items in the store, apply new property:
    oItem = GetFirstItemInInventory();
    while (oItem != OBJECT_INVALID)
        {
        IPSafeAddItemProperty(oItem, ItemPropertyAttackBonus(nAttackBonus));
        oItem = GetNextItemInInventory();
        }
}
1 Like
#include "x2_inc_itemprop"

int getItemHasLowerAB(object oItem, int nTestValue);
//int getItemHasCorrectType(object oItem);

void main()
{
	object oPC = GetLastOpenedBy();
	int nHitDice = GetHitDice(oPC);
	int nAttackBonus = FloatToInt((nHitDice - 1)/5.) + 1;
	itemproperty ipAB = ItemPropertyAttackBonus(nAttackBonus);

	object oItem = GetFirstItemInInventory();
	while (GetIsObjectValid(oItem))
	{
		if (/* getItemHasCorrectType(oItem) && */ getItemHasLowerAB(oItem, nAttackBonus))
			IPSafeAddItemProperty(oItem, ipAB);

		oItem = GetNextItemInInventory();
	}
}

int getItemHasLowerAB(object oItem, int nTestValue)
{
	int nValue;
	itemproperty ipScan = GetFirstItemProperty(oItem);
	while (GetIsItemPropertyValid(ipScan))
	{
		if (GetItemPropertyType(ipScan) == ITEM_PROPERTY_ATTACK_BONUS
		 && GetItemPropertyDurationType(ipScan) == DURATION_TYPE_PERMANENT)
		{
			nValue = GetItemPropertyCostTableValue(ipScan);
			if (nValue >= nTestValue)
			{
				return FALSE;
			}
		}
		ipScan = GetNextItemProperty(oItem);
	}

	return TRUE;
}

/*
int getItemHasCorrectType(object oItem)
{
	int nPropType = StringToInt(Get2DAString("baseitems", "PropColumn", GetBaseItemType(oItem)));
	// see itemprops.2da, line 56
	if (nPropType <= 3 || nPropType == 14 || nPropType == 15 || nPropType == 21)
	{
		return TRUE;
	}
	return FALSE;
}
*/
2 Likes

In NWScript, the quotient of integer division is also integer - no need here for float + truncate.

int nAttackBonus = (nHitDice - 1) / 5 + 1; // same result
2 Likes

Yeah, I know, that’s why I replaced “5” with “5.”. I just had some doubts about integer division truncating towards zero in NWScript. Thanks for clarifying this question.

1 Like

or round up …

int nAttackBonus = (nHitDice + 4) / 5;
1 Like

You might want to prepare few different stores with different offer and show player the one based on his level instead. The method from @TheBarbarian will work, however it has several issues.

  1. it works only once, if this is multiplayer where multiple players can open the store items will cumulate enhancement bonuses
  2. items won’t have proper name
  3. since items are created this way they will not be “legit” which means that you cannot use features like persistent storage based on resref or “refreshing” items based on resref
2 Likes