Merchants: How to "Destroy" items sold to Merc;hant
Ugly_Duck
Member Posts: 182
Is there a way to make merchants "destroy" the items players sell to them - making the items sold to the merchant un-buyable because they're removed from the shops inventory?
0
Comments
But if your only motivation was to clear up the merchant's inventory, that could be done by having a merchant shop which sells nothing and then have it erase everything in its inventory every time the shop is closed. Players will still be able to buy objects from the merchant, but only until someone closes their access to the shop.
All merchants which sell things would be set to not buy anything. The player would need to access a different shop in order to sell items.
The OnUnAcquireItem event isn't much help, either, as far as I can see - you can detect that a PC has lost an item, but you can't easily discover whether it was sold or lost in some other way.
So the OnStoreClosed method is probably the only one. There's no way to prevent the PC from buying an item back before the store closes.
It looks to me as though it should be possible to use OnUnAcquireItem, by using GetModuleItemLost() along with GetItemPossessor(). Then use GetObjectType() on the object returned by the last function and if it's a merchant, use DestroyObject() to get rid of the item which was returned by GetModuleItemLost().
Nice idea, but NWScript event functions are surprisingly picky about the exact circumstances in which they will work as expected.
I'd be pretty cautious about destroying items, on refection. Obviously, truly "mission-critical" items should be Plot, to prevent game-breaking mistakes, but there is a grey area of "very useful" items which maybe you don't want to destroy irreversably. I've lost count of the number of times I've sold an item which turns out to be pretty effective against a monster, but can't remember who I sold it to...
// put this in the "OnOpenStore"-event
void main()
{
if (GetLocalInt(OBJECT_SELF, "init_done")) return;
SetLocalInt(OBJECT_SELF, "init_done", 1);
object o = GetFirstItemInInventory(OBJECT_SELF);
while (GetIsObjectValid(o))
{
SetDescription (o, "1", FALSE);
o = GetNextItemInInventory(OBJECT_SELF);
}
}
// put this in the "OnStoreClosed"-event
void main()
{
object o = GetFirstItemInInventory(OBJECT_SELF);
while (GetIsObjectValid(o))
{
string s = GetDescription (o, FALSE, FALSE);
if (s != "1") DestroyObject (o);
o = GetNextItemInInventory(OBJECT_SELF);
}
>> Bracketing the previous script in code markers, and correcting a couple of small mistakes:
Didn't find the button for "bracketing". Now I see one must open the drop down menu at the pilcrow ... Sorry.
The simplest way I found is to use the word "code" enclosed in square braces "[" and "]" just before the code segment and use "/code" (also enclosed in square braces) just after the end. Using the menu options inserts those markers, but I find typing them by hand easier than messing around with menu options. But then again, I touch-type so ymmv.
If all the items you want to keep are marked as infinite, then having this script in the merchant's 'onstoreclosed' event will get rid of anything the PC has just sold to the merchant.
I tried this and it worked great! Thanks friend!