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

[JASS] Learning JASS. Last Question

Status
Not open for further replies.
SetUnitPosition(x, y) will make the unit jump to the point nearest where you want it to go that it is able to stand on. SetUnitX(x) / SetUnitY(y) will definitely put the unit exactly where you say, even if it shouldn't be able to stand there normally.
Does that means that I will need two variables; one for X and another for Y instead of just one variable, which is stepPoint in my case ?
 
Level 8
Joined
Aug 4, 2006
Messages
357
When it comes to stuff like programming, there is no "easy way". You have to learn by doing. Besides, it can be quite rewarding when you finally get something to work that you made all by yourself. You have to be willing to experiment and get your hands dirty to figure out how things work.
 
When it comes to stuff like programming, there is no "easy way". You have to learn by doing. Besides, it can be quite rewarding when you finally get something to work that you made all by yourself. You have to be willing to experiment and get your hands dirty to figure out how things work.

You are right programming is not easy but thanks for the hints.
 
I am trying to make the scipt for making an AoE nova, I have made a few things here.


JASS:
scope AoETemplate initializer Init
    private keyword Data
 
    globals
        private constant real TIMER_INTERVAL = 0.03
        private constant real DIST = 32
        private constant integer NOVA_SIZE = 36 // number of the Nova Units
        private constant integer UNIT_ID = 'e001' // rawcode of the Nova Unit
        private constant integer ABIL_ID = 'A001' // rawcode of the Dummy Spell
    endglobals
 
    private struct Data
        unit caster
        unit array Nova[NOVA_SIZE]
        player Owner
        real cx
        real cy
 
        static method NovaStart takes unit caster, location centre returns nothing
            local Data dat = Data.allocate()
            local integer i = 0
            local real A = 0
            local real dA = 360. / NOVA_SIZE
            local real dr = 0
            set dat.caster = caster
            set dat.Owner = GetOwningPlayer(dat.caster)
            set dat.cx = GetLocationX(centre)
            set dat.cy = GetLocationY(centre)
            loop
                exitwhen i == NOVA_SIZE
                set dat.Nova[i] = CreateUnit(Player(0),UNIT_ID,dat.cx,dat.cy,A)
                set A = A + dA
                set i = i + 1
            endloop
        endmethod
 
        static method NovaExpand takes nothing returns nothing
        endmethod
 
    endstruct
 
     private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == ABIL_ID
     endfunction
 
     private function Actions takes nothing returns nothing
        call Data.NovaStart(GetTriggerUnit(), GetSpellTargetLoc())
     endfunction
 
     private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST)
        call TriggerAddCondition(t,Condition(function Conditions))
        call TriggerAddAction(t,function Actions)
     endfunction
endscope

Is it going well ?
 


JASS:
scope AoETemplate initializer Init
    private keyword Data
 
    globals
        private constant real TIMER_INTERVAL = 0.03
        private constant real DIST = 32.00
        private constant real NOVA_RADIUS = 288.00 // radius of the Nova
        private constant integer NOVA_SIZE = 36 // number of the Nova Units
        private constant integer UNIT_ID = 'e001' // rawcode of the Nova Unit
        private constant integer ABIL_ID = 'A001' // rawcode of the Dummy Spell
    endglobals
 
    private struct Data
        unit caster
        unit array Nova[NOVA_SIZE]
        player owner
        real cx
        real cy
 
        static method NovaStart takes unit caster, location centre returns nothing
            local Data dat = Data.allocate()
            local integer i = 0
            local real A = 0.00
            local real dA = 360.00 / NOVA_SIZE
            local real dr = 0
            set dat.caster = caster
            set dat.owner = GetOwningPlayer(dat.caster)
            set dat.cx = GetLocationX(centre)
            set dat.cy = GetLocationY(centre)
            loop
                exitwhen i == NOVA_SIZE
                set dat.Nova[i] = CreateUnit(dat.owner,UNIT_ID,dat.cx,dat.cy,A)
                set A = A + dA
                set i = i + 1
            endloop
 
        endmethod
 
        static method NovaExpand takes nothing returns nothing
            local Data dat
            local integer index = 0
            local real r
            local real rmax = NOVA_RADIUS
            local real array nux[NOVA_SIZE]
            local real array nuy[NOVA_SIZE]
            // nova expanding
            loop
                exitwhen r == rmax
                call SetUnitX(dat.Nova[index],nux[index])
                call SetUnitY(dat.Nova[index],nuy[index])
                set index = index + 1
            endloop
 
            // nova damage
        endmethod
 
    endstruct
 
     private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == ABIL_ID
     endfunction
 
     private function Actions takes nothing returns nothing
        call Data.NovaStart(GetTriggerUnit(), GetUnitLoc(GetTriggerUnit()))
     endfunction
 
     private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t,Condition(function Conditions))
        call TriggerAddAction(t,function Actions)
     endfunction
