• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Snippet] IsDestructableTree

Level 19
Joined
Mar 18, 2012
Messages
1,716
Easily distinguish between trees and other types of destructables.

For best optimization make sure the harvester unit doesn't get indexed by
your unit indexing system ( in case you use one in your map )
JASS:
library IsDestructableTree uses optional UnitIndexer /* v1.3.1
*************************************************************************************
*
*   Detect whether a destructable is a tree or not.  
*
***************************************************************************
*
*   Credits
*
*       To PitzerMike
*       -----------------------
*
*           for IsDestructableTree
*
*************************************************************************************
*
*    Functions
*
*       function IsDestructableTree takes destructable d returns boolean
*
*       function IsDestructableAlive takes destructable d returns boolean
*
*       function IsDestructableDead takes destructable d returns boolean
*
*       function IsTreeAlive takes destructable tree returns boolean
*           - May only return true for trees.          
*
*       function KillTree takes destructable tree returns boolean
*           - May only kill trees.
*
*/
    globals
        private constant integer HARVESTER_UNIT_ID = 'hpea'//*  human peasant
        private constant integer HARVEST_ABILITY   = 'Ahrl'//*  ghoul harvest
        private constant integer HARVEST_ORDER_ID  = 0xD0032//* harvest order ( 852018 )
        private constant player  NEUTRAL_PLAYER    = Player(PLAYER_NEUTRAL_PASSIVE)
        private unit harvester                     = null
    endglobals
    function IsDestructableTree takes destructable d returns boolean
        //*  851973 is the order id for stunned, it will interrupt the preceding harvest order.
        return (IssueTargetOrderById(harvester, HARVEST_ORDER_ID, d)) and (IssueImmediateOrderById(harvester, 851973))
    endfunction
    function IsDestructableDead takes destructable d returns boolean
        return (GetWidgetLife(d) <= 0.405)
    endfunction
    function IsDestructableAlive takes destructable d returns boolean
        return (GetWidgetLife(d) > .405)
    endfunction
    function IsTreeAlive takes destructable tree returns boolean
        return IsDestructableAlive(tree) and IsDestructableTree(tree)
    endfunction
    function KillTree takes destructable tree returns boolean
        if (IsTreeAlive(tree)) then
            call KillDestructable(tree)
            return true
        endif
        return false
    endfunction
    private function Init takes nothing returns nothing
        static if LIBRARY_UnitIndexer then//*  You may adapt this to your own indexer.
            set UnitIndexer.enabled = false
        endif
        set harvester = CreateUnit(NEUTRAL_PLAYER, HARVESTER_UNIT_ID, 0, 0, 0)
        static if LIBRARY_UnitIndexer then
            set UnitIndexer.enabled = true
        endif
        call UnitAddAbility(harvester, HARVEST_ABILITY)
        call UnitAddAbility(harvester, 'Aloc')
        call ShowUnit(harvester, false)
    endfunction
    //*  Seriously?
    private module Inits
        private static method onInit takes nothing returns nothing
            call Init()
        endmethod
    endmodule
    private struct I extends array
        implement Inits
    endstruct
    
endlibrary
 
Last edited:
The UnitIndexer optional requirement is a bit odd in my opinion.

I also really don't like how people use modules for initializers because of the priority.

Why not just use the standard way of initializing? It would be make the code look cleaner anyway.

Also,function TreeAlive->function IsTreeAlive

And maybePLAYER_NEUTRAL_PASSIVEshould be configurable.

and I don't see the point of setting the dummy's position.

BPower said:
I might add IsDestructableDead aswell for 100% backwards compatibility
yah
 
Last edited:
Level 19
Joined
Mar 18, 2012
Messages
1,716
Also, function TreeAlive -> function IsTreeAlive
It was IsTreeAlive in the first place, then I changed it to TreeAlive analogous to UnitAlive, but you are right it can't be compared to the native.
The UnitIndexer optional requirement is a bit odd in my opinion.
I removed the UnitIndexer requirement, because it is no longer available here.

I also don't see the point of setting the dummy's position.
There was no point, because the unit is hidden. I also removed that line.

And maybe PLAYER_NEUTRAL_PASSIVE should be configurable.
Why not ...
 
