I came across this thread on bugged natives. Both natives in the Jass snippets below are not bugged. In fact all the natives used to add items to marketplaces work fine. You just need to undo Blizzard's forced shop behavior. I couldn't find any posts that explained what's going on in greater detail and offering solutions, so here goes...
The behavior you're seeing is because of Blizzard.j function InitNeutralBuildings. This function is called at map initialization in the function main from InitBlizzard(). It configures all marketplaces to offer items of the same type and level that are dropped by mobs, but only if an item table is setup in the WE for those mobs. If setup through the WE then it calls UnitDropItem automatically, which creates and drops the item and makes sure items of the same type and level are available in future marketplace stock updates.
Only the shops for PLAYER_NEUTRAL_PASSIVE are setup to only have one of each item in stock. There's a trigger for PLAYER_NEUTRAL_PASSIVE that instantly removes the purchased item from the stock after being sold. Hence the item is removed when purchased regardless of the maximum stock available.
A solution to this is to disable the trigger that forces the item to be removed from stock and disable the stock update timer.
in the main function and copy & paste the contents of the function in main and replace the
with your own shop initialization function. For GUI users this last solution will not work since there's no way to change the contents of the main function from within the GUI, other than changing the contents of the map initialization trigger. GUI users could use another player for shops to circumvent this "forced remove sold item" behavior from neutral passive shops. Keep in mind that this only stops the removal of items after a purchase. Marketplaces are still updated with items with item type and level of previously dropped items. Therefore if you're a GUI user you're better of disabling the timer and trigger involved in marketplace stock updating, if you want to have full control over your shop.
I've attached a demo map to try this out. Try the map with and without disabling trigger/timer. You'll see the difference in behavior of the marketplace.
JASS:
AddItemToAllStock
AddUnitToAllStock //No matter how much stock you pass as a parameter, it only counts as 1
JASS:
native AddItemToAllStock takes integer itemId, integer currentStock, integer stockMax returns nothing
native AddItemToAllStock takes integer itemId, integer currentStock, integer stockMax returns nothing
// After adding an item to a neutral building through either of these functions,
// it will cause any units that purchase the item to receive only one of it
// before it is completely removed from the stock. Regardless of the stock
// amount, the item will only remain available in the building for one purchase.
The behavior you're seeing is because of Blizzard.j function InitNeutralBuildings. This function is called at map initialization in the function main from InitBlizzard(). It configures all marketplaces to offer items of the same type and level that are dropped by mobs, but only if an item table is setup in the WE for those mobs. If setup through the WE then it calls UnitDropItem automatically, which creates and drops the item and makes sure items of the same type and level are available in future marketplace stock updates.
Only the shops for PLAYER_NEUTRAL_PASSIVE are setup to only have one of each item in stock. There's a trigger for PLAYER_NEUTRAL_PASSIVE that instantly removes the purchased item from the stock after being sold. Hence the item is removed when purchased regardless of the maximum stock available.
A solution to this is to disable the trigger that forces the item to be removed from stock and disable the stock update timer.
-
Disable Marketplace updates
-
Events
- Map initialization
- Conditions
-
Actions
- -------- Pausing the timer will make sure no more Marketplace stock updates will occur. --------
- Custom script: call PauseTimer(bj_stockUpdateTimer)
- -------- Destroying the timer is optional, but can be done if you want to free a handle index. --------
- Custom script: call DestroyTimer(bj_stockUpdateTimer)
- Custom script: set bj_stockUpdateTimer = null
- -------- Disable the trigger that removes the sold item from the marketplace stock. --------
- -------- Destroying the trigger will free the memory used for the trigger object but will leak the handle ID and triggeraction object. --------
- -------- Therefore destroying the trigger is not recommended since you can't free the associated triggeraction. --------
- Custom script: call DisableTrigger(bj_stockItemPurchased)
- -------- From here on you can do whatever you like to implement your own marketplace behavior. --------
-
Events
JASS:
call InitBlizzard()
JASS:
call InitNeutralBuildings()
I've attached a demo map to try this out. Try the map with and without disabling trigger/timer. You'll see the difference in behavior of the marketplace.