endscope

I get error saying:
" Line 168: Unexprcted: [AoETemplate__NOVA_SIZE] "

Whats wrong ?




The nova don't expand what's wrong with my code ?


JASS:
scope AoETemplate initializer Init
    private keyword Data
 
    globals
        private constant real TIMER_INTERVAL = 0.5
        private constant real DIST = 32.00
        private constant real NOVA_RADIUS = 512.00 // radius of the Nova
        private constant integer NOVA_SIZE = 9 // number of the Nova Units
        private constant integer UNIT_ID = 'e001' // rawcode of the Nova Unit
        private constant integer ABIL_ID = 'A001' // rawcode of the Dummy Spell
        private timer tm
    endglobals
 
    private struct Data
        unit caster
        unit array Nova[NOVA_SIZE]
        player owner
        real cx
        real cy
        static method NovaExpand takes nothing returns nothing
            local Data dat = Data.allocate()
            local integer i2 = 0
            local real r = 0
            local real dr = DIST
            local real rmax = NOVA_RADIUS
            local real array nux
            local real array nuy
            local real A = 0.00
            local real dA = 360.00 / NOVA_SIZE
 
            // nova expanding
            loop
                exitwhen i2 == NOVA_SIZE
                set nux[i2] = dat.cx + r * Cos(A * bj_DEGTORAD)
                set nuy[i2] = dat.cy + r * Sin(A * bj_DEGTORAD)
                call SetUnitX(dat.Nova[i2],nux[i2])
                call SetUnitY(dat.Nova[i2],nux[i2])
                set r = r + dr
                set A = A + dA
                set i2 = i2 + 1
            endloop
 
            // nova damage
        endmethod
        static method NovaStart takes unit caster, location centre returns nothing
            local Data dat = Data.allocate()
            local integer i = 0
            local real A = 0.00
            local real dA = 360.00 / NOVA_SIZE
            set dat.caster = caster
            set dat.owner = GetOwningPlayer(dat.caster)
            set dat.cx = GetLocationX(centre)
            set dat.cy = GetLocationY(centre)
            loop
                exitwhen i == NOVA_SIZE
                set dat.Nova[i] = CreateUnit(dat.owner,UNIT_ID,dat.cx,dat.cy,A)
                set A = A + dA
                set i = i + 1
            endloop
 
            call TimerStart(tm,TIMER_INTERVAL,true,function Data.NovaExpand)
 
        endmethod
 
    endstruct
 
     private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == ABIL_ID
     endfunction
 
     private function Actions takes nothing returns nothing
        call Data.NovaStart(GetTriggerUnit(), GetUnitLoc(GetTriggerUnit()))
     endfunction
 
     private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t,Condition(function Conditions))
        call TriggerAddAction(t,function Actions)
        set tm = CreateTimer()
     endfunction
endscope

 
Last edited:
When writting
JASS:
struct Str
unit U
location P
real R
real A
method takes m1 takes unit u, location p, real r, real a returns Str
          local Str S = Str.allocate()
          set S.U = u
          set S.P = p
          set S.R = r
          set S.A = a
          return S
endmethod

What is the value of S when I say return S?

And if I want to use the value of the struct S in another method or function do I write
JASS:
method m2 takes nothing returns nothing
          local Str S = Str.allocate
          local unit UNIT = S.U
          local location LOC = S.P
          local real RADIUS = S.R
          local real ANGLE = S.A
