globals
// Timing settings for Marketplace inventories.
constant real bj_STOCK_RESTOCK_INITIAL_DELAY = 120
constant real bj_STOCK_RESTOCK_INTERVAL = 30
constant integer bj_STOCK_MAX_ITERATIONS = 20
constant integer bj_MAX_STOCK_ITEM_SLOTS = 11
constant integer bj_MAX_STOCK_UNIT_SLOTS = 11
constant integer bj_MAX_ITEM_LEVEL = 10
// Marketplace vars
trigger bj_stockItemPurchased = null
timer bj_stockUpdateTimer = null
boolean array bj_stockAllowedPermanent
boolean array bj_stockAllowedCharged
boolean array bj_stockAllowedArtifact
integer bj_stockPickedItemLevel = 0
itemtype bj_stockPickedItemType
endglobals
//===========================================================================
// Update the per-class stock limits.
//
function UpdateStockAvailability takes item whichItem returns nothing
local itemtype iType = GetItemType(whichItem)
local integer iLevel = GetItemLevel(whichItem)
// Update allowed type/level combinations.
if (iType == ITEM_TYPE_PERMANENT) then
set bj_stockAllowedPermanent[iLevel] = true
elseif (iType == ITEM_TYPE_CHARGED) then
set bj_stockAllowedCharged[iLevel] = true
elseif (iType == ITEM_TYPE_ARTIFACT) then
set bj_stockAllowedArtifact[iLevel] = true
else
// Not interested in this item type - ignore the item.
endif
endfunction
//===========================================================================
// Find a sellable item of the given type and level, and then add it.
//
function UpdateEachStockBuildingEnum takes nothing returns nothing
local integer iteration = 0
local integer pickedItemId
loop
set pickedItemId = ChooseRandomItemEx(bj_stockPickedItemType, bj_stockPickedItemLevel)
exitwhen IsItemIdSellable(pickedItemId)
// If we get hung up on an entire class/level combo of unsellable
// items, or a very unlucky series of random numbers, give up.
set iteration = iteration + 1
if (iteration > bj_STOCK_MAX_ITERATIONS) then
return
endif
endloop
call AddItemToStock(GetEnumUnit(), pickedItemId, 1, 1)
endfunction
//===========================================================================
function UpdateEachStockBuilding takes itemtype iType, integer iLevel returns nothing
local group g
set bj_stockPickedItemType = iType
set bj_stockPickedItemLevel = iLevel
set g = CreateGroup()
call GroupEnumUnitsOfType(g, "marketplace", null) // This is ugly, yet interesting. I wonder if it works for other game langs too-- It should, at least...
call ForGroup(g, function UpdateEachStockBuildingEnum)
call DestroyGroup(g)
endfunction
//===========================================================================
// Update stock inventory.
//
function PerformStockUpdates takes nothing returns nothing
local integer pickedItemId
local itemtype pickedItemType
local integer pickedItemLevel = 0
local integer allowedCombinations = 0
local integer iLevel
// Give each type/level combination a chance of being picked.
set iLevel = 1
loop
if (bj_stockAllowedPermanent[iLevel]) then
set allowedCombinations = allowedCombinations + 1
if (GetRandomInt(1, allowedCombinations) == 1) then
set pickedItemType = ITEM_TYPE_PERMANENT
set pickedItemLevel = iLevel
endif
endif
if (bj_stockAllowedCharged[iLevel]) then
set allowedCombinations = allowedCombinations + 1
if (GetRandomInt(1, allowedCombinations) == 1) then
set pickedItemType = ITEM_TYPE_CHARGED
set pickedItemLevel = iLevel
endif
endif
if (bj_stockAllowedArtifact[iLevel]) then
set allowedCombinations = allowedCombinations + 1
if (GetRandomInt(1, allowedCombinations) == 1) then
set pickedItemType = ITEM_TYPE_ARTIFACT
set pickedItemLevel = iLevel
endif
endif
set iLevel = iLevel + 1
exitwhen iLevel > bj_MAX_ITEM_LEVEL
endloop
// Make sure we found a valid item type to add.
if (allowedCombinations == 0) then
return
endif
call UpdateEachStockBuilding(pickedItemType, pickedItemLevel)
endfunction
//===========================================================================
// Perform the first update, and then arrange future updates.
//
function StartStockUpdates takes nothing returns nothing
call PerformStockUpdates()
call TimerStart(bj_stockUpdateTimer, bj_STOCK_RESTOCK_INTERVAL, true, function PerformStockUpdates)
endfunction
//===========================================================================
function RemovePurchasedItem takes nothing returns nothing
call RemoveItemFromStock(GetSellingUnit(), GetItemTypeId(GetSoldItem()))
endfunction
//===========================================================================
function InitNeutralBuildings takes nothing returns nothing
local integer iLevel
// Chart of allowed stock items.
set iLevel = 0
loop
set bj_stockAllowedPermanent[iLevel] = false
set bj_stockAllowedCharged[iLevel] = false
set bj_stockAllowedArtifact[iLevel] = false
set iLevel = iLevel + 1
exitwhen iLevel > bj_MAX_ITEM_LEVEL
endloop
// Limit stock inventory slots.
call SetAllItemTypeSlots(bj_MAX_STOCK_ITEM_SLOTS)
call SetAllUnitTypeSlots(bj_MAX_STOCK_UNIT_SLOTS)
// Arrange the first update.
set bj_stockUpdateTimer = CreateTimer()
call TimerStart(bj_stockUpdateTimer, bj_STOCK_RESTOCK_INITIAL_DELAY, false, function StartStockUpdates)
// Set up a trigger to fire whenever an item is sold.
set bj_stockItemPurchased = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(bj_stockItemPurchased, Player(PLAYER_NEUTRAL_PASSIVE), EVENT_PLAYER_UNIT_SELL_ITEM, null)
call TriggerAddAction(bj_stockItemPurchased, function RemovePurchasedItem)
endfunction
//***************************************************************************
//*
//* THIS FUNCTION IS GENERALLY USED BY WORLD EDITOR ITSELF WHEN A MAP MAKER
//* TELLS A UNIT TO DROP ITEMS.
//*
//***************************************************************************
function UnitDropItem takes unit inUnit, integer inItemID returns item
local real x
local real y
local real radius = 32
local real unitX
local real unitY
local item droppedItem
if (inItemID == -1) then
return null
endif
set unitX = GetUnitX(inUnit)
set unitY = GetUnitY(inUnit)
set x = GetRandomReal(unitX - radius, unitX + radius)
set y = GetRandomReal(unitY - radius, unitY + radius)
set droppedItem = CreateItem(inItemID, x, y)
call SetItemDropID(droppedItem, GetUnitTypeId(inUnit))
call UpdateStockAvailability(droppedItem) // <- forces this item_type and level to be added to the "stack"
return droppedItem
endfunction