Name | Type | is_array | initial_value |
RS_Index | integer | No | |
RS_ItemList_Free | integer | No | |
RS_ItemList_Item | item | Yes | |
RS_ItemList_Link | integer | Yes | |
RS_ItemList_N | integer | No | |
RS_Table_Fallback | location | Yes | |
RS_Table_Item_Count | integer | Yes | |
RS_Table_Item_Type | itemcode | Yes | |
RS_Table_ItemList | integer | Yes | |
RS_Table_N | integer | No | |
RS_Table_Period | real | Yes | |
RS_Table_Region | rect | Yes | |
RS_Table_Timer | real | Yes | |
RS_UPDATE_PERIOD | real | No | 0.00 |
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_RS_Spawn_FuncItemListAdd takes item litem returns nothing
local integer node
// Get free node
if udg_RS_ItemList_Free == udg_RS_ItemList_N then
// New node from top of node heap
set node = udg_RS_ItemList_Free
set udg_RS_ItemList_N = udg_RS_ItemList_N + 1
set udg_RS_ItemList_Free = udg_RS_ItemList_N
else
// Recycle node from free list
set node = udg_RS_ItemList_Free
set udg_RS_ItemList_Free = udg_RS_ItemList_Link[node]
endif
// Prepare node and add to item list
set udg_RS_ItemList_Item[node] = litem
set udg_RS_ItemList_Link[node] = udg_RS_Table_ItemList[udg_RS_Index]
set udg_RS_Table_ItemList[udg_RS_Index] = node
endfunction
function Trig_RS_Spawn_FuncItemListRemove takes integer prev returns nothing
local integer free
// Extract node
if prev == -1 then
// Header reference needs updating
set free = udg_RS_Table_ItemList[udg_RS_Index]
set udg_RS_Table_ItemList[udg_RS_Index] = udg_RS_ItemList_Link[free]
else
// Previous node reference needs updating
set free = udg_RS_ItemList_Link[prev]
set udg_RS_ItemList_Link[prev] = udg_RS_ItemList_Link[free]
endif
// Prepare node and add to free list
set udg_RS_ItemList_Item[free] = null
set udg_RS_ItemList_Link[free] = udg_RS_ItemList_Free
set udg_RS_ItemList_Free = free
endfunction
function Trig_RS_Spawn_FuncCountProcessItems takes nothing returns integer
local integer index = udg_RS_Table_ItemList[udg_RS_Index]
local integer prev = -1
local integer next
local integer count = 0
local item litem
// Process and count list
loop
// Evaluate node
exitwhen index == -1
set next = udg_RS_ItemList_Link[index]
// Process item
set litem = udg_RS_ItemList_Item[index]
if litem == null then
// Item removed so remove from list
call Trig_RS_Spawn_FuncItemListRemove(prev)
elseif GetWidgetLife(litem) < 0.405 then
// Item is dead so clean and remove from list
call RemoveItem(litem)
call Trig_RS_Spawn_FuncItemListRemove(prev)
elseif IsItemOwned(litem) or not RectContainsCoords(udg_RS_Table_Region[udg_RS_Index], GetItemX(litem), GetItemY(litem)) then
// Item moved away from rect so remove from list
call Trig_RS_Spawn_FuncItemListRemove(prev)
else
// Item is counted
set count = count + 1
endif
// Advance list position
set prev = index
set index = next
endloop
// LDLHVRCLR fix
set litem = null
return count
endfunction
function Trig_RS_Spawn_FuncSpawnItem takes nothing returns nothing
// Spawn item
local rect whichRect = udg_RS_Table_Region[udg_RS_Index]
local item litem = CreateItem(udg_RS_Table_Item_Type[udg_RS_Index], GetRandomReal(GetRectMinX(whichRect), GetRectMaxX(whichRect)), GetRandomReal(GetRectMinY(whichRect), GetRectMaxY(whichRect)))
// Evaluate spawned location
if not RectContainsCoords(udg_RS_Table_Region[udg_RS_Index], GetItemX(litem), GetItemY(litem)) then
// Fallback to safe spawn location
call SetItemPositionLoc(litem, udg_RS_Table_Fallback[udg_RS_Index])
endif
// Add to list
call Trig_RS_Spawn_FuncItemListAdd(litem)
// LDLHVRCLR fix
set whichRect = null
set litem = null
endfunction
function Trig_RS_Spawn_FuncSpawnLogic takes integer periods returns nothing
// Get item count
local integer count = Trig_RS_Spawn_FuncCountProcessItems()
// For each period
loop
// Break when all periods done
exitwhen periods <= 0
// Spawn logic
if count < udg_RS_Table_Item_Count[udg_RS_Index] then
// Spawn an item and count it
call Trig_RS_Spawn_FuncSpawnItem()
set count = count + 1
else
// No more spawning needed so break
exitwhen true
endif
// Advance period
set periods = periods - 1
endloop
endfunction
function Trig_RS_Spawn_Actions takes nothing returns nothing
local integer periods
// Advance timer
set udg_RS_Table_Timer[udg_RS_Index] = udg_RS_Table_Timer[udg_RS_Index] + udg_RS_UPDATE_PERIOD * udg_RS_Table_N
// Compute number of periods to schedule
set periods = R2I(udg_RS_Table_Timer[udg_RS_Index] / udg_RS_Table_Period[udg_RS_Index])
// Scheduler logic
if periods > 0 then
// Only schedule if at least 1 period has lapsed
call Trig_RS_Spawn_FuncSpawnLogic(periods)
// Compute unscheduled time (emulated modulus)
set udg_RS_Table_Timer[udg_RS_Index] = udg_RS_Table_Timer[udg_RS_Index] - udg_RS_Table_Period[udg_RS_Index] * periods
endif
// Cycle scheduler index
set udg_RS_Index = ModuloInteger(udg_RS_Index + 1, udg_RS_Table_N)
endfunction
//===========================================================================
function InitTrig_RS_Spawn takes nothing returns nothing
set gg_trg_RS_Spawn = CreateTrigger( )
call TriggerAddAction( gg_trg_RS_Spawn, function Trig_RS_Spawn_Actions )
endfunction