• 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.

[Snippet] Invul Mass Destructables

Level 9
Joined
Apr 23, 2011
Messages
460
This is probably not too useful to anyone, maybe to some beginners or someone who wants an easily configurable system for a map that has tons of destuctables that you want to make invulnerable. I'm new to JASS (sorta) so any corrects please post them and I'll make them. It seems to work fine for me, and I just wanted to put this up for anyone who might need it.
Simple copy and paste with some moderate configuration should do the trick. The coding is annotated with what to modify.
This code can really be used in many situations when you need say 4+ destructable TYPES all invulnerable and you have various instances of these multiple destructables. I just though "maybe someone could use this", so I posted it here.

JASS:
globals
integer array destType
integer begin = 1 //Keep this unless you start the DestType at 0 or some other number.. Dunno why you would though.
integer end = 2 //Change to the max number of destructable types you are declaring.
rect area = bj_mapInitialPlayableArea //Change to the the Area you want your variables to be selected in.
endglobals

function DeclareDestTypes takes nothing returns nothing
set destType[1] = 'ZTtw' // Change to whatever your first destructable type you want to invul is. (Raw Data)
set destType[2] = 'B001' // Change to whatever your second destructable type you want to invul is.(Raw Data)
//Add more lines here if you have more types to invul.
endfunction

function IsInvul takes nothing returns nothing
    loop
        exitwhen begin > end
        if GetDestructableTypeId(GetEnumDestructable()) == destType[begin] then
            call SetDestructableInvulnerable(GetEnumDestructable(), true)
        endif
        set begin = begin + 1
    endloop
endfunction

function GetDestructables takes nothing returns nothing
    call EnumDestructablesInRect(area, null,  function IsInvul)
endfunction

function InitTrig_InvulDestructables takes nothing returns nothing
    local trigger t = CreateTrigger()
    
    call TriggerRegisterTimerEvent(t, 0.5, false)
    call TriggerAddAction(t, function GetDestructables)
    call TriggerAddAction(t, function DeclareDestTypes)
    set t = null
endfunction
 
Last edited:
JASS:
@scope InvulDests initializer Init@ //Scopes are your friend.
    
    globals //Indentation was needed, and so was "private"
    @    private @integer array destType
    @    private @integer end = 2
    @    private @rect area = bj_mapInitialPlayableArea
    endglobals
    
    @private @function DeclareDestTypes takes nothing returns nothing
    @    @set destType[0] = 'ZTtw' //Arrays always start at 0, why waste?
    @    @set destType[1] = 'B001'
    endfunction
    
    @private @function IsInvul takes nothing returns nothing
        @local destructable d = GetEnumDestructable()@ //Locals are your friend.
        @local integer id = GetDestructableTypeId(d)@ //Cache the ID to prevent calling the function many times.
        @local integer i = 0@ //You don't need the "begin" variable. A local works better and you also forgot
                              //to reset "begin" to 0 at the end of this function causing issues.
        loop
            if id == destType[begin] then
                call SetDestructableInvulnerable(@d@, true)
                @exitwhen true@ //You can now exit the loop, as you don't have to check for any other types.
            endif
            set begin = begin + 1
            @exitwhen begin > end@ //Moved it to the end to keep the loop end-point intuitive.  
        endloop
        @set d = null@ //Always null local handles.
    endfunction
    
    @private@ function Init takes nothing returns nothing
        @call DeclareDestTypes()@ //You forgot to call that function.
        @call EnumDestructablesInRect(area, null,  function IsInvul)@ //There's no reason for delaying it.
        /*local trigger t = CreateTrigger()
        
        call TriggerRegisterTimerEvent(t, 0.5, false)
        call TriggerAddAction(t, function GetDestructables)
        set t = null
        */
    endfunction
@endscope@
 
Or:

