Combo Points System Not Working

WolfieeifloW

WEHZ Helper
Reaction score
372
I'm working on converting my map over to using GTrigger, Damage, and AIDS.
I've got some help with making my ComboPoints system use AIDS, but it's not working now.
Here's a quote from my previous combo points thread:
What's supposed to happen:
A unit uses a certain spell (Mangle or Claw) and gets a 'combo point'.
Combo points range from 0-5.
So, I made 6 spells with different icons/descriptions/models to represent these combo points.

When the hero uses Mangle/Claw, it's combo points get increased by 1 up to a maximum of 5.
The system removes the current combo point ability, and gives it the next rank (Again, up to 5).
I, honestly, don't really know how to use AIDS, but I need it for my map to use Damage.

Here's my systems code, if someone could spot the error perhaps and also explain how/why it's not working so I can actually learn from this?
Thank you in advance, and sorry for the trouble.
JASS:
library ComboPoints initializer onInit uses AIDS, GT

    globals
        integer array COMBO
        public integer array Data
    endglobals

    private function onCast takes nothing returns boolean
        local unit u = GetTriggerUnit()
        local integer id
        
        set id = GetUnitId(u)
        if Data[id] != 5 then
            call UnitRemoveAbility(u, COMBO[Data[id]])
            set Data[id] = Data[id] + 1
            call UnitAddAbility(u, COMBO[Data[id]])
        endif
        set u = null
        return false
    endfunction
    
    private function OnInit takes nothing returns nothing
        call TriggerAddCondition(GT_RegisterStartsEffectEvent(CreateTrigger(), mangle), Condition(function onCast))
        call TriggerAddCondition(GT_RegisterStartsEffectEvent(CreateTrigger(), claw), Condition(function onCast))
        
        // set up your COMBO array values
        set COMBO[0] = 'A009'
        set COMBO[1] = 'A00E'
        set COMBO[2] = 'A00F'
        set COMBO[3] = 'A00G'
        set COMBO[4] = 'A00H'
        set COMBO[5] = 'A00I'
    endfunction

endlibrary
 

Laiev

Hey Listen!!
Reaction score
188
JASS:
private struct data extends array
    integer comboCounter
    
    method AIDS_filter takes unit u returns boolean
        return IsUnitType(u, UNIT_TYPE_HERO)
    endmethod
    
    static method AIDS_onInit takes nothing returns nothing
        set .comboCounter = 0
    endmethod
    
    //! runtextmacro AIDS()
endstruct

private function onCast takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local data d = data<u>
    
    
    if d.comboCounter != 5 then
        call UnitRemoveAbility(u, COMBO[d.comboCounter])
        set d.comboCounter = d.comboCounter + 1
        call UnitAddAbility(u, COMBO[d.comboCounter])
    endif

    set u = null
    return false
endfunction
</u>


freehand :p
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Hmm.
It seems there is still an error with the "finishing move".
If the user has no combo points, it should not allow him to cast the move.
It does this, if you don't get any combo points.
But, if you get combo points, then use them up with the finisher, then retry the finisher when you're supposed to have gone back down to 0, it doesn't stop the user.
JASS:
scope FerociousBite initializer onInit

    private function Chance takes integer level returns integer
        return level * 2
    endfunction

    private function Damage takes integer level returns real
        return (level * 0.5) + 0.5
    endfunction
    
    private function onCast takes nothing returns boolean
        local real dmg
        local unit u = GetTriggerUnit()
        local integer UD = ComboPoints_Data[GetUnitId(u)]
        
        if (GetSpellAbilityId() == ferociousBite and UD &gt; 0) then
            set dmg = (GetHeroAgi(u, true) * Damage(UD))
            call Damage_Physical(u, GetSpellTargetUnit(), dmg, ATTACK_TYPE_MELEE, true, false)
            call UnitRemoveAbility(u, COMBO[UD])
            if (GetRandomInt(1, 100) &lt;= Chance(GetUnitAbilityLevel(u, ferociousBite)) and UD &gt;= 4) then
                set UD = UD - 3
            else
                set UD = 0
            endif
            call UnitAddAbility(u, COMBO[UD])
        elseif (GetSpellAbilityId() == ferociousBite and UD &lt;= 0) then
            call IssueImmediateOrder(u, &quot;stop&quot;)
            call SimError(GetOwningPlayer(u), &quot;You need at least one combo point!&quot;)
        endif
        set u = null
        return false
    endfunction

    private function onInit takes nothing returns nothing
        call TriggerAddCondition(GT_RegisterStartsEffectEvent(CreateTrigger(), ferociousBite), Condition(function onCast))
    endfunction