endmethod
endstruct

will the values of m2 local variables be the same as in m1 ?
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
What is the value of S when I say return S?

A unique value between 1 and 8190 (can be higher if you explicitly need more). Each struct you create corresponds with such a value. When a struct variable is destroyed, the index is available again. For example:

set s = Str.create() // s is 1
set s = Str.create() // s is 2
set d = Str.create() // d is 3
call s.destroy() // the index "2" is available again
set d = Str.create() // d is 2

Note that there are 2 leaks here, since we never destroy the first S we created and the first d we created. Thus, indices 1 and 3 are still in use and cannot be recycled.

will the values of m2 local variables be the same as in m1 ?
No. Str.allocate() allocates new memory for U,P,R,A variables. When you use Str.allocate(), the variables themselves aren't initialized yet.
Thus, in m2 when you use Str.allocate(), U,P,R,A are still uninitialized. And thus UNIT, LOC, RADIUS and ANGLE too will be uninitialized because S.U, S.P, S.R, S.A don't have a value yet.

In m1, you allocate new memory for your U, P, R, A variables, and you change their values to u, p, r, a.
 
A unique value between 1 and 8190 (can be higher if you explicitly need more). Each struct you create corresponds with such a value. When a struct variable is destroyed, the index is available again. For example:

set s = Str.create() // s is 1
set s = Str.create() // s is 2
set d = Str.create() // d is 3
call s.destroy() // the index "2" is available again
set d = Str.create() // d is 2

Note that there are 2 leaks here, since we never destroy the first S we created and the first d we created. Thus, indices 1 and 3 are still in use and cannot be recycled.


No. Str.allocate() allocates new memory for U,P,R,A variables. When you use Str.allocate(), the variables themselves aren't initialized yet.
Thus, in m2 when you use Str.allocate(), U,P,R,A are still uninitialized. And thus UNIT, LOC, RADIUS and ANGLE too will be uninitialized because S.U, S.P, S.R, S.A don't have a value yet.

In m1, you allocate new memory for your U, P, R, A variables, and you change their values to u, p, r, a.
That means that in order to transfer the value of m1 to m2 I will need another variable of Str type but it must be global in that case. Right or Wrong ?
 
JASS:
scope AoETemplate initializer Init
    private keyword Data
    globals
        private constant real TIMER_INTERVAL = 0.02
        private constant real DIST = 32.00
        private constant real NOVA_RADIUS = 512.00 // radius of the Nova
        private constant integer NOVA_SIZE = 64 // number of the Nova Units
        private constant integer UNIT_ID = 'e001' // rawcode of the Nova Unit
        private constant integer ABIL_ID = 'A001' // rawcode of the Dummy Spell
        private timer tm
        private Data array temp_dat
        private integer index = 0
    endglobals
    private struct Data
        unit caster
        unit array Nova[NOVA_SIZE]
        player owner
        static real cx // cx: Centre X
        static real cy // cy: Centre Y
        static real r = 32.00 // current radius of the nova. initial value = 32.00
        static real dr = DIST // radius increment
        static real array nux[NOVA_SIZE]   // nux: Nova Unit X
        static real array nuy[NOVA_SIZE]   // nuy: Nova Unit Y
        static method NovaExpand takes nothing returns nothing
            local Data dat
            local integer i = 0
            local real rmax = NOVA_RADIUS
            local real A = 0
            local real dA = 360.00 / NOVA_SIZE