Looks good. Make sure you switch TreeAlive to IsTreeAlive in the documentation. The IsTreeAlive function is a little funny logic wise (it'll return false if the destructable is not a tree). It just gave me a little chuckle to visualize it as: "Q: Are you an alive tree? A: Well... I'm alive. Q: I'll take that as a no."

Of course, I don't mean for you to change it. It is just interesting. I guess it could make sense logically as IsTreeAndAlive, but that is so ugly that it makes my vomit want to vomit.

Anyway, it is a good resource and definitely approvable once the documentation is fixed.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
I now also added IsDestructableAlive. It's somehow funny how the functions works in symbiosis. KillTree --> IsTreeAlive --> IsDestructableAlive + IsDestructableTree.

The old IsDestructableTree library had IsDestructableDead instead of IsDestructableAlive which I really dislike, because for instance
KillTree would have to check -> not IsDestructableDead. Still it exists since 2009. Should I change it in favour of backwards-compatibility?
 
Spinnaker, Let me help with that :
http://www.hiveworkshop.com/forums/spells-569/isdestree-v1-2-a-224623/?prev=status=a&u=Almia
http://www.hiveworkshop.com/forums/spells-569/gui-jass-isdesttree-v1-2-a-240149/
http://www.hiveworkshop.com/forums/...abletree-222145/?prev=search=Tree&d=list&r=20
http://www.hiveworkshop.com/forums/...e-gui-1-1-a-228385/?prev=d=list&r=20&u=Chaosy
Those are IDS I found at Spell Section. Seems we got tons of variants of these ^^

Everyone
I guess users can have lots of fun testing each IDS and see which one suits the best for them. (Mappers varies from GUI, JASS, VJASS, CJASS, WURST Coders, when a WURST version will show up anyway?)
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
- IsDesTree v1.2 is neat. I forgot about it when I uploaded this version. However you should add the harvest ability to the unit, because users might mess around with the worker unit.
- GUI and JASS IsDestTree is the same code as IsDesTree v1.2.

Use hashtables if you have to store a huge amount of data, which you want to access quickly, ... but for two trees, come on.
- IsDestructableTree may cause trouble with custom trees.
- IsDestructableTree GUI 1.1 no comment.

I made it, because I saw the IDS in your TR library.
It was the "not so good" one of wc3.net in the first place, now it's equal to this one.
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
I hope you do understand that my previous replies were not even remotely meant to offend you. Simply, I've just posted my opinion that truely there is a lot of such resources already.

You're right, the "default" implementation used within my script is not as perfect as one implemented here. Its biggest issue is that it lacks callback for stop or stun order to prevent any suprices from occuring. However, user can use any IDT lib he wants, thus wc3c implem is not forced to be used. I'll update my lib.

I do not think is a problem with approval of this but meaby add a "library_once" keyword to prevent any missunderstandings when multiple libraries of such are in use.

I've coded destdex and destutils about 2years ago, meaby I'll dig to find those out, but what comes to my mind is the IsDestructableDead function - yours lack GetDestructableTypeId() == 0; I have never encountered situation where checking getwidgetlife missled me, yet if function of such designed for units checks for typeid, I think there is nothing wrong to add additional safety here too. Inline frienly +
 
Sorry if I offend you in any way.
Anyway, thanks for this information :
- IsDesTree v1.2 is neat. I forgot about it when I uploaded this version. However you should add the harvest ability to the unit, because users might mess around with the worker unit.
- GUI and JASS IsDestTree is the same code as IsDesTree v1.2.
I'll patch it today if I can. +Credit.
 

Cokemonkey11

Code Reviewer
Level 29
Joined
May 9, 2006
Messages
3,516
> IsDestructableAlive

> IsDestructableDead

Never do this. Add a deprecated marker to IsDestructableDead, which isn't part of the original API and adds no functionality.

> (IssueImmediateOrderById(h, 851973))

Never reference raw Order Ids without comment

Anything else is minor, but these are important.
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
Or add global + static if for modularity:
-> true: implement
-> false: do not ;>

That way, function can still exist within this lib if user wants to, and compatability is not broken even if he doesn't.

+1 for dislike of "is_alive" within IDT tho.

Btw, why, oh, why you removed gaps between functions and named private unit "h"; I know that many scripts, done even by mods and approved use such naming however, bad naming is bad, lol.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
Btw, why, oh, why you removed gaps between functions and named private unit "h"; I know that many scripts, done even by mods and approved use such naming however, bad naming is bad, lol.
Ha, I though about the same thing today, after checking the script due to Cokemonkey's post. I changed h to HARVESTER.

I think it depends much on which function is more useful ( more often used), either IsDead or IsAlive. Personally I prefer IsAlive.
 

Cokemonkey11

Code Reviewer
Level 29
Joined
May 9, 2006
Messages
3,516
Ha, I though about the same thing today, after checking the script due to Cokemonkey's post. I changed h to HARVESTER.

I think it depends much on which function is more useful ( more often used), either IsDead or IsAlive. Personally I prefer IsAlive.

It's not your API to change, and having both is dumb :p

I guess it's still minor.
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
Can you issue harvest order to dead trees?

Shouldn't this be something like this ? :)

JASS:
function IsDestructableTree takes destructable d returns boolean
    local boolean b // better to use global mb
    if IsDestructableAlive(d) then
        return IssueTargetOrderById(HARVESTER, HARVEST, d) and IssueImmediateOrderById(HARVESTER, 851973)
    else
        ReviveDestructable(d) // or whatever it is
        set b = IssueTargetOrderById(HARVESTER, HARVEST, d) and IssueImmediateOrderById(HARVESTER, 851973)
        call KillDestructable(d)
        return b
    endif
endfunction
 
Top