Struct/Method Help; Getting A Unit From One Method To Another

WolfieeifloW

WEHZ Helper
Reaction score
372
Hey there.
Recently I've got more into structs and methods, but I'm having a bit of trouble.

I've semi-learned about static and non-static structs.
But uhm, I'm wondering how I carry a unit from one method to another:
JASS:
struct HowlingBlast
    unit Caster
    unit Target
    integer Level
    
    static method Damage takes integer level returns real
        return level * 5.
    endmethod
    
    static method Radius takes nothing returns real
        return 150.
    endmethod
    
    static method Conditions takes nothing returns boolean
        if (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(.Caster))) then
            call Damage_Spell(.Caster, GetFilterUnit(), Damage(.Level) / 2)
        endif
        return false
    endmethod

    static method onCast takes nothing returns boolean
        local thistype this = thistype.create()
        set .Caster = GetTriggerUnit()
        set .Target = GetSpellTargetUnit()
        set .Level = GetUnitAbilityLevel(.Caster, HOWLING_BLAST)
        
        call Damage_Spell(.Caster, .Target, thistype.Damage(.Level))
        call GroupEnumUnitsInRange(GROUP, GetUnitX(.Target), GetUnitY(.Target), thistype.Radius, Filter(function thistype.Conditions))
        return false
    endmethod
    
    static method onInit takes nothing returns nothing
        call TriggerAddCondition(GT_RegisterStartsEffectEvent(CreateTrigger(), HOWLING_BLAST), Condition(function thistype.onCast))
    endmethod
    
endstruct

The whole Conditions method errors:
Undeclared variable this

So, I'm wondering.
How do I get a unit from one method to another?
 

Solmyr

Ultra Cool Member
Reaction score
30
Static methods do not use an instance ([ljass]this[/ljass]), so instead, you have to pass the current instance through the use of a static variable.
JASS:
struct HowlingBlast
    unit Caster
    unit Target
    integer Level
    static thistype currentInstance /* We will use this static member to pass the current instance to the filter function. */
    
    static method Damage takes integer level returns real
        return level * 5.
    endmethod
    
    static method Radius takes nothing returns real
        return 150.
    endmethod
    
    static method Conditions takes nothing returns boolean
        local thistype this = thistype.currentInstance /* Look here! */
        if (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(.Caster))) then
            call Damage_Spell(.Caster, GetFilterUnit(), Damage(.Level) / 2)
        endif
        return false
    endmethod

    static method onCast takes nothing returns boolean
        local thistype this = thistype.create()
        set .Caster = GetTriggerUnit()
        set .Target = GetSpellTargetUnit()
        set .Level = GetUnitAbilityLevel(.Caster, HOWLING_BLAST)
        
        call Damage_Spell(.Caster, .Target, thistype.Damage(.Level))
        set thistype.currentInstance = this /* Look here! */
        call GroupEnumUnitsInRange(GROUP, GetUnitX(.Target), GetUnitY(.Target), thistype.Radius, Filter(function thistype.Conditions))
        return false
    endmethod
    
    static method onInit takes nothing returns nothing
        call TriggerAddCondition(GT_RegisterStartsEffectEvent(CreateTrigger(), HOWLING_BLAST), Condition(function thistype.onCast))
    endmethod
    
endstruct
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Sounds good.
Is that the easiest/most efficient way to do so?

And, (I know I'm not supposed to ask another thing) but;
1) Is using this struct+methods better then using normal scope/library+functions?
2) What's the difference?
3) If it's better to use the latter sometimes, how do I know when to use S&M :)P) over S/L+F?


/EDIT: Does CurrentInstance have to be static?
 

Solmyr

Ultra Cool Member
Reaction score
30
It totally depends on what you're trying to achieve. You can store lots of data in a struct and later retrieve it simply by having the struct's index. Structs also provide you with other OOP concepts (interfaces, pseudo-inheritance, polymorphism ...). In your current example, you could get away using both ways.

/EDIT: Does CurrentInstance have to be static?
Oh, silly me, yes, it needs to be static. I even said it in my post (pass the current instance through the use of a static variable).

EDIT: How come you aren't deallocating the struct? You should do that, or you could run out of indices.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Okay, it's damaging the initial target, but not targets in the AoE.
JASS:
struct HowlingBlast
    unit caster
    unit target
    integer level
    static thistype currentInstance
    
    static method Damage takes integer level returns real
        return level * 5.
    endmethod
    
    static method Radius takes nothing returns real
        return 250.
    endmethod
    
    static method Conditions takes nothing returns boolean
        local thistype this = thistype.currentInstance
        if (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(.caster)) and GetFilterUnit() != .target) then
            call Damage_Spell(.caster, GetFilterUnit(), Damage(.level) / 2)
        endif
        return false
    endmethod

    static method onCast takes nothing returns boolean
        local thistype this = thistype.create()
        set .caster = GetTriggerUnit()
        set .target = GetSpellTargetUnit()
        set .level = GetUnitAbilityLevel(.caster, HOWLING_BLAST)
        
        call Damage_Spell(.caster, .target, thistype.Damage(.level))
        set thistype.currentInstance = this
        call GroupEnumUnitsInRange(GROUP, GetUnitX(.target), GetUnitY(.target), thistype.Radius, Filter(function thistype.Conditions))
        return false
    endmethod
    
    static method onInit takes nothing returns nothing
        call TriggerAddCondition(GT_RegisterStartsEffectEvent(CreateTrigger(), HOWLING_BLAST), Condition(function thistype.onCast))
    endmethod
    
endstruct
 

Solmyr

Ultra Cool Member
Reaction score
30
[ljass]call GroupEnumUnitsInRange(GROUP, GetUnitX(.target), GetUnitY(.target), thistype.Radius, Filter(function thistype.Conditions))[/ljass]

[ljass]thistype.Radius[/ljass] should be [ljass]thistype.Radius()[/ljass].

You should also deallocate the struct by putting [ljass]this.destroy()[/ljass] right above the [ljass]return false[/ljass].
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Wow.. Something that simple, sorry, lol.
Final working code, for future references:
JASS:
struct HowlingBlast
    unit caster
    unit target
    integer level
    static thistype currentInstance
    
    static method Damage takes integer level returns real
        return level * 5.
    endmethod
    
    static method Radius takes nothing returns real
        return 250.
    endmethod
    
    static method Conditions takes nothing returns boolean
        local thistype this = thistype.currentInstance
        if (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(.caster)) and GetFilterUnit() != .target) then
            call Damage_Spell(.caster, GetFilterUnit(), Damage(.level) / 2)
        endif
        return false
    endmethod

    static method onCast takes nothing returns boolean
        local thistype this = thistype.create()
        set .caster = GetTriggerUnit()
        set .target = GetSpellTargetUnit()
        set .level = GetUnitAbilityLevel(.caster, HOWLING_BLAST)
        
        call Damage_Spell(.caster, .target, thistype.Damage(.level))
        set thistype.currentInstance = this
        call GroupEnumUnitsInRange(GROUP, GetUnitX(.target), GetUnitY(.target), thistype.Radius(), Filter(function thistype.Conditions))
        call .destroy()
        return false
    endmethod
    
    static method onInit takes nothing returns nothing
        call TriggerAddCondition(GT_RegisterStartsEffectEvent(CreateTrigger(), HOWLING_BLAST), Condition(function thistype.onCast))
    endmethod
    
endstruct
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top