//      nova expanding
            loop
                exitwhen i >= NOVA_SIZE
                set dat = temp_dat[i]
                set dat.nux[i] = Data.cx + Data.r * Cos( A * bj_DEGTORAD )
                set dat.nuy[i] = Data.cy + Data.r * Sin( A * bj_DEGTORAD )
                call SetUnitX( dat.Nova[i] , Data.nux[i] )
                call SetUnitY( dat.Nova[i] , Data.nuy[i] )
                set i = i + 1
                set A = A + dA
            endloop
            
            if Data.r >= rmax then
                call dat.destroy()
            endif
            
            set Data.r = Data.r + Data.dr
        endmethod
        static method NovaCreate takes unit caster, location centre returns Data
            local Data dat = Data.allocate()
            local integer i = 0
            local real A = 0.00
            local real dA = 360.00 / NOVA_SIZE
            set dat.caster = caster
            set dat.owner = GetOwningPlayer(dat.caster)
            set Data.cx = GetLocationX(centre)
            set Data.cy = GetLocationY(centre)
            loop
                exitwhen i >= NOVA_SIZE
                set dat.Nova[i] = CreateUnit( dat.owner , UNIT_ID , dat.cx , dat.cy , A )
                set A = A + dA
                set i = i + 1
            endloop
            
            if index == 0 then
                call TimerStart(tm,TIMER_INTERVAL,true,function Data.NovaExpand)
            endif
            
            set temp_dat[index] = dat            
            set index = index + 1
            return dat
        endmethod
        method onDestroy takes nothing returns nothing
            local integer i = 0
            call PauseTimer(tm)
            loop
                exitwhen i >= NOVA_SIZE
                call KillUnit(.Nova[i])
                set .Nova[i] = null
                set i = i + 1
            endloop
            set index = index - 1
        endmethod
    endstruct
     private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == ABIL_ID
     endfunction
     private function Actions takes nothing returns nothing
        call Data.NovaCreate(GetTriggerUnit(), GetUnitLoc(GetTriggerUnit()))
     endfunction
     private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t,Condition(function Conditions))
        call TriggerAddAction(t,function Actions)
        set tm = CreateTimer()
     endfunction
endscope

The nova expands to infinity and after a few seconds the game craches, I tried to destroy the struct but why onDestroy function hasn't been called ?

