Jump to content

AddStoreItem() fails when there's already a copy of the item in shop or when it is an item with charges

Guest Lambda

Recommended Posts

It seems that the AddStoreItem() action is bugged and fails to add items in certain cases. This can be tested in The Black Pits II with the Illithid merchant. Check out this wiki article which mentions each shop addition that failed. Additions are controlled by OHBHUB.BCS.

It seems from looking at this data that the action fails in either of the following cases:

  • An item with charges and with ITM's "Maximum in stack" field no higher than 1.
  • An item is already in shop. Item quantity won't increase then.

I didn't test if other scenarios make this action fail, didn't test that the above were correctly inferred, and didn't test if RemoveStoreItem() also had bugs. It's possible items with a max stack higher than 1 may be affected too for instance.

The data on the wiki article is reliable though.

Link to comment

If the action is trying to add multiple copies of an item and the store has some instances of that item already, does it restock to that number?

For example, that BP2 script includes AddStoreItem("OHBCONCO","POTN14",5,1) to add five oils of speed to the Concocter's shop at each tier. The store starts with five. If some but not all of those potions have been bought, how many are in the store afterward?

And then I answer my own question. Buy one of those oils, story mode to tier 2 ... store ends up with five oils of speed.

Conclusion: the AddStoreItem(store, item, N, flags) doesn't add N copies of the item to the store. It restocks the store to N copies.

On charged items ... there's no parameter in the action for charges. And exactly what works here is complicated. For example, the AddStoreItem("OHBSDWM","STAF12",10,1) action at the end of tier 2 creates ten staves of power in the shop, each fully charged at 10 and 10 charges respectively. That ... actually, that looks like one for the EE Fixpack. There don't need to be multiple copies of that staff in the shop.

On the other hand, the Greenstone Amulet (or ten) at the end of tier 3 flat out doesn't work. What's the difference? The Staff of Power has charges for its second and third (magical) abilities, but not its first (melee) ability. The Greenstone Amulet has charges for its sole (magical) ability, and the "item vanishes" parameter when those charges are drained.

After more testing ... I'm pretty sure the action fails completely if and only if the item's first ability has multiple charges. Here are the items that you should gain access to in later tiers of BP2 that don't actually get added to the shops:

Tier 1: Rod of Resurrection (five charges intended) to MIM, Rod of Reversal (five charges intended) to MIM.

Tier 3: Greenstone Amulet (ten charges intended) to MIM, Thieves' Hood to HG, White Dragon Scale to HG.

Tier 4: Gargoyle Boots to HG.

Edited by jmerry
More information from testing
Link to comment

the AddStoreItem("OHBSDWM","STAF12",10,1) action at the end of tier 2 creates ten staves of power in the shop, each fully charged at 10 and 10 charges respectively.

It's possible part of the issues encountered through trying to outline what exactly is wrong with this script action are actually "normal" shop behavior with odd combinations of values in the STO and ITM files. If I remember correctly, I've encountered similar shop behavior with ITM "Maximum in stack" >= 2 and STO "Quantity/Charges 1" > ITM "Maximum in stack". (Using Near Infinity naming)

I can't spend the time to test this all myself but I did dig into the shop algorithm recently. Maybe some of that work can help gain you some time separating AddStoreItem and "normal" shop oddities: The adjustITMPrice function and code comments here show how the shop uses various ITM and STO values to calculate the price. When values get into odd combinations, a shop can turn a stack of X items into X stacks of X items, among other things, without involvement from AddStoreItem.

Link to comment

For the X thing at the end, I'm saying this from memory. Accurate behavior might be slightly different, but it's definitely possible to duplicate items and I suspect I've seen shops confuse charges and stacks and stock, though some of that may involve the player buying/selling/buying. Sorry it's not more accurate, but point is, beware because you could be testing shop weirdness as you try to outline the AddStoreItem issue. :/

Link to comment
4 hours ago, Guest Lambda said:

It's possible part of the issues encountered through trying to outline what exactly is wrong with this script action are actually "normal" shop behavior with odd combinations of values in the STO and ITM files. If I remember correctly, I've encountered similar shop behavior with ITM "Maximum in stack" >= 2 and STO "Quantity/Charges 1" > ITM "Maximum in stack". (Using Near Infinity naming)

In my testing, I changed that to AddStoreItem("OHBSDWM","STAF12",1,1). That created one fully charged staff. When the function works, that third parameter is always quantity.

