HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Spawning System

07-01-2005, 07:09 PM#1
Kolibri
I've made a spawning system.

It works by you make one or more paths at the initialization of the map.
Eg.
Code:
    call Path_createPath( "path0", gg_rct_Region_001, gg_rct_Region_002)
    call Path_appendRect("path0", gg_rct_Region_003 )
    call Path_appendRect("path0", gg_rct_Region_004 )
    call Path_appendRect("path0", gg_rct_Region_005 )

Then when you want to create a spawn unit or unitgroup you call one of the spawn function. And the units are automatically made and ordered to follow the path.
Eg.
Code:
    call Path_createSpawnUnitGroup( 5, 'hfoo', Player(5), "path0" )

Please tell me what you think of it. Do you like it? Is there something I have missed? Are there any memory leaks? Something that could have been done much easier?

Code:
// ------------------ PATH SYSTEM ------------------


function Path_getPath takes unit whichUnit returns string
    return GetStoredString(udg_StoredGameCache, I2S(H2I(whichUnit)), "path")
endfunction

function Path_createPath_CreatedTriggerActions takes nothing returns nothing
    local unit getTriggerUnit = GetTriggerUnit()
    local string pathnameOfUnit = GetStoredString(udg_StoredGameCache, I2S(H2I(getTriggerUnit)), "pathname")
    local rect nextRectOfTheUnit = I2Rect(GetStoredInteger(udg_StoredGameCache, I2S(H2I(getTriggerUnit)), "nextRect"))
    local rect enteredRect = I2Rect(GetStoredInteger(udg_StoredGameCache, I2S(H2I(GetTriggeringTrigger())), "rect"))
    local rect nextRect
    local location nextLoc


    if ( (pathnameOfUnit != null) and (enteredRect == nextRectOfTheUnit)) then
        set nextRect = I2Rect(GetStoredInteger(udg_StoredGameCache, pathnameOfUnit, I2S(H2I(nextRectOfTheUnit))+".nextRect"))
        if (nextRect != null) then 
            set nextLoc = I2Location(GetStoredInteger(udg_StoredGameCache, pathnameOfUnit, I2S(H2I(nextRect))+".centerLoc"))
            call IssuePointOrderLoc( getTriggerUnit, "attack", nextLoc )
            call StoreInteger( udg_StoredGameCache, I2S(H2I(getTriggerUnit)), "nextRect", H2I(nextRect) )
        else
            call IssueImmediateOrderBJ( getTriggerUnit, "stop" )
        endif        
    endif

    
    set getTriggerUnit = null
    set pathnameOfUnit = null
    set nextRectOfTheUnit = null
    set enteredRect = null
    set nextRect = null
    set nextLoc = null
endfunction

function Path_createSpawnUnitAux takes player id, integer unitid, string pathname returns location
    local rect startRect = I2Rect(GetStoredInteger(udg_StoredGameCache, pathname, "startRect"))
    local rect nextRect = I2Rect(GetStoredInteger(udg_StoredGameCache, pathname, I2S(H2I(startRect))+".nextRect"))
    local location startLoc = I2Location(GetStoredInteger(udg_StoredGameCache, pathname, I2S(H2I(startRect))+".centerLoc"))
    local location nextLoc = I2Location(GetStoredInteger(udg_StoredGameCache, pathname, I2S(H2I(nextRect))+".centerLoc"))


    // create spawn unit and store pathname and nextRect for it in gamecache
    set bj_lastCreatedUnit = CreateUnitAtLocSaveLast(id, unitid, startLoc, AngleBetweenPoints(startLoc, nextLoc) )
    // store the unit's path in gamecache.unit.pathname = pathname
    call StoreString( udg_StoredGameCache, I2S(H2I(bj_lastCreatedUnit)), "pathname", pathname )
    // store the unit's nextRect in gamecache.unit.nextRect = nextRect
    call StoreInteger( udg_StoredGameCache, I2S(H2I(bj_lastCreatedUnit)), "nextRect", H2I(nextRect) )


    set startRect = null
    set nextRect = null
    set startLoc = null
    //set nextLoc = null


    return nextLoc
endfunction



// ------ Interface -----

// Creates a path.
// @pathname - the name of the new path.
// @startRect - the start rectangle of the new path.
// @nextRect - the next rectangle of the new path.
function Path_createPath takes string pathname, rect startRect, rect nextRect returns nothing
    local trigger tmp_trigger 


    // set gamecache.pathname.startRect = startRect
    call StoreInteger( udg_StoredGameCache, pathname, "startRect", H2I(startRect) )
    // create and store point for startRect in gamecache.pathname.startRect.centerLoc
    call StoreInteger( udg_StoredGameCache, pathname, I2S(H2I(startRect))+".centerLoc", H2I(GetRectCenter(startRect)) )
    // set gamecache.pathname.startRect.nextRect = nextRect
    call StoreInteger( udg_StoredGameCache, pathname, I2S(H2I(startRect))+".nextRect", H2I(nextRect) )

    // set gamecache.pathname.endRect = nextRect
    call StoreInteger( udg_StoredGameCache, pathname, "endRect", H2I(nextRect) )
    // create and store point for nextRect in gamecache.pathname.endRect.centerLoc
    call StoreInteger( udg_StoredGameCache, pathname, I2S(H2I(nextRect))+".centerLoc", H2I(GetRectCenter(nextRect)) )

    // create trigger to order spawn units entering the nextRect to move forward
    set tmp_trigger = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( tmp_trigger, nextRect )
    call TriggerAddAction( tmp_trigger, function Path_createPath_CreatedTriggerActions )
    // store rectangle for the trigger in gamecache.tmp_trigger.rect
    call StoreInteger( udg_StoredGameCache, I2S(H2I(tmp_trigger)), "rect", H2I(nextRect) )

    
    set tmp_trigger = null