JASS:
struct InvulnerableDestructables extends array

    private static hashtable ht = InitHashtable()
    private static rect world = bj_mapInitialPlayableArea
    
    private static method declareTypes takes nothing returns nothing
        call SaveBoolean(ht, 'ZTtw', 0, true)
        call SaveBoolean(ht, 'B001', 0, true)
    endmethod
    
    private static method makeInvulnerable takes nothing returns nothing
        if HaveSavedBoolean(ht, GetDestructableTypeId(GetEnumDestructable()), 0) then
            call SetDestructableInvulnerable(GetEnumDestructable(), true)
        endif
    endmethod
    
    private static method onInit takes nothing returns nothing
        call declareTypes()
        call EnumDestructablesInRect(world, null, function thistype.makeInvulnerable)
    endmethod
endstruct

This is way faster o_O
 
Or:

JASS:
struct InvulnerableDestructables extends array

    private static hashtable ht = InitHashtable()
    private static rect world = bj_mapInitialPlayableArea
    
    private static method declareTypes takes nothing returns nothing
        call SaveBoolean(.ht, 'ZTtw', 0, true)
        call SaveBoolean(.ht, 'B001', 0, true)
    endmethod
    
    private static method makeInvulnerable takes nothing returns nothing
        call SetDestructableInvulnerable(GetEnumDestructable(), LoadBoolean(.ht, GetDestructableTypeId(GetEnumDestructable()), 0))
    endmethod
    
    private static method onInit takes nothing returns nothing
        call .declareTypes()
        call EnumDestructablesInRect(.world, null, function thistype.makeInvulnerable)
        call FlushParentHashtable(.ht)
        set .ht = null
    endmethod
endstruct
 
I guess I should make a vJass tutorial.
I have a structs tutorial though.
It's called "Structs For Dummies" ^_^

Scopes are nothing special, all you do is declare them and everything inside the scope can't be used from the outside. (Unless you declare a public function)

Scopes are moved to the end of the mapscript.

Structs are ... well, you can read about them in that tutorial.
I sometimes also use structs the same way scopes are used because I like them :3

static methods are the exact same things as functions.
The only difference between a static method and a function is the name and the fact that you can't declare a static method outside a struct.

A method is like a static method, but it gets compiled to take an extra argument (integer this)

So this:

JASS:
method hi takes nothing returns nothing

endmethod

gets compiled to this:

JASS:
function hi takes integer this returns nothing

endfunction


You would use methods to refer to one instance of the struct.
Static methods are not associated with a single instance, but the struct itself.

Libraries are used for the same thing as scopes, but there are some differences.

Libraries can be required using the "requires/uses/needs" keywords, and that way, you would be able to use the functions and structs inside a library.

Locals are just like globals, but they're faster and they can only be accessed from inside the function in which they are declared.

JASS:
function Example takes nothing returns nothing
    local integer i = 1
    // i can only be used here.
endfunction

function Hello takes nothing returns nothing
    set i = 0 // This is wrong because i is not declared inside this function, but inside the other one.
endfunction
 
Level 9
Joined
Apr 23, 2011
Messages
460
Sorry, I understand locals but whats a private static <variable>? And yes i'd like to see this struct guide. And also do make a vjass tutorial. I learned Jass from blizzard and applied the JPAG guide to make my scripts and scripting a lot cleaner and more organized. I also read other scripts and things but I never really was able to learn vjass cuz no one write about it, it's just written in.
 
Level 9
Joined
Apr 23, 2011
Messages
460
So I've been reading about structs and I have come to the conclusion that structs operate like objects that declare variables or code inside of the struct as child operators of the struct as if it were an object which can be initialized through <structname>.create(). Correct me if I'm wrong here.
 
The only way to save this resource is to do the following:

- Change the initialization function to a library/scope initializer.
- Make it call DeclareDestTypes() and then just enumerate over all destructables.
- Put the code inside a library/scope.

If you don't want to, or don't have time, I can graveyard this leaving it dead for all eternity, or I can graveyard it temporarily and revive it when you feel like updating.
 
Top