library GetStockInShop/*
==================================================================================================
OPTIONAL LIBRARIES: I suggest using one of the 2 libraries below for Timer Recycling,
but if you don't care about efficiency, this system will still work
even without either of the two libraries recommended.
*/ uses /*
*/optional TimerUtilsEx, /*
by Magtheridon96
http://www.hiveworkshop.com/forums/graveyard-418/system-timerutilsex-204500/
*/optional TimerUtils /*
by Vexorian
http://www.wc3c.net/showthread.php?t=101322
==================================================================================================
GetStockInShop v1.02b written by Shadow Flux
This System allows you to get the current stock of an item/unit in a certain shop.
For this system to work, the shop and the item/unit type must first be defined using
Stock.monitor(id, shopUnit, maximumStock, replenishInterval, stockStartDelay)
This system is useful if you want to get the current stock of certain critical items/units
Author's Note:
I used this system to check if a certain shop has Observer Wards to let the
AI skip buying an Observer Ward in its next item-to-purchase list if it
currently has no Stock.
Look in the Demo Trigger Folder for an example and how it use used in GUI
Requires:
Jass New Gen Pack
Struct Stock
API:
*********************************************************************************************
static method monitor takes unit shopUnit, integer id, integer maximumStock, real replenishInterval,
real stockStartDelay returns nothing
- Tells the system to monitor the stock of a certain item/unit type from a certain shopUnit.
*********************************************************************************************
static method get takes unit shopUnit, integer id returns integer
- Returns the current stock of item/unit type in shopUnit
*********************************************************************************************
*/
globals
//To display System Messages, set DEBUG_SYSTEM = true and run in DEBUG MODE (Main Toolbar -> JassHelper -> Debug Mode)
private constant boolean DEBUG_SYSTEM = true
////////////////////////////////////////
private trigger trg = CreateTrigger()
private hashtable ht = InitHashtable()
endglobals
struct Stock
private integer currentStock
private integer maxStock
private real refreshTime
private boolean onStartDelay
debug private unit shop
debug private integer id
static method get takes unit shopUnit, integer id returns integer
return thistype(LoadInteger( ht, GetHandleId(shopUnit), id )).currentStock
endmethod
private static method timerExpire takes nothing returns nothing
local timer t = GetExpiredTimer()
static if LIBRARY_TimerUtilsEx then
local thistype this = GetTimerData(t)
elseif LIBRARY_TimerUtils then
local thistype this = GetTimerData(t)
else
local thistype this = LoadInteger(ht, GetHandleId(t), 0)
endif
set this.currentStock = this.currentStock + 1
if this.currentStock == this.maxStock then
static if LIBRARY_TimerUtilsEx then
call ReleaseTimer(t)
elseif LIBRARY_TimerUtils then
call ReleaseTimer(t)
else
call PauseTimer(t)
call DestroyTimer(t)
endif
else
if this.onStartDelay then
call TimerStart(t, this.refreshTime, true, function thistype.timerExpire)
set this.onStartDelay = false
endif
endif
set t = null
//////////////////////////////////////////////////////////////////////////////////////////
static if DEBUG_SYSTEM then
debug call BJDebugMsg("|cffffcc00GetStockInShop|r: Stock of |cffffcc00" + GetObjectName(this.id)/*
*/+ "|r in |cffffcc00" + GetUnitName(this.shop) + "|r is increased to " + I2S(this.currentStock))
endif
endmethod
private static method onBuy takes nothing returns boolean
local integer idType = GetUnitTypeId(GetSoldUnit())
local thistype this
static if not(LIBRARY_TimerUtilsEx) then
static if not(LIBRARY_TimerUtils) then
local timer t
endif
endif
//Check if the stock sold is unit or item
if idType == 0 then
set idType = GetItemTypeId(GetSoldItem())
endif
set this = LoadInteger( ht, GetHandleId(GetTriggerUnit()), idType )
if this != 0 then
if this.maxStock == this.currentStock then
static if LIBRARY_TimerUtilsEx then
call TimerStart(NewTimerEx(this), this.refreshTime, true, function thistype.timerExpire)
elseif LIBRARY_TimerUtils then
call TimerStart(NewTimerEx(this), this.refreshTime, true, function thistype.timerExpire)
else
set t = CreateTimer()
call SaveInteger(ht, GetHandleId(t), 0, this)
call TimerStart(t, this.refreshTime, true, function thistype.timerExpire)
set t = null
endif
endif
set this.currentStock = this.currentStock - 1
static if DEBUG_SYSTEM then
debug call BJDebugMsg("|cffffcc00GetStockInShop|r: Stock of |cffffcc00" + GetObjectName(this.id)/*
*/+ "|r in |cffffcc00" + GetUnitName(this.shop) + "|r is decreased to " + I2S(this.currentStock))
endif
endif
return false
endmethod
static method monitor takes unit shopUnit, integer stockId, integer maximumStock, real replenishInterval, real stockStartDelay returns nothing
local thistype this = thistype.allocate()
local integer hId = GetHandleId(shopUnit)
static if not(LIBRARY_TimerUtilsEx) then
static if not(LIBRARY_TimerUtils) then
local timer t
endif
endif
//Struct Data
debug set this.id = stockId
debug set this.shop = shopUnit
set this.maxStock = maximumStock
set this.refreshTime = replenishInterval
call SaveInteger(ht, hId, stockId, this)
//Register Shop to Trigger Event to detect when a player has bought from that shop
if not(HaveSavedBoolean(ht, hId, 0)) then
call SaveBoolean(ht, hId, 0, true)
call TriggerRegisterUnitEvent(trg, shopUnit, EVENT_UNIT_SELL_ITEM)
call TriggerRegisterUnitEvent(trg, shopUnit, EVENT_UNIT_SELL)
//////////////////////////////////////////////////////////////////////////////////////////
static if DEBUG_SYSTEM then
debug call BJDebugMsg("|cffffcc00GetStockInShop|r: " + GetUnitName(shopUnit) + " is now being monitored")
endif
endif
//If there is a stockStartDelay
if stockStartDelay > 0 then
set this.onStartDelay = true
set this.currentStock = 0
static if LIBRARY_TimerUtilsEx then
call TimerStart(NewTimerEx(this), stockStartDelay, false, function thistype.timerExpire)
elseif LIBRARY_TimerUtils then
call TimerStart(NewTimerEx(this), stockStartDelay, false, function thistype.timerExpire)
else
set t = CreateTimer()
call SaveInteger(ht, GetHandleId(t), 0, this)
call TimerStart(t, stockStartDelay, false, function thistype.timerExpire)
set t = null
endif
else
set this.currentStock = maximumStock
endif
endmethod
private static method onInit takes nothing returns nothing
call TriggerAddCondition(trg, Condition(function thistype.onBuy))
endmethod
endstruct
endlibrary