endscope

And here's the actual combo point system:
JASS:
library ComboPoints initializer onInit uses AIDS, GT

    globals
        integer array COMBO
        public integer array Data
    endglobals

    private function onCast takes nothing returns boolean
        local unit u = GetTriggerUnit()
        local integer id
        
        set id = GetUnitId(u)
        if Data[id] != 5 then
            call UnitRemoveAbility(u, COMBO[Data[id]])
            set Data[id] = Data[id] + 1
            call UnitAddAbility(u, COMBO[Data[id]])
        endif
        set u = null
        return false
    endfunction
    
    private function onInit takes nothing returns nothing
        call TriggerAddCondition(GT_RegisterStartsEffectEvent(CreateTrigger(), mangle), Condition(function onCast))
        call TriggerAddCondition(GT_RegisterStartsEffectEvent(CreateTrigger(), claw), Condition(function onCast))
        
        // set up your COMBO array values
        set COMBO[0] = &#039;A009&#039;
        set COMBO[1] = &#039;A00E&#039;
        set COMBO[2] = &#039;A00F&#039;
        set COMBO[3] = &#039;A00G&#039;
        set COMBO[4] = &#039;A00H&#039;
        set COMBO[5] = &#039;A00I&#039;
    endfunction

endlibrary
 

Ayanami

칼리
Reaction score
288
You need to:
JASS:
set ComboPoints_Data[GetUnitId(u)] = 0 // do this to set the combo point to 0


And this part:
JASS:
if (GetSpellAbilityId() == ferociousBite

That is not necessary. You notice that when you register a starts effect event with GTrigger, you already specify the ability Id, thus you don't need to do GetSpellAbilityId().
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Yeah, forgot to edit that out :p

Also, it now works :)
Here's the final code:
JASS:
scope FerociousBite initializer onInit

    private function Chance takes integer level returns integer
        return level * 2
    endfunction

    private function Damage takes integer level returns real
        return (level * 0.5) + 0.5
    endfunction
    
    private function onCast takes nothing returns boolean
        local real dmg
        local unit u = GetTriggerUnit()
        local integer UD = ComboPoints_Data[GetUnitId(u)]
        
        if (UD &gt; 0) then
            set dmg = (GetHeroAgi(u, true) * Damage(UD))
            call Damage_Physical(u, GetSpellTargetUnit(), dmg, ATTACK_TYPE_MELEE, true, false)
            call UnitRemoveAbility(u, COMBO[UD])
            if (GetRandomInt(1, 100) &lt;= Chance(GetUnitAbilityLevel(u, ferociousBite)) and UD &gt;= 4) then
                set UD = UD - 3
                set ComboPoints_Data[GetUnitId(u)] = ComboPoints_Data[GetUnitId(u)] - 3
            else
                set UD = 0
                set ComboPoints_Data[GetUnitId(u)] = 0
            endif
            call UnitAddAbility(u, COMBO[UD])
        elseif (UD &lt;= 0) then
            call IssueImmediateOrder(u, &quot;stop&quot;)
            call SimError(GetOwningPlayer(u), &quot;You need at least one combo point!&quot;)
        endif
        set u = null
        return false
    endfunction

    private function onInit takes nothing returns nothing
        call TriggerAddCondition(GT_RegisterStartsEffectEvent(CreateTrigger(), ferociousBite), Condition(function onCast))
    endfunction

