• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

How to re-create/ revive trees after they die?

Status
Not open for further replies.
Ypu mean resurrecting a tree? You can use my GUI-friendly TreeRevive system.

~Uses converted IsDestructableTree by PitzerMike from wc3C.net to get rid of NewGen requirement.

EDIT: Updated - in case I just noticed that Bribe posted shorter version. Even that I catch up the idea about cuting IsDestructableTree into one 'if', my script wans't using 'uloc' (it's much better dummy), but standard 'hfoo' - the first one enables us to omit adding locust ability action. Neat idea.
One mistake Bribe - your unit isn't hidden.
JASS:
//************************************************************************************************
//*                                                                                              *
//*                                Tree Revival System                                           *
//*                                    by Spinnaker                                              *
//*                                                                                              *
//************************************************************************************************



//*************************************************************************
//*
//* Globals required
//*
//*************************************************************************


    //* udg_TreeRevivalTrig                      Trigger for handling the revive actions
    //* udg_TRhash                               Hashtable for timer issues
    //* udg_dummyh                               Dummy harvester for IsDestructibleTree function
    

//* Configurable function for delay before tree gets resurrected     
    constant function TreeReviveDelay takes nothing returns real
        return 5.
    endfunction

//* Tells if birth animation should be shown while resurrecting a tree
    constant function TreeShowAnimation takes nothing returns boolean
        return true
    endfunction

   
//* System itself
function TrCallback takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local destructable d = LoadDestructableHandle(udg_TRhash, GetHandleId(t), 0)
    call DestructableRestoreLife(d, GetDestructableMaxLife(d), TreeShowAnimation())
    call PauseTimer(t)
    call DestroyTimer(t)
    call FlushChildHashtable(udg_TRhash, GetHandleId(t))
    set d = null
    set t = null
endfunction
    
function CallTreeRevive takes nothing returns boolean
    local timer t = CreateTimer()
    call SaveDestructableHandle(udg_TRhash, GetHandleId(t), 0, GetTriggerDestructable())
    call TimerStart(t, TreeReviveDelay(), false, function TrCallback)
    set t = null
    return false
endfunction

function IsDestructableTree takes destructable dest returns boolean
    return IssueTargetOrderById(udg_dummyh, 852018, dest)
endfunction

function CallAddTree takes nothing returns nothing
    if IsDestructableTree(GetEnumDestructable()) then
        call TriggerRegisterDeathEvent(udg_TreeReviveTrig, GetEnumDestructable())
    endif
endfunction

//***************************************************************************
function InitTrig_TreeRevive takes nothing returns nothing
    set udg_TreeReviveTrig = CreateTrigger()
    set udg_TRhash = InitHashtable() 

  //* Actions required for IsDestructibleTree function
    set udg_dummyh = CreateUnit(Player(15), 'uloc', 0., 0., 0.)
    call ShowUnit(udg_dummyh, false)
    call UnitAddAbility(udg_dummyh, 'Ahrl')
    call UnitRemoveAbility(udg_dummyh, 'Amov')

  //* Revival setup
    call EnumDestructablesInRect(bj_mapInitialPlayableArea, null, function CallAddTree)
    call TriggerAddCondition(udg_TreeReviveTrig, Condition(function CallTreeRevive))
endfunction
Test map attached.
 

Attachments

  • TreeRevive.w3x
    26.4 KB · Views: 76
Last edited:
Level 26
Joined
Aug 18, 2009
Messages
4,097
The 64-limit derives from the functions for the bj-event.

JASS:
function RegisterDestDeathInRegionEnum takes nothing returns nothing
    set bj_destInRegionDiesCount = bj_destInRegionDiesCount + 1
    if (bj_destInRegionDiesCount <= bj_MAX_DEST_IN_REGION_EVENTS) then
        call TriggerRegisterDeathEvent(bj_destInRegionDiesTrig, GetEnumDestructable())
    endif
endfunction

function TriggerRegisterDestDeathInRegionEvent takes trigger trig, rect r returns event
    set bj_destInRegionDiesTrig = trig
    set bj_destInRegionDiesCount = 0
    call EnumDestructablesInRect(r, null, function RegisterDestDeathInRegionEnum)
    return trig
endfunction

Enumerating destructables by EnumDestructablesInRect works for more than 64.
 
For a GUI version of the system : Link of Map

  • OneSec Elapsed GT
    • Evénements
      • Temps - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • Destructible - Pick every destructible in (Entire map) and do (Actions)
        • Boucle - Actions
          • Déclencheur - Add to Respawn Tree <gen> the event (Destructible - (Picked destructible) dies)
  • Respawn Tree
    • Evénements
    • Conditions
      • (Destructible-type of (Dying destructible)) Egal à Mur d'arbres d'été
    • Actions
      • Wait 60.00 seconds
      • Destructible - Resurrect (Dying destructible) with (Max life of (Dying destructible)) life and Montrer birth animation
With the pick every detructible, the system works for all trees.
 
Well the issue with enumerating these destructables is that it only
counts 64 destructables. You'd want to divide the map into various
regions so that each region contains less than or equal to 64 trees.
Bribe, everything what you say is fine although 64 limitation happens only if you register destructible death event while refering to given region.

If you enumerate the destructibles on map and than call register death event (picked dest here) everything works fine and function registers '64 <' trees without any problem. Furthermore you can check my test map. There are total of 351 trees (=

Could I post this mini-system on Spells section, or it's too small? =p
 
Level 22
Joined
Nov 14, 2008
Messages
3,256
If you want to post it in the spell section you should either make it run on only one timer or make a timer recycler (because I really dislike that only we doing "vJASS/ZINC/cJASS" have to recycle timers/run on the same timer, you can do it in JASS as well, it's not that difficult, good practice as well - and we also want to increase the standards in the spells section, don't we?). You can either make it somewhat hashindexing with only 1 parentkey and put the trees into the childkeys (to get rid of the flush call all the time, just flush when instances == 0 and also you can use the second parent key for timer recycling so you dont waste hashes if you wanna still do it with a hash) or normal indexing (will require a few more variables though). I'm just curious about the DestroyTimer leak will be if it's 1 timer/tree each time a tree does in a map, let's say DOTA (worst example ever). And if you should completly rip it off you should add the treedead function :p Great anyway.

@Vladadamm

Every single second you register a new event? Nice!
 
Status
Not open for further replies.
Top