I am also aware of the fact that selling something stackable (say, an arrow) to a store that already has stacks of that item for sale restocks a whole stack, allowing for unlimited copies of that item to be generated through repeated buying and selling. And that this can suddenly get less effective if you sell too many of them at once.

That doesn't seem to be the problem here, unless you have something more to report. The charged items that AddStoreItem() fails for aren't stackable, and the stackable items in BP2 that use that action to restock have perfectly predictable behavior (restock to N, rather than adding N).

Link to comment

Ah, I thought you were trying to outline the general use of AddStoreItem for the IESDP description rather than to fix the Black Pits II issue for the EE Fixpack. When creating an item with unusual combinations of "Maximum in stack", ability 1-3 "# charges", "When drained", things happen. With certain combinations of pre-existing STO stock and AddStoreItem parameters, other things happen. Some of those things are "normal" shop oddities, others may be bugs in AddStoreItem, and yet others could be due to AddStoreItem's code path triggering shop oddities that we would not encounter in most AddStoreItem-less shop tests. Good luck testing this all and rounding it up without disassembling the game's executable.

For example if you do AddStoreItem("OHBSDWM", "AROW07", 30, 1), the weapon merchant who previously had one stack of 10 arrows of dispelling will now have 3 stacks of 10 arrows. If however you buy the lone stack before calling the function, you'll get 30 stacks of 1 arrow. If instead you buy the lone stack first, sell 4 arrows back (the store now has 4 stacks of 1 arrow), and only then call the function, all arrows of dispelling vanish from the store.

If you redo the first case in the previous paragraph but with AddStoreItem("OHBSDWM", "AROW07", 33, 1), you'll get 3 stacks of 10 and lose the extra 3 arrows. In the second case you'll get 33 stacks of 1 arrow, losing none. In the third case all arrows are lost again.

Now what happens with AddStoreItem("OHBSDWM", "AROW07", 7, 1)? First case: All arrows vanish! Second case: 6 stacks of 1 arrow, not 7. Third case: All arrows vanish as usual.

An algorithm being deterministic ("perfectly predictable") doesn't make it straightforward to outline from in-game tests unfortunately. I don't know how the IESDP should go about this. Warn that the script action is unreliable, give examples, say there's more, and call it a day?😕

Link to comment

A couple corrections:

The arrows actually don't vanish in case 3 (buy the lone stack of 10, sell 4 arrows, call the function). It looked weird so I just re-checked, it seems that my eyes rolled over them all 3 times lol. So what happens in case 3 is 30 stacks of 1 arrow, then 33 stacks, and finally 7 stacks of 1 arrow. Case 3 is relatively standard when your eyes don't play dumb.

The one valid vanishing case is #1 with AddStoreItem 7. As for the surprising case 2, the 6 arrows instead of 7, I now get all 7. Not sure what's the difference here, I confirmed 6 arrows several times and always made sure AI has plenty of time to finish.

Link to comment

I was trying for both the specific issue of fixing the BP2 store additions and the general issue of clarifying what this action actually does for the IESDP. Thanks for the arrow examples; that's an angle I hadn't looked at, and sheds some more light on things.

And ... checking ... AddStoreItem("OHBIMIM","RODS03",10,1) creates one fully charged (ten charges) rod of resurrection at the Magical Item Merchant.

Another bit to check ... the scripts add some items with the third parameter zero. Potions of superior healing at the end of tier 1, +4 arrows and bolts at the end of tier 3. This one actually results in them becoming available with infinite supply, though the arrows come one at a time instead of in stacks of 40 like the others.


All right, how's this for a revised description?

This action adds "count" instances of the specified item to the store. If the item is already present in the store, it sets the quantity available to "count", increasing or decreasing it as needed. When used with "count" equal to zero, the item is added with an unlimited supply. You can also specify the item flags (such as IDENTIFIED or STOLEN).

Info: This action behaves oddly with charged items, and with stackable items when a stack is already present in the store. There is no parameter to specify charge number, and any items with charges are added to the store fully charged. However, if the item's first ability has a maximum charge number greater than 1, the action adds (count/max charges, rounded down) instances of the item to the store instead of just "count". Similarly, if a stack is already present in the store, the action restocks to (count/stack size, rounded down) instances of the stack.

Link to comment

PR? .... Right, github jargon. And I've never interacted with that system beyond just downloading things; I'm simply not on github at this time.

I had also hoped to get a bit of proofreading/formatting feedback on my suggestion first, before locking this one in. While I'm pretty sure I've got the information that should be there in, I'm not at all sure that I have it phrased right to match the project's style.

Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...