endscope
 

tooltiperror

Super Moderator
Reaction score
231
>ferociousBite
Is this a constant? If so, it should be [LJASS]FEROCIOUS_BITE[/LJASS]. Just a convention.

>(level * 0.5) + 0.5
This is not necessary. * has higher precedence than + so the () does nothing.

>call SimError(
Creative. I like it :)
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Ah yeah.
I'm still getting used to the different conventions.
Is it only constants that get all caps, or generally all sort of global names like so?

I know it's not necessary (BEDMAS for the win), but I like it as it makes it more readable for me.
I assume that having it in brackets like that isn't a problem for efficiency or speed or anything?
If it is, then by all means I'd remove them.

And I love SimError.
Ever since I found it I always use it.
 

tooltiperror

Super Moderator
Reaction score
231
Theoretically, since JASS is theorized to be string based, and Blizzard would be dumb enough not to optimize that, it should be slower to use parenthesis. But unless you're doing shit by the second, I doubt it matters at all.

Only constants get UPPER_CASE_AND_UNDER_SCORES. Global variables go CamelCase, local variables are camelCase. Also, MyFavoriteFunction for functions, and camelCase for local variables. Local variables and global variables using the different camel cases are very important so you do not get variable shadowing.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
MYCONSTANT.
MyGlobal.
myLocal.
MyFunction.

I knew about the function, but the other three are nice to know.
 

tooltiperror

Super Moderator
Reaction score
231
>MYCONSTANT
[LJASS]MY_CONSTANT[/LJASS] ;)

Another random tip is to not name triggers "t", I name them "trig" and "t" is reserved for local timers. I just like doing that :)

I use two extra linebreaks inside of a function: a line between local declarations and the function script, and then a line after the function script and before the return/nulling/clean up.

Don't use bj_ globals. It's just not the right thing to do. Sure, [ljass]bj_ghoul[7182][/LJASS] will probably never be overlapped, but it's against coder morals.

Learn more data structures, and how to use the ones you have, as soon as possible. I'm in the process of writing a tutorial, but you should know Array Sorting, (linked) Lists, Maps ([LJASS]hashtable + StringHash[/LJASS]) and so on.

Just some random JASS advice.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Yeah, had the _ in there, must have deleted it by accident :p

The extra linebreak at the end is nice, to make it look cleaner, yes.

I don't think I've ever used a bj_ in a Global.

And what's a data structure? Is that a struct?
I know, very lightly/limited-ly how to use structs.
I don't think I know any of the other things though.

I had a hard time learning timers way back when.
And the only thing about structs I know is how to use them to help pass units to a timed function, like here.
 

tooltiperror

Super Moderator
Reaction score
231
Alright, let's start by using parallel integers and an array.

JASS:
globals
    integer array Balance[30]
endglobals

function onInit takes nothing returns nothing
    local integer account_Tom = 1
    local integer account_Jay = 2

    set Balance[account_Tom] = 242
    set Balance[account_Jay] = 600
endfunction


As you can see, you can use arrays to fake having an account type in JASS. You can go so far with this that you could even make functions!

JASS:
function GetBalance takes integer account returns integer
    return Balance[account]
endfunction


Now, let's say we wanted to automate this process. We could use a struct instead.

JASS:
struct Account
    integer balance // Create an integer array called balance
endstruct

function onInit takes nothing returns nothing
    local Account Tom = 1  // We can use &quot;Account&quot; instead of integer, JASSHelper turns it into integer anyways
    set Tom.balance = 300  // Tom.balance = Balance[Tom], we just get to use a . instead now
endfunction


Now here's the great part, methods.

JASS:
struct Account
    integer balance

    // It looks like a function declaration, but uses method
    method SetBalance takes integer newBalance returns nothing
        set balance = newBalance
    endmethod
