Snippet Regrowing Trees

Discussion in 'Systems and Snippets' started by AceHart, Aug 31, 2008.

  1. AceHart

    AceHart Your Friendly Neighborhood Admin

    Ratings:
    +1,489 / 0 / -0
    Regrowing trees... who wouldn't want that?
    I tend to add it even to maps that can't even kill any :p

    Anyway, given it's simple but still annoying to recreate it for every map, I made a library out of that thing.
    Copy&paste to your map, map header for example, done.


    Required edits:
    - "RegrowAfter" is simply the time in seconds it takes a tree until it regrows.


    JASS:
    library REGROWTREES initializer Init
    globals
        private constant real RegrowAfter = 23.0 // seconds to wait until tree regrows
        private unit u
    endglobals
    private function IsTree takes nothing returns boolean
        local boolean b
        call SetUnitX(u, GetWidgetX(GetFilterDestructable()))
        call SetUnitY(u, GetWidgetY(GetFilterDestructable()))
        set b = IssueTargetOrder(u, "harvest", GetFilterDestructable())
        call IssueImmediateOrder(u, "stop")
        return b
    endfunction
    private function Regrow takes nothing returns nothing
        call TriggerSleepAction(RegrowAfter)
        call DestructableRestoreLife(GetDyingDestructable(), GetDestructableMaxLife(GetDyingDestructable()), true)
    endfunction
    private function Register takes nothing returns nothing
        call TriggerRegisterDeathEvent(bj_destInRegionDiesTrig, GetEnumDestructable())
    endfunction
    private function Init takes nothing returns nothing
        set u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'nmpe', 0, 0, 0) // Mur'gul Slave...
        call SetUnitInvulnerable(u, true)
        call ShowUnit(u, false)
        call UnitAddAbility(u, 'Aloc') // Locust
        call UnitAddAbility(u, 'Ahrl') // Harvest Lumber
        set bj_destInRegionDiesTrig = CreateTrigger()
        call EnumDestructablesInRect(bj_mapInitialPlayableArea, Condition(function IsTree), function Register)
        call TriggerAddAction(bj_destInRegionDiesTrig, function Regrow)
        call RemoveUnit(u)
        set u = null
    endfunction
    endlibrary



    Thanks to a brilliant idea by PitzerMike, no tree types or related input is required.
    A tree is any destructible that can be harvested for Lumber.
    Works on custom trees too.


    By popular request, here's a version that waits for all units within a given range of the dead tree to first leave before it attempts to regrow:
    JASS:
    library REGROWTREES initializer Init
    globals
        private constant real RegrowAfter = 23.0 // seconds to wait until tree regrows
        private constant real Range = 250.0      // distance around tree that needs to be free of units before regrowing
        private unit u
        private group g = CreateGroup()
        private boolexpr b
        private boolean ok
    endglobals
    private function IsTree takes nothing returns boolean
        local boolean b
        call SetUnitX(u, GetWidgetX(GetFilterDestructable()))
        call SetUnitY(u, GetWidgetY(GetFilterDestructable()))
        set b = IssueTargetOrder(u, "harvest", GetFilterDestructable())
        call IssueImmediateOrder(u, "stop")
        return b
    endfunction
    private function W2D takes widget w returns destructable
        return w // do not inline
        return null
    endfunction
    private function IsUnitNear takes nothing returns boolean
        if GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.5 then
            set ok = false
        endif
        return false
    endfunction
    private function Regrow takes nothing returns nothing
        local widget t = GetTriggerWidget()
        call TriggerSleepAction(RegrowAfter)
        loop
            set ok = true
            call GroupClear(g)
            call GroupEnumUnitsInRange(g, GetWidgetX(t), GetWidgetY(t), Range, b)
            exitwhen ok
            call TriggerSleepAction(3.0)
        endloop
        call DestructableRestoreLife(W2D(t), GetDestructableMaxLife(W2D(t)), true)
        set t = null
    endfunction
    private function Register takes nothing returns nothing
        call TriggerRegisterDeathEvent(bj_destInRegionDiesTrig, GetEnumDestructable())
    endfunction
    private function Init takes nothing returns nothing
        set u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'nmpe', 0, 0, 0) // Mur'gul Slave...
        call SetUnitInvulnerable(u, true)
        call ShowUnit(u, false)
        call UnitAddAbility(u, 'Aloc') // Locust
        call UnitAddAbility(u, 'Ahrl') // Harvest Lumber
        set bj_destInRegionDiesTrig = CreateTrigger()
        call EnumDestructablesInRect(bj_mapInitialPlayableArea, Condition(function IsTree), function Register)
        call TriggerAddAction(bj_destInRegionDiesTrig, function Regrow)
        set b = Condition(function IsUnitNear)
        call RemoveUnit(u)
        set u = null
    endfunction
    endlibrary


    Usage is still as simple:
    Copy&paste to your map, done.
     
    • Like Like x 3
  2. Prometheus

    Prometheus Everything is mutable; nothing is sacred Staff Member

    Ratings:
    +592 / 0 / -0
    JASS:
        return t == 'VTlt' or t == 'CTtr' or t == 'Cttc' // Edit tree-types as needed


    Shove into the globals block?
     
  3. AceHart

    AceHart Your Friendly Neighborhood Admin

    Ratings:
    +1,489 / 0 / -0
    As what? Or, rather, how you get that type of condition from a list of sorts without the need to loop through it?
     
  4. Prometheus

    Prometheus Everything is mutable; nothing is sacred Staff Member

    Ratings:
    +592 / 0 / -0
    JASS:
    globals
        private constant real RegrowAfter = 23.0 // seconds to wait until tree regrows
        private constant integer TREE1 = 'VTlt'
        private constant integer TREE2 = 'CTtr'
        private constant integer TREE3 = 'Cttc'
        private constant integer TREE4-10 = blah
    endglobals
    private function TreeTypeFilter takes nothing returns boolean
        local integer t = GetDestructableTypeId(GetFilterDestructable())
        return t == TREE1 or t == TREE2 or t == TREE3 or t == TREE4-10
    endfunction


    It'll make it more newbie friendly. And you can do up to 10 and throw in instructions on how to go over 10.
     
  5. AceHart

    AceHart Your Friendly Neighborhood Admin

    Ratings:
    +1,489 / 0 / -0
    Providing a global list doesn't make much sense if you still have to provide the condition yourself.
     
  6. Prometheus

    Prometheus Everything is mutable; nothing is sacred Staff Member

    Ratings:
    +592 / 0 / -0
    You can do the
    JASS:
    return t == TREE1 or t == TREE2 or t == TREE3 or t == TREE4 or t == TREE5 or t == TREE6 or t == TREE7 or t == TREE8 or t == TREE9 or t == TREE10

    Just make it so that users can easily change them.
     
  7. Larcenist

    Larcenist REP: Respect, Envy, Prosperity?

    Ratings:
    +211 / 0 / -0
    Considering this is a 21 line snippet, I'm pretty confident people can locate the 7:th line with the comment "//Edit tree-types as needed".
     
  8. ReVolver

    ReVolver Moderator Staff Member

    Ratings:
    +608 / 0 / -0
    Nice script :thup: I was just wondering if a unit is in the way does it get moved out of the area or does the tree not grow?
     
  9. AceHart

    AceHart Your Friendly Neighborhood Admin

    Ratings:
    +1,489 / 0 / -0
    The trees ALWAYS grow back :p
    In theory, it's possible to end up with a configuration that traps a unit in the middle of a forest.
    Though that's dark theory only, and not "limited" to this script.
     
  10. ReVolver

    ReVolver Moderator Staff Member

    Ratings:
    +608 / 0 / -0
    Oh :p I didn't know because usually I play melee games and the trees never grow back to know what will happen.
     
  11. Romek

    Romek Super Moderator Staff Member

    Ratings:
    +961 / 0 / -0
    You could use this:

    JASS:
    t == 'ATtr' or t=='BTtw'or t=='KTtw' or t=='YTft' or t=='JTct' or t=='YTst' or t=='YTct' or t=='YTwt' or t=='JTwt' or t=='DTsh' or t=='FTtw' or t=='CTtr' or t=='ITtw' or t=='NTtw' or t=='OTtw' or t=='ZTtw' or t=='WTst' or t=='LTlt' or t=='GTsh' or t=='Xtlt' or t=='WTtw' or t=='Attc' or t=='BTtc' or t=='CTtc' or t=='ITtc' or t=='NTtc' or t=='ZTtc'


    And maybe make another function where the user can put in their own trees:
    JASS:
    private function TreeFilterCustom takes nothing returns boolean
        local integer t = GetDestructableTypeId(GetFilterDestructable())
        return false // Remove "false" and put in the Raw codes of custom trees here
    endfunction
    
    private function TreeTypeFilter takes nothing returns boolean
        local integer t = GetDestructableTypeId(GetFilterDestructable())
        return t == 'ATtr' or t=='BTtw'or t=='KTtw' or t=='YTft' or t=='JTct' or t=='YTst' or t=='YTct' or t=='YTwt' or t=='JTwt' or t=='DTsh' or t=='FTtw' or t=='CTtr' or t=='ITtw' or t=='NTtw' or t=='OTtw' or t=='ZTtw' or t=='WTst' or t=='LTlt' or t=='GTsh' or t=='Xtlt' or t=='WTtw' or t=='Attc' or t=='BTtc' or t=='CTtc' or t=='ITtc' or t=='NTtc' or t=='ZTtc' or TreeFilterCustom() 
    endfunction
     
    • Like Like x 1
  12. Matrix

    Matrix New Member

    Ratings:
    +5 / 0 / -0
    I remember that there is a IsDestTree function, try to search on wc3jass.com or hive
     
  13. Matrix

    Matrix New Member

    Ratings:
    +5 / 0 / -0
    JASS:
    //=======================================//
    //Credits to PitzerMike for this function//
    //=======================================//
    
    globals
        private constant integer DUMMY_ID = 'h000'
    endglobals
    
    private function TreeFilter takes nothing returns boolean
        local destructable d = GetFilterDestructable()
        local boolean i = IsDestructableInvulnerable(d)
        local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_ID, GetWidgetX(d), GetWidgetY(d), 0)
        local boolean result = false
    
        call UnitAddAbility(u, 'Ahrl')
    
        if i then
            call SetDestructableInvulnerable(d, false)
        endif
    
        set result = IssueTargetOrder(u, "harvest", d)
        call RemoveUnit(u)
    
        if i then
          call SetDestructableInvulnerable(d, true)
        endif
    
        set u = null
        set d = null
        return result
    endfunction
     
    • Like Like x 1
  14. AceHart

    AceHart Your Friendly Neighborhood Admin

    Ratings:
    +1,489 / 0 / -0
    Updated.
     
  15. Charapanga

    Charapanga New Member

    Ratings:
    +46 / 0 / -0
    Quick noob question:
    How do i copy and paste it to my map?
    And is this for all types of trees?

    (i'm a noob at jass, i know what some mean, not all)
     
  16. TriggerHappy

    TriggerHappy ...

    Ratings:
    +341 / 0 / -0
    1).... Copy it!
    2)Works for all trees.
     
  17. eraserboy

    eraserboy Guest

    Ratings:
    +0 / 0 / -0
    i'm very noob

    sory but... can u explain how to copy to the map? i'm very very noob TT

    in my map.... copy to..... where?

    maybe i should open anything else first ?
    after i opened the map...
    then paste it....

    thx..
     
    • Like Like x 1
  18. WolfieeifloW

    WolfieeifloW WEHZ Helper

    Ratings:
    +372 / 0 / -0
    Make a new trigger.
    Go to "Edit -> Convert to Custom Text".
    Erase what's there and paste the script into it.
    Save the map.
    GG!

    Oh, and nice snippet AceHart!
    Might use this in my AoS.
     
  19. eraserboy

    eraserboy Guest

    Ratings:
    +0 / 0 / -0
    error =C

    i just did what u told me to do to paste the config wolf... but there's an error when i saved the map...

    it said "script error"
    all script are error....

    how's that?

    maybe there is another editor?

    i only use editor that i got from the frozen throne cd

    the error is like this

    47 compile error
    ...
    Note: rest edited out
     
  20. WolfieeifloW

    WolfieeifloW WEHZ Helper

    Ratings:
    +372 / 0 / -0
    Put all that in a quote tag please :eek: .
    And you need Jass NewGen WE (i think?)

    EDIT: @AceHart: Could you make the unit "holdposition" instead of "stop"?
    I know it's easily configured, but for people who don't know how it's nice.
     

Share This Page