(Please, help me and don't ignore me this time)
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
I didn't have time to look through the whole thing, but it seems to me like you're only destroying one "dat" when you should put your if/then/else in the loop to check every struct.

I don't get this thread. So you're basically reading Vexorian's jasshelper manual and posting here immediately when you don't understand something? Why don't you just take your time and read those stuff multiple times? It's how complicated manuals should be read anyways.
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
A stub method is a method that can be expanded by a struct's children.

For example:

JASS:
struct Parent
    stub method sayHello takes nothing returns nothing
        call BJDebugMsg("Hello from the parent!")
    endmethod
endstruct

struct Child extends Parent // see: extend
    stub method sayHello takes nothing returns nothing // See: sayHello is already defined by the parent struct. This is not allowed, except when the method is a stub method.
        call BJDebugMsg("Hello from the child!")
    endmethod
endstruct

struct Grandchild extends Child
    stub method sayHello takes nothing returns nothing
        call super.sayHello() // super refers to the original struct, i.e. "Parent".
    endmethod
endstruct

struct Child2 extends Parent
    // We don't HAVE to redefine sayHello
endstruct

// In your code:
local Parent p = Parent.create()
local Parent c = Child.create() // Note: this is of local type "Parent", but it IS in fact a Child.
local Parent g = GrandChild.create()
local Child2 c2 = Child2.create()

call p.sayHello() // displays: "Hello from the parent!"
call c.sayHello() // displays: "Hello from the child!"
call g.sayHello() // displays: "Hello from the parent!" --> because g calls super.sayHello()
call c2.sayHello() // displays: "Hello from the parent!" --> because Child2 did not redefine sayHello, it simply uses sayHello that was already defined by Parent.
 
JASS:
struct Test
    private real x
    private real y
    unit u
    method operator x= takes real x returns nothing
        call SetUnitX(.u, x)
        set .x = x
    endmethod
    method operator x takes nothing returns real
        return .x
    endmethod
    method operator y= takes real y returns nothing
        call SetUnitY(.u, y)
        set .y = y
    endmethod
    method operator y takes nothing returns real
        return .y
    endmethod
endstruct

This is a common use of a method operator. Basically, putting the operator keyword there means you can call a method like it's just a variable. This means you can make the assignment of variables change things, such as the unit's position, really easily.
 
Level 8
Joined
Aug 4, 2006
Messages
357
// In your code:
local Parent g = GrandChild.create()

call g.sayHello() // displays: "Hello from the parent!" --> because g calls super.sayHello()[/code]
Actually, it displays: "Hello from the child!" (I tested it). super actually gives you the struct that this struct extends from. Since GrandChild extends Child, it calls Child.sayHello().

@Starguizer
JASS:
library Table
//***************************************************************
//* Table object 3.0
//* ------------
//*
//*   set t=Table.create() - instanceates a new table object
//*   call t.destroy()     - destroys it
//*   t[1234567]           - Get value for key 1234567
//*                          (zero if not assigned previously)
//*   set t[12341]=32      - Assigning it.
//*   call t.flush(12341)  - Flushes the stored value, so it
//*                          doesn't use any more memory
//*   t.exists(32)         - Was key 32 assigned? Notice
//*                          that flush() unassigns values.
//*   call t.reset()       - Flushes the whole contents of the
//*                          Table.
//*
//*   call t.destroy()     - Does reset() and also recycles the id.
//*
//*   If you use HandleTable instead of Table, it is the same
//* but it uses handles as keys, the same with StringTable.
//*
//*  You can use Table on structs' onInit  if the struct is
//* placed in a library that requires Table or outside a library.
//*
//*  You can also do 2D array syntax if you want to touch
//* mission keys directly, however, since this is shared space
//* you may want to prefix your mission keys accordingly:
//*
//*  set Table["thisstring"][ 7 ] = 2
//*  set Table["thisstring"][ 5 ] = Table["thisstring"][7]
//*
//***************************************************************

//=============================================================
    globals
        private constant integer MAX_INSTANCES=8100 //400000
        //Feel free to change max instances if necessary, it will only affect allocation
        //speed which shouldn't matter that much.

    //=========================================================
        private hashtable ht
    endglobals

    private struct GTable[MAX_INSTANCES]

        method reset takes nothing returns nothing
            call FlushChildHashtable(ht, integer(this) )
        endmethod

        private method onDestroy takes nothing returns nothing
            call this.reset()
        endmethod

        //=============================================================
        // initialize it all.
        //
        private static method onInit takes nothing returns nothing
            set ht = InitHashtable()
        endmethod

    endstruct

    //Hey: Don't instanciate other people's textmacros that you are not supposed to, thanks.
    //! textmacro Table__make takes name, type, key
    struct $name$ extends GTable

        method operator [] takes $type$ key returns integer
            return LoadInteger(ht, integer(this), $key$)
        endmethod

        method operator []= takes $type$ key, integer value returns nothing
            call SaveInteger(ht,  integer(this)  ,$key$, value)
        endmethod

        method flush takes $type$ key returns nothing
            call RemoveSavedInteger(ht, integer(this), $key$)
        endmethod

        method exists takes $type$ key returns boolean
            return HaveSavedInteger( ht,  integer(this)  ,$key$)
        endmethod

        static method flush2D takes string firstkey returns nothing
            call $name$(- StringHash(firstkey)).reset()
        endmethod

        static method operator [] takes string firstkey returns $name$
            return $name$(- StringHash(firstkey) )
        endmethod

    endstruct
    //! endtextmacro

    //! runtextmacro Table__make("Table","integer","key" )
    //! runtextmacro Table__make("StringTable","string", "StringHash(key)" )
    //! runtextmacro Table__make("HandleTable","handle","GetHandleId(key)" )

endlibrary

Basically, operators are methods with different notation in vJass. The only types of method operators supported are "[]", "[]=", "<", and ">" (Edit: and the kind EOW talks about above). They are converted to regular method calls when you compile your map from vJass to regular Jass. "[]" is converted to a method that takes one parameter and returns something. "[]=" takes two parameters and returns nothing. "<" takes one parameter and returns a boolean. ">" takes one parameter and returns a boolean. Why would you want methods with different notation? Sometimes the modified notation is easier to understand and shorter to write.

Let's look at how [] and []= operators work with Table. Suppose we make a Table object of integers.
JASS:
local Table intTable = Table.create()
Then let's store the integer 5 at index 20.
JASS:
set intTable[20] = 5
Wasn't that easy? It's just like storing stuff in an array. Suppose instead Vexorian used a regular method "setIndex" that takes two parameters.
JASS:
call intTable.setIndex(20, 5)
Hmm... that's longer to type and not as easy to understand. Which one is the index and which is the integer we're storing? They're both in the parentheses so it's hard to tell. I like using the method operator better. Anyway, the method operator []= is really just a method in disguise. When vJass compiles, it creates a setindex method whose first parameter is the stuff between the [] and whose second parameter is the stuff after the =.
Now let's get the integer we stored at index 20.
JASS:
intTable[20]
Again, that was easy and intuitive. Better than having to do intTable.getIndex(20).
You still may be wondering what the static method operator [] does. Well, since it's static, it has to be called with the struct name. It takes a string and returns an instance of the struct. So, we can do Table["category1"]. Used by itself, this static method operator is useless. However, since it returns a struct instance, we can use it in combination with the regular method operators. For example,
JASS:
set Table["category1"][0] = 4
Just pretend that it said "intTable" instead of "Table["category1"]".

Anyway, I think that's enough for now. Just remember that method operators are really just methods with different syntax and limited uses.
 
When I tested the manual example.

JASS:
    struct operatortest
        string str=""

        method operator [] takes integer i returns string
            return SubString(.str,i,i+1)
        endmethod

        method operator[]= takes integer i, string ch returns nothing
            set .str=SubString(.str,0,i)+ch+SubString(.str,i+1,StringLength(.str)-i)
        endmethod

    endstruct


    function test takes nothing returns nothing
     local operatortest x=operatortest.create()
        set x.str="Test"
        call BJDebugMsg( x[1])
        call BJDebugMsg( x[0]+x[3])

        set x[1] = "."
        call BJDebugMsg( x.str)
    endfunction

It gave me during test:

e
Tt
T.s

But when I tracked it, I get different result:

Te
Tst
T.es

At the line call BJDebugMsg(x[1])

i = 1 then the operator [] method return will be like this:
SubString("Test",1,2) = Te

And at the line call BJDebugMsg(x[0] + x[3])

i = 0 then the operator [] method return will be:
SubString("Test",0,1) = T

i = 3 then SubString("Test",3,4) = st

When concatinated: Tst

for the last one:
i = 1 , ch = "."
SubString("Test",0,1) + "." + SunString("Test",2,3) = T.es

I know this may seems nonsense but that is what I get. Anyway I get different results from game testing.
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
Element of Water: that won't compile because you're redefining x as an operator when it's already defined as a real.

Mathematically speaking, an operator is "+", "-", "/", "*", "=", etc.
There are some non-mathematical operators such as () for functions and [] for arrays.

vJass allows you to redefine the [] operator, as well as the [] = operator. Table is a good example of this: the Table struct redefines [] and []= so you can use handles and strings as indices.
e.g.
table[GetTriggerUnit()] = 5
==> normally, you must use integers inbetween [] for arrays (e.g. arr[0]) but struct HandleTable has redefined the [] operator so you can use handles too.

In addition to this, vJass allows you to create your own pseudo-operators. A pseudo-operator is just like a method, except that it doesn't require () to be called. For example:

JASS:
struct Test
    private real fx

    method getX takes nothing returns real
        return this.fx
    endmethod

    method operator x takes nothing returns real
        return this.fx
    endmethod
endstruct

// in a function:
local Test s = Test.create()
local real x = s.getX() // notice the ()
local real y = s.x // notice no () are used.
set s.x = 5 // NOT ALLOWED. s.x is an operator, NOT a variable, therefor you cannot assign a new value to it.
In this example, s.x returns this.fx. Why can it be useful? Since this.fx is private, you cannot read the value of fx outside the struct. To solve this you could make a new method, or you could create a new operator. The advantage of the operator is that it looks like no method is being called, as if you're directly reading x.
 
So Whats wrong with what I said in post #226 ?

I found what is the problem, it seems SubString is different than SubStringBJ in the start and end integers.

JASS:
function SubStringBJ takes string source, integer start, integer end returns string
    return SubString(source, start-1, end)
endfunction

Thanks for any attempts to help me.
 
Level 8
Joined
Aug 4, 2006
Messages
357
Eleandor, when you want to be able to get a variable directly but not modify it, I think it's easier to specify the variable as readonly. You can put "readonly real fx" instead of "private real fx" and it will allow you to do the same thing without making method operators. However, when you need to do more than just return a variable (or set a variable), operators can be useful.
 
Tracking of triggers and functions???

Yes, like in loops you track the loop's index and see how variables' value change, its a slow method but effective especially when a code contains an error some where. Its like when you insert a msg function to display the value of a certain variable. That's what I mean by tracking a code.
 
You can't learn by doing that. You just correct stuff.

OK, then how do you learn then; I really can't understand Vexorian's table. Do I need to understand how it works or I just take it as it is (which is a thing I don't like, like when some of my collegues tell me that I apply an equation as it is without understanding it, Sorry if that has drifted away from the subject)
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
When it comes to using libraries, you need to know how to use them, not how they work internally. Now, knowing how they work can be interesting, but knowing how to use them is the only thing you really *need* to know. How they work won't help you when it comes to problem solving. Especially in "early" stages of learning a language, you should know how to use it. If you become more experienced you may get to understand how it works behind the scenes.

Nevertheless, feel free to ask more *specific* questions related to how Table works. Or how to use it, in case you don't know that either.
 
In the table I found text macros, when I tried to learn how to use them I make a function using them but I get a syntax error. The function is like that:

JASS:
//! textmacro TextMacroName takes DISPTEXT
function Message$DISPTEXT$ takes nothing returns nothing
    Call DisplayTimedTextToPlayer(Player(0),0,0,10,"$DISPTEXT$ Test" )
endfunction
//! endtextmacro
function exe takes nothing returns nothing
    //! runtextmacro TextMacroName("Integer")
    //! runtextmacro TextMacroName("Real")
    //! runtextmacro TextMacroName("Unit")
endfunction
function InitTrig_text_macro takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent(t,Player(0),"tm",false)
    call TriggerAddAction(t, function exe )
endfunction

What error did I made ?
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
"Call" should be "call", with lowercase c.

Another mistake you made is running your textmacro inside a function.
This is what happens when a textmacro is compiled:

Everything between
//! textmacro blabla
and
//! endtextmacro
is copied into each line containing //! runtextmacro blabla, and the parameters are being replaced.

In your example, this is how your resulting code looks like:
JASS:
function exe takes nothing returns nothing
    function MessageInteger takes nothing returns nothing
        call DisplayTimedTextToPlayer(Player(0),0,0,10,"Integer Test" )
    endfunction
    function MessageReal takes nothing returns nothing
        call DisplayTimedTextToPlayer(Player(0),0,0,10,"Real Test" )
    endfunction
    function MessageUnit takes nothing returns nothing
        call DisplayTimedTextToPlayer(Player(0),0,0,10,"Unit Test" )
    endfunction
endfunction
function InitTrig_text_macro takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent(t,Player(0),"tm",false)
    call TriggerAddAction(t, function exe )
endfunction

As you can see, the actual textmacro is removed, and each //! runtextmacro line is replaced by the code written in the textmacro.
In this case, you have written 3 functions INSIDE a function, which is obviously not allowed.
 
I have changed it to that:

JASS:
//! textmacro TextMacroName takes DISPTEXT
    call DisplayTimedTextToPlayer(Player(0),0,0,10,"$DISPTEXT$ Test" )
//! endtextmacro
function exe takes nothing returns nothing
    //! runtextmacro TextMacroName("Integer")
    //! runtextmacro TextMacroName("Real")
    //! runtextmacro TextMacroName("Unit")
endfunction
function InitTrig_text_macro takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent(t,Player(0),"tm",false)
    call TriggerAddAction(t, function exe )
endfunction

Now its working, thanks to your detailed explanation, Eleandor.
 
Level 5
Joined
Nov 22, 2009
Messages
181
Posted by Silvenon
Yeah. People who work in GUI have a different concept of a trigger. They think that a trigger is something that in fact is some kind of a "folder" where you can have multiple triggers.
This is so true. i was stumped and thought a function was the same as a trigger.
 
Status
Not open for further replies.
Top