endstruct


Then, you can use SetBalance on any Account object! Such as, [LJASS]Tom.SetBalance(150)[/LJASS] to change it.

But using [LJASS]Account x = 1[/LJASS] is too... bad. I mean, then stuff can be overwritten! What if you wanted to use a struct to make something MUI? The solution is to use the [LJASS].create[/LJASS] method, and [LJASS].destroy[/LJASS] to get rid of references.

JASS:
local Account Tom = Account.create()
call Tom.destroy()
 

Ayanami

칼리
Reaction score
288
Structs are very powerful and you might want to learn it as soon as possible if you're planning to use vJASS. Honestly, I myself struggled a lot learning about Structs.

First thing that I struggled with Struct is understanding how it works and what are the practical uses for it. I'll attempt to explain Struct from the very basic stage.

If you have ever taken other Programming Languages, I believe Struct is more commonly known as a Class (at least in JAVA it is called a Class). First, you must understand that a Struct generally represents an object. This object can be anything, be it a Car, a Book, a Person, etc. This object would then be a variable type that you can use (like integers, reals, strings, etc).

The next important concept about Struct is the various instances that you can have inside the Struct. I'll elaborate this with an example. Let's say you have a Struct called Bicycle. So basically, this would mean that you could have multiple bicycles inside the Struct. Let's say the Struct has 2 instances initiated. This means that there are currently 2 bicycles that are present under the Struct Bicycle. You can also imagine Struct instances as variable array indexes. For example, you can have Bicycle[1] and Bicycle[2]. I hope you can grasp the concept of instance this.

So a Struct can have instances. But now we need to know how to create an instance. That's where you use:
JASS:

struct Bicycle
endstruct

private function Test takes nothing returns nothing
    local Bicycle d = Bicycle.create()
endfunction


You notice that you can do things like local Bicycle d now. As I mentioned, you can use Structs as a variable type (just like integer, real, string, etc). As shown above, .create() is the syntax to create a new instance. So basically, your variable d holds an instance of the Struct type Bicycle.

So great, now we can create an instance, awesome! But now what? Before we go on to anything else, we need to know how to destroy an instance as well. What if you create a bicycle then later, you decide you don't need it anymore. Keeping the unneeded bicycle would just waste space. That's why we destroy the unneeded instances. Here, I would like to also mention that your Struct instances are limited. You can have up to 8190 instances for a Struct. That's why destroying the unneeded instances is necessary. To do that:

JASS:

struct Bicycle
endstruct

private function Test takes nothing returns nothing
    local Bicycle d = Bicycle.create() // creating an instance

    // other actions...

   call d.destroy() // destroying the instance
endfunction


You would have noticed that you don't do [ljass]Bicycle.destroy()[/ljass]. This is because Bicycle is the struct itself. When you destroy something, you want to destroy the instance of Bicycle, not the struct itself. Thus, it's [ljass]d.destroy()[/ljass]. The variable d holds the instance, which is the reason why you do [ljass]d.destroy()[/ljass]. That's the syntax to destroy.

So now that we have the creating and destroying out of the way, now we need to know what can these instances actually be used for. Inside a Struct, you can have what you call Instance Variables:
JASS:

struct Bicycle
    integer gear
    real speed
    real size
endstruct

private function Test takes nothing returns nothing
    local Bicycle d = Bicycle.create()

    set d.gear = 1
    set d.speed = 10.0
    set d.size = 40.
endfunction


The above demonstrates Instance Variables. Basically, instance variables have different values depending on the instance itself:
JASS:

struct Bicycle
    real speed
endstruct

private function Test takes nothing returns nothing
    local Bicycle a = Bicycle.create()
    local Bicycle b = Bicycle.create()

    set a.speed = 10.0
    set b.speed = 30.0

    call BJDebugMsg(R2S(a.speed))
    call BJDebugMsg(R2S(b.speed))
endfunction