endfunction

// Adds another rectangle at the end of the path.
// @pathname - the name of the path.
// @nextRect - the rectangle to add at the end of the path. WARNING: Don't add a rect which is already in the path.
function Path_appendRect takes string pathname, rect nextRect returns nothing
    local trigger tmp_trigger 
    local rect endRect = I2Rect(GetStoredInteger(udg_StoredGameCache, pathname, "endRect"))


    // set gamecache.pathname.endRect.nextRect = nextRect
    call StoreInteger( udg_StoredGameCache, pathname, I2S(H2I(endRect))+".nextRect", H2I(nextRect) )    

    // set gamecache.pathname.endRect = nextRect
    call StoreInteger( udg_StoredGameCache, pathname, "endRect", H2I(nextRect) )
    // create and store point for nextRect in gamecache.pathname.endRect.centerLoc
    call StoreInteger( udg_StoredGameCache, pathname, I2S(H2I(nextRect))+".centerLoc", H2I(GetRectCenter(nextRect)) )

    // create trigger to order spawn units entering the nextRect to move forward
    set tmp_trigger = CreateTrigger(  )
    call TriggerRegisterEnterRectSimple( tmp_trigger, nextRect )
    call TriggerAddAction( tmp_trigger, function Path_createPath_CreatedTriggerActions )
    // store rectangle for the trigger in gamecache.tmp_trigger.rect
    call StoreInteger( udg_StoredGameCache, I2S(H2I(tmp_trigger)), "rect", H2I(nextRect) )


    set tmp_trigger = null
    set endRect = null
endfunction

// Returns wether or not the unit is a spawn unit. 
// @whichUnit - the unit to check.
// @returns true if the unit is a spawn unit, otherwise false.
function Path_isSpawnUnit2 takes unit whichUnit returns boolean
    return Path_getPath(GetTriggerUnit()) != null
endfunction

// Reorders the spawn unit. Used for re-ordering spawn units that have stopped for some reason. If the unit isn't a spawn unit it won't be re-ordered.
// @whichUnit - the unit to reorder.
// @returns true if the unit is a spawn unit, otherwise false. 
function Path_reorderSpawnUnit takes unit whichUnit returns boolean
    local string pathname = Path_getPath(whichUnit)
    local rect nextRect
    local location nextLoc


    if (pathname == null) then 
        set pathname = null
        return false
    endif

    set nextRect = I2Rect(GetStoredInteger(udg_StoredGameCache, I2S(H2I(whichUnit)), "nextRect"))
    set nextLoc = I2Location(GetStoredInteger(udg_StoredGameCache, pathname, I2S(H2I(nextRect))+".centerLoc"))
    call IssuePointOrderLoc( whichUnit, "attack", nextLoc )


    set pathname = null
    set nextRect = null
    set nextLoc = null
    return true
endfunction

// Creates a unit, registers it as a spawn unit, and orders it to move along the path given.
// @unitid - the id of the unittype of the new unit.
// @id - the id of the owner for the new unit.
// @pathname - which path the spawn unit is ordered to follow.
// @returns the unit created.
function Path_createSpawnUnit takes integer unitid, player id, string pathname returns unit
    local location nextLoc = Path_createSpawnUnitAux(id, unitid, pathname)
    

    call IssuePointOrderLoc( bj_lastCreatedUnit, "attack", nextLoc )    


    set nextLoc = null
    return bj_lastCreatedUnit
endfunction

// Creates a group of unit, registers them as spawn units, and orders them to move along the path given.
// @noOfUnits - the number of units to create.
// @unitid - the id of the unittype of the new units.
// @id - the id of the owner for the new units.
// @pathname - which path the spawn units are ordered to follow.
// @returns a group containing the units. DOES NOT CREATE A UNIT GROUP.
function Path_createSpawnUnitGroup takes integer noOfUnits, integer unitid, player id, string pathname returns group
    local location nextLoc
    call GroupClear(bj_lastCreatedGroup)

    loop
        set noOfUnits = noOfUnits - 1
        exitwhen noOfUnits < 0
        set nextLoc = Path_createSpawnUnitAux(id, unitid, pathname)
        call GroupAddUnit(bj_lastCreatedGroup, bj_lastCreatedUnit)
    endloop

    
    call GroupPointOrderLoc( bj_lastCreatedGroup, "attack", nextLoc )


    set nextLoc = null
    return bj_lastCreatedGroup
endfunction

// ------ End of Interface -----



// ------------------ END OF PATH SYSTEM ------------------