So from the above, Bicycle a has a speed of 10.0 while Bicycle b has a speed of 30.0. So using a.speed would be different from using b.speed. You can imagine this as arrays. In an array form, a and b would be 1 and 2. Then a.speed would be speed[1] and b.speed would be speed[2]. I should also now mention that instances are basically integers. Thus you can do things like:
JASS:

struct Bicycle
endstruct

private function Test takes nothing returns nothing
    local Bicycle a = Bicycle.create()

    call BJDebugMsg(I2S(a)) // would display an integer
endfunction


Instances start at the value 1, all the way to 8190. 0 is reserved for another special purpose I believe. Thus, you can use Struct to easily make a spell that is MUI. Struct also have something called Methods. Methods are basically functions. However, inside a struct, you wouldn't call it a function. It would be a method. However, methods are special. Why? There are 2 types of methods. There is a Static Method and an Instance Method. I'll touch on Instance Methods first.

Instance methods are similar to instance variables. Instance methods basically do things like any other functions would do, except you refer to an instance. An example is needed again:
JASS:

struct Bicycle
    real speed

    method setSpeed takes real r returns nothing
        set this.speed = r
    endmethod
endstruct

private function Test takes nothing returns nothing
    local Bicycle d = Bicycle.create()

    call d.setSpeed(20.0) // calls the method &quot;setSpeed&quot;
endfunction


When you call an instance method, you notice you need to refer an instance, d.setSpeed. The d in front is basically saying that you're running the method setSpeed for instance d. Now let's look at the method itself. You would notice the syntax is pretty similar to a function, except it's "method" instead of "function". The next thing that could puzzle you is the syntax [ljass]this[/ljass]. [ljass]this[/ljass] basically refers to the instance that you associated with the method when you called it. Remember you did [ljass]call d.setSpeed[/ljass]? [ljass]this[/ljass] basically refers to d inside of the method setSpeed.

On the other hand, static methods are slightly different. Static methods have no instances associated with them. You can just imagine static methods as your normal functions, because static methods are your normal everyday function. They're just called static method inside a struct. Example:
JASS:

struct Bicycle
    static method print takes nothing returns nothing
        call BJDebugMsg(&quot;Hello!&quot;)
    endmethod
endstruct

private function Test takes nothing returns nothing
    call Bicycle.print()
endfunction


You would have noticed that this time, you don't need an instance to call the method. So basically, static methods are your normal functions. Just note that you need the struct name when you call a static method, thus Bicycle.print(). This is there to differentiate methods with the same name from different structs:
JASS:

struct A
    static method print takes nothing returns nothing
        call BJDebugMsg(&quot;A&quot;)
    endmethod
endstruct

struct B
    static method print takes nothing returns nothing
        call BJDebugMsg(&quot;B&quot;)
    endmethod
endstruct

private function Test takes nothing returns nothing
    call A.print() // calls the static method &quot;print&quot; inside struct A
    call B.print() // calls the static method &quot;print&quot; inside struct B
endfunction


The keyword static is basically a term to say that that certain thing isn't associated with an instance. Thus, there are also static variables inside a struct. Static variables are basically global variables inside a struct. They don't need an instance:
JASS:

struct Bicycle
    static integer count
endstruct

private function Test takes nothing returns nothing
     set Bicycle.count = 1 // sets the static integer &quot;count&quot; inside struct Bicycle to 1
endfunction


Lastly, you should also know that you can use the private and public keyword inside and for a struct. I hope this massive passage helped you understand struct a little better xD
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Easiest way, struct is an integer.
Struct.create returns a integer.
Struct.destroy recycles the integer for future usage.
Enough said.
 

tommerbob

Minecraft. :D
Reaction score
110
Structs are very powerful and you might want to learn it as soon as possible if you're planning to use vJASS. Honestly, I myself struggled a lot learning about Structs.

First thing that I struggled with Struct is understanding how it works and what are the practical uses for it. I'll attempt to explain Struct from the very basic stage.

If you have ever taken other Programming Languages, I believe Struct is more commonly known as a Class (at least in JAVA it is called a Class). First, you must understand that a Struct generally represents an object. This object can be anything, be it a Car, a Book, a Person, etc. This object would then be a variable type that you can use (like integers, reals, strings, etc).

The next important concept about Struct is the various instances that you can have inside the Struct. I'll elaborate this with an example. Let's say you have a Struct called Bicycle. So basically, this would mean that you could have multiple bicycles inside the Struct. Let's say the Struct has 2 instances initiated. This means that there are currently 2 bicycles that are present under the Struct Bicycle. You can also imagine Struct instances as variable array indexes. For example, you can have Bicycle[1] and Bicycle[2]. I hope you can grasp the concept of instance this.

So a Struct can have instances. But now we need to know how to create an instance. That's where you use:
JASS:

struct Bicycle
endstruct

private function Test takes nothing returns nothing
    local Bicycle d = Bicycle.create()
endfunction


You notice that you can do things like local Bicycle d now. As I mentioned, you can use Structs as a variable type (just like integer, real, string, etc). As shown above, .create() is the syntax to create a new instance. So basically, your variable d holds an instance of the Struct type Bicycle.

So great, now we can create an instance, awesome! But now what? Before we go on to anything else, we need to know how to destroy an instance as well. What if you create a bicycle then later, you decide you don't need it anymore. Keeping the unneeded bicycle would just waste space. That's why we destroy the unneeded instances. Here, I would like to also mention that your Struct instances are limited. You can have up to 8190 instances for a Struct. That's why destroying the unneeded instances is necessary. To do that:

JASS:

struct Bicycle
endstruct

private function Test takes nothing returns nothing
    local Bicycle d = Bicycle.create() // creating an instance

    // other actions...

   call d.destroy() // destroying the instance
endfunction


You would have noticed that you don't do [ljass]Bicycle.destroy()[/ljass]. This is because Bicycle is the struct itself. When you destroy something, you want to destroy the instance of Bicycle, not the struct itself. Thus, it's [ljass]d.destroy()[/ljass]. The variable d holds the instance, which is the reason why you do [ljass]d.destroy()[/ljass]. That's the syntax to destroy.

So now that we have the creating and destroying out of the way, now we need to know what can these instances actually be used for. Inside a Struct, you can have what you call Instance Variables:
JASS:

struct Bicycle
    integer gear
    real speed
    real size
endstruct

private function Test takes nothing returns nothing
    local Bicycle d = Bicycle.create()

    set d.gear = 1
    set d.speed = 10.0
    set d.size = 40.
endfunction


The above demonstrates Instance Variables. Basically, instance variables have different values depending on the instance itself:
JASS:

struct Bicycle
    real speed
endstruct

private function Test takes nothing returns nothing
    local Bicycle a = Bicycle.create()
    local Bicycle b = Bicycle.create()

    set a.speed = 10.0
    set b.speed = 30.0

    call BJDebugMsg(R2S(a.speed))
    call BJDebugMsg(R2S(b.speed))
endfunction


So from the above, Bicycle a has a speed of 10.0 while Bicycle b has a speed of 30.0. So using a.speed would be different from using b.speed. You can imagine this as arrays. In an array form, a and b would be 1 and 2. Then a.speed would be speed[1] and b.speed would be speed[2]. I should also now mention that instances are basically integers. Thus you can do things like:
JASS:

struct Bicycle
endstruct

private function Test takes nothing returns nothing
    local Bicycle a = Bicycle.create()

    call BJDebugMsg(I2S(a)) // would display an integer
endfunction


Instances start at the value 1, all the way to 8190. 0 is reserved for another special purpose I believe. Thus, you can use Struct to easily make a spell that is MUI. Struct also have something called Methods. Methods are basically functions. However, inside a struct, you wouldn't call it a function. It would be a method. However, methods are special. Why? There are 2 types of methods. There is a Static Method and an Instance Method. I'll touch on Instance Methods first.

Instance methods are similar to instance variables. Instance methods basically do things like any other functions would do, except you refer to an instance. An example is needed again:
JASS:

struct Bicycle
    real speed

    method setSpeed takes real r returns nothing
        set this.speed = r
    endmethod
endstruct

private function Test takes nothing returns nothing
    local Bicycle d = Bicycle.create()

    call d.setSpeed(20.0) // calls the method &quot;setSpeed&quot;
endfunction


When you call an instance method, you notice you need to refer an instance, d.setSpeed. The d in front is basically saying that you're running the method setSpeed for instance d. Now let's look at the method itself. You would notice the syntax is pretty similar to a function, except it's "method" instead of "function". The next thing that could puzzle you is the syntax [ljass]this[/ljass]. [ljass]this[/ljass] basically refers to the instance that you associated with the method when you called it. Remember you did [ljass]call d.setSpeed[/ljass]? [ljass]this[/ljass] basically refers to d inside of the method setSpeed.

On the other hand, static methods are slightly different. Static methods have no instances associated with them. You can just imagine static methods as your normal functions, because static methods are your normal everyday function. They're just called static method inside a struct. Example:
JASS:

struct Bicycle
    static method print takes nothing returns nothing
        call BJDebugMsg(&quot;Hello!&quot;)
    endmethod
endstruct

private function Test takes nothing returns nothing
    call Bicycle.print()
endfunction


You would have noticed that this time, you don't need an instance to call the method. So basically, static methods are your normal functions. Just note that you need the struct name when you call a static method, thus Bicycle.print(). This is there to differentiate methods with the same name from different structs:
JASS:

struct A
    static method print takes nothing returns nothing
        call BJDebugMsg(&quot;A&quot;)
    endmethod
endstruct

struct B
    static method print takes nothing returns nothing
        call BJDebugMsg(&quot;B&quot;)
    endmethod
endstruct

private function Test takes nothing returns nothing
    call A.print() // calls the static method &quot;print&quot; inside struct A
    call B.print() // calls the static method &quot;print&quot; inside struct B
endfunction


The keyword static is basically a term to say that that certain thing isn't associated with an instance. Thus, there are also static variables inside a struct. Static variables are basically global variables inside a struct. They don't need an instance:
JASS:

struct Bicycle
    static integer count
endstruct

private function Test takes nothing returns nothing
     set Bicycle.count = 1 // sets the static integer &quot;count&quot; inside struct Bicycle to 1
endfunction


Lastly, you should also know that you can use the private and public keyword inside and for a struct. I hope this massive passage helped you understand struct a little better xD

OMG. This is by far the most useful thing I've read on structs. You must write more Jass tutorials! :thup:
 

Dirac

22710180
Reaction score
147
I don't wanna steal wolfie's thread, but i've always wondered: what's the advantage of creating an "static" method rather than a normal function (except of course the .create method) same thing goes to static variables, i mean wouldn't it just be better to create a normal global? since they're the same thing
 

Ayanami

칼리
Reaction score
288
I don't wanna steal wolfie's thread, but i've always wondered: what's the advantage of creating an "static" method rather than a normal function (except of course the .create method) same thing goes to static variables, i mean wouldn't it just be better to create a normal global? since they're the same thing

I think it's for encapsulation. Plus, I think it looks neater to code everything inside the struct rather than using functions, etc.
 
Reaction score
456
Static variable belongs to struct.

JASS:
struct Bicycle
    public static real maxSpeed = 100.00
endstruct

function ...
    BJDebugMsg(R2S(Bicycle.maxSpeed))


I think that makes more sense than:

JASS:
globals
    real BicycleMaxSpeed = 100.00
endglobals

struct Bicycle
endstruct

function ...
    BJDebugMsg(R2S(BicycleMaxSpeed))
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top