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!
struct pair
integer x=1
integer y=2
endstruct
function pair_sum takes pair A, pair B returns pair
local pair C=pair.create()
set C.x=A.x+B.x
set C.y=A.y+B.y
return C
endfunction
function testpairs takes nothing returns nothing
local pair A=pair.create()
local pair B=pair_sum(A, A)
local pair C=pair_sum(A,B)
call BJDebugMsg(I2S(C.x)+" : "+I2S(C.y))
//Dont forget, if you are not using an struct instance anymore, you destroy it
call B.destroy()
call C.destroy()
call pair.destroy(A)
endfunction
It would display "3 : 6"
this what the manual says
globals can only be initialized by constants.
0 = a constant
pair.create() is a variable
The same goes for e.g. units:
null = a constant
CreateUnit(...) is a variable and isn't allowed either (if it's allowed by the compiler, it still won't work in-game)
That's also a good reason why you would use initializers.
Well that explains lot. Thanks
________________________
What are static members ? And their purpose ?
________________________
JASS:
scope cool
public struct a
integer x
endstruct
globals
a x
public a b
endglobals
public function test takes nothing returns nothing
set b = a.create()
set b.x = 3
call b.destroy()
endfunction
endscope
function test takes nothing returns nothing
local cool_a x=cool_a.create()
set a.x=6
call a.destroy()
endfunction
In the globals block, removing public keyword from
Static members can be called on the type of the struct, instead of on an instance of the type. For example:
JASS:
struct Test
static method func takes nothing returns nothing
endmethod
method func2 takes nothing returns nothing
endmethod
endstruct
function One takes nothing returns nothing
local Test t = Test.create()
call t.func2()
call t.destroy()
call Test.func() // I don't need a variable t to be able to call func
endfunction
Yes. By using the public qualifier you can use b outside the scope by refering to it as "cool_b".
Without the public qualifier, you would use "b" instead of "cool_b".
With a private qualifier, you cannot reach variable b from outside the scope.
No. If you make a public, then you must use cool_a outside the scope. Else, you can use "a".
JASS:
scope cool
public struct Cooler
integer x
endstruct
globals
private Cooler a
public Cooler b
Cooler c
endglobals
public function test takes nothing returns nothing
set a = Cooler.create()
set a.x = 3
call a.destroy()
endfunction
endscope
function test takes nothing returns nothing
set c = Cooler.create()
set cool_b = Cooler.create() // since b is a public variable, it can only be reached outside the scope through adding a prefix "cool_".
set cool_a = Cooler.create() // this is not allowed because a is private
endfunction
Sorry if anyone already said this, but the Map Initialisation is nowhere.
Basicly its hidden in the InitTrig_Initialization function, which is called 'INIT' + 'TRIGGER' + 'NAME' Function. Basicly that runs the trigger on mapinit.
And how to learn: Everyone has another way (someone already pointed it out). I learned it by converting my GUI spells to vJASS, reading alot of Tutorials here and at Wc3c and getting teached by a few good projassers here.
struct point
real x=0.0
real y=0.0
method move takes real tx, real ty returns nothing
set this.x=tx
set this.y=ty
endmethod
endstruct
function testpoint takes nothing returns nothing
local point p=point.create()
call p.move(56,89)
call BJDebugMsg(R2S(p.x))
endfunction
When I say
JASS:
call p.move(56,89)
this means that tx = 56 and ty = 89 and set this.x = tx will set the real x to the value of tx (which is 56) and the same for ty. If what I said is right, what is the function of method keyword; I can set the value of point p in another function.
This simply doesn't make any sense at all. Try to use more words and a better sentence speach. What you said is right, but I doubt I understand what this sentence was trying to mean.
This simply doesn't make any sense at all. Try to use more words and a better sentence speach. What you said is right, but I doubt I understand what this sentence was trying to mean.
The purpose of the keyword is to use it when you want. I've spent the last few weeks coverting spells to vjass and I haven't once used methods. The important part is that you can.
The purpose of the keyword is to use it when you want. I've spent the last few weeks coverting spells to vjass and I haven't once used methods. The important part is that you can.
Sorry if anyone already said this, but the Map Initialisation is nowhere.
Basicly its hidden in the InitTrig_Initialization function, which is called 'INIT' + 'TRIGGER' + 'NAME' Function. Basicly that runs the trigger on mapinit.
It's not hidden in there. Regardless of what event you use, InitTrig ALWAYS runs on map initialization. The "map initialization" event in GUI is converted to a "run on map init" checkbox on top of your trigger. InitTrig has nothing to do with the event.
The special thing about "map initialization" event is that it runs Trig_Initialization_Actions function, and not the InitTrig_Initialization function.
this means that tx = 56 and ty = 89 and set this.x = tx will set the real x to the value of tx (which is 56) and the same for ty. If what I said is right, what is the function of method keyword; I can set the value of point p in another function.
Well, one reason would be that you can convert a lot of "set x = y" lines to 1 single line. For example:
call point.move(x, y)
would otherwise have to be written as
set point.x = x
set point.y = y
Secondly, it's a common rule to make variables inside structs private. This means that any struct's member cannot be reached from outside the struct, e.g.
JASS:
struct point
private real x=0.0
private real y=0.0
method move takes real tx, real ty returns nothing
set this.x=tx
set this.y=ty
endmethod
endstruct
function testpoint takes nothing returns nothing
local point p=point.create()
call p.move(56,89) // this is allowed now
set p.x = 56 // this is not allowed, since p.x is only visible to the struct itself, not to code using the struct.
call BJDebugMsg(R2S(p.x))
endfunction
Thirdly, methods are basically functions that are "owned" by the struct, and written specifically for this struct. It can have many advantages, modularity being one of them.
Another advantage is that you hide the implementation of your new variable. Let's say I have:
I, as a jass scripter who wants to use the Car struct, don't have to worry about making sure BOTH wheels turn to the left if I wish to turn. All I have to say is:
local Car c = Car.create()
call c.turn(false)
I never have to bother about thinking of turning both wheels, and I never have to worry about forgetting to turn one of my front wheels. I am certain that if I ask my car to turn to the left, my car will take care of the details. It's like in real life: if I turn left, I don't worry about making sure my left- and my rightwheel both turn to the same direction. I assume that whoever made the car has made sure it turns like it's supposed to turn.
Whenever you need to make a function that is very strongly related to your struct, you should make it a method.
Some other examples:
local Vector3D v1 = Vector3D.create(1, 2, 5)
local Vector3D v2 = Vector3D.create(5, 1, 0)
local Vector3D v3 = v1.sum(v2) // v3 is equal to v1 + v2. "sum" is a method of Vector3D, because it makes the sum of 2 vectors. Rather than having to say
set v3.x = v1.x + v2.x
set v3.y = v1.y + v2.y
set v3.z = v1.z + v2.z
// I can simply make the sum since it's part of vectors.
// Another good thing is that by saying v3 = v1.sum(v2), I hide the implementation of adding v1 to v2, so the implementation is hidden. When you decide to change the implementation of a vector (to make it more efficient, for example), you don't need to change ALL your code that sets v3.x = v1.x + v2.x. No, all you have to do is modify how the sum method works.
The purpose of the keyword is to use it when you want. I've spent the last few weeks coverting spells to vjass and I haven't once used methods. The important part is that you can.
Good code should use methods. If you avoid methods, because you don't need to use them, then why bother using vJass anyway because in the end, there's nothing vJass can do that jass can't do...
Methods are just functions in a struct, don't let it scare you
One question to Eleandor, why making a struct member private? I know that I make functions private because I don't want them to conflict with other functions, so I can for example have tons of private function Actions takes nothing returns nothing, but struct members can't conflict with anything, because it gets the prefix after the struct name, right?
The only reason I can think of right now would be in case when interfaces are involved...
EDIT: Hmm, it seems that [icode=jass] tags don't highlight the word "nothing" correctly.
It's not hidden in there. Regardless of what event you use, InitTrig ALWAYS runs on map initialization. The "map initialization" event in GUI is converted to a "run on map init" checkbox on top of your trigger. InitTrig has nothing to do with the event.
The special thing about "map initialization" event is that it runs Trig_Initialization_Actions function, and not the InitTrig_Initialization function.
Am I totally wrong or are you wrong? I mean the INIT_TRIG_XXX activated the trigger to be runned on the map init. The function which is runned is the _Action function, but without the init trigger, the action function won't be runned, would it?
Am I totally wrong or are you wrong? I mean the INIT_TRIG_XXX activated the trigger to be runned on the map init. The function which is runned is the _Action function, but without the init trigger, the action function won't be runned, would it?
I noticed that in GUI if you have the event |Map Initialization| then turned the trigger to custom text there is a check box above says "Run on Map Initialization", when I deleted the event |Map Initialization| I found the the check box is unchecked. Also, every trigger that don't have this event I found the check box is unchecked which means that in order to run the trigger at map initialization you need only to check that box and there is no function or special name for the trigger to run at map initialization.
Also, I don't understand the purpose of using interface ?
________________________________________________
When I say
JASS:
struct complex
real r
real i
endstruct
function ComplexNumber takes real r1 , real r2 returns complex
local complex C = complex.create()
return C
endfunction
Is C called an Instance ? and if I used static keyword I don't need to make the Instance C; just use the struct type (complex). Is that right ?
it's good to make struct variables private to create a sense of encapsulation. encapsulation allows structs to fulfill their intended purpose without being tampered with from the outside. say you have a "watch" struct. on the inside, it works in complicated ways with gears and electronics that interact with each other. from the outside, all you care about is that the watch keeps track of time, and can tell you the current time when you ask for it. you don't want to be able to access those gears and things individually because you might screw them up and keep the struct from telling you the proper time. you would want to use private methods and variables for all the internal time keeping. the only thing you would want to be public would be a method that tells the current time and a method that allows you to reset the time.
@Starquizer 1) When I say a struct member, the word member does it include structs or just the standard variable-types ?
I am actually getting a little confused over what the word "member" means. sorry.
2) What is meant by class as in the manual:
the word "class" is synonymous with "struct", in this case. what the manual means is that methods are functions that are defined inside a struct.
3) What is the difference between static and instance ?
an instance of a struct is a variable that is defined as that struct variable. for example,
JASS:
struct cup
real radius
real height
endstruct
//this is creating an instance of the cup struct
cup fattyCup = cup.create()
set fattyCup.radius = 500
set fattyCup.height = 800
static variables or methods are things that are the same for the whole struct. did you notice that to create an instance of the cup class we did "cup.create()"? create is a static method! it makes sense that all cups should be created in the same manner. here's another example of static usage.
JASS:
struct cup
private real radius
private real height
private static string description = "this is the cup struct"
static method printDescription takes nothing returns nothing
call BJDebugMsg(cup.description)
endmethod
endstruct
//then you could do
call cup.printDescription()
//and it would display "this is the cup struct"
notice that i made the static description variable private? this is so that outside sources cannot set cup.description = "this is a gay struct. roflcopter. owned" (or something else) yet we can still display the description.
One question to Eleandor, why making a struct member private? I know that I make functions private because I don't want them to conflict with other functions, so I can for example have tons of private function Actions takes nothing returns nothing, but struct members can't conflict with anything, because it gets the prefix after the struct name, right?
Firstly because it's considered to be a rule amongst programmers. It's a design choice to hide the implementation of your structs.
Just look at units. To get the unit's hit points you must use GetUnitState(u, UNIT_STATE_LIFE). They've written a function that does this. They could have also just added something like set u.hitpoints = u.hitpoints +5, but then didn't.
Secondly because it can be the cause of bugs. To give a similar example with units:
If I could say:
set u.hitpoints = -1
Then the unit would STILL be on the map, because u.hitpoints is nothing more than a variable. Still, it would be logical to assume a unit to be dead when he's got negative hit points, right?
SetUnitState() however takes care of other details too. On top of changing u.hitpoints, SetUnitState also checks if the new hitpoints are negative. If it's negative, SetUnitState will make sure the unit actually dies. Therefor, it is important that you, as the programmer of the new datatype, make sure that whoever uses the datatype uses it correctly, in order to avoid bugs.
Often it will still be useful to make members readonly. As you could guess from the name: this means you can "read" the member but cannot modify it (unless through methods). This allows you to safely retrieve info from a struct without screwing things up.
1) When I say a struct member, the word member does it include structs or just the standard variable-types ?
struct MyStruct
private integer var // this is a member
method Test takes nothing returns nothing // this is also a member.
endmethod
// Still, 90% of the time that we speak of structmembers, we refer to the variables, and not to the methods. Generally, the "variables" are the struct's members, and the "functions" are the struct's methods.
structs and classes, while not being completely the same in many languages, are the same thing in jass. Well, technically, there's no such thing as a "class" in jass. But talking about classes and talking about structs is talking about the same thing.
3) What is the difference between static and instance ?
Let me give some examples to explain the terminology:
JASS:
struct Human
readonly string name
public static integer default_legs = 2
readonly integer legs = 2
method CarAccident takes nothing returns nothing
set this.legs = 1 // ouch
endmethod
endstruct
// ...
local Human eleandor = Human.create()
local Human starguizer = Human.create()
call eleandor.CarAccident()
call BJDebugMsg(I2S(eleandor.legs)) // display 1
call BJDebugMsg(I2S(eleandor.default_legs)) // display 2
set eleandor.default_legs = 1 // I know: wtf am I doing now?
call BJDebugMsg(I2S(starguizer.default_legs)) // display 1
A "Human" is a definition. It "defines" what a Human is. In this case, a Human is defined as something that has a name, and an amount of legs.
eleandor is called an "instance" of a human. eleandor behaves like a human, but has specific characteristics. In this case, I've had a caraccident which is why I only have 1 leg. But even though I have special attributes, I'm still a human. Because I'm able to have special attributes, I'm called an "instance" of a human.
You too are an "instance" of a Human.
eleandor.legs will clearly display "1", because I only have 1 leg.
eleandor.default_legs will show "2". default_legs is the same for every instance of "Human". It is an attribute of "Humans" in general.
If eleandor.default_legs would be changed into 1, starguizer.default_legs TOO will now be 1. However, starguizer.legs will still be 2.
static methods or static variables are variables that are "generic", they count for the whole struct type. normal methods/variables however perform specific actions on an instance of a struct. For example: a specific instance can have a car accident which changes that specific instance's legs.
The same is said for other variables:
local unit u = CreateUnit(...) // u is an "instance" of type "unit".
P.s. I still have both legs, this is just an example
P.p.s. ok, maybe that's a really strange example... but it's the best I can do
P.p.p.s. Indeed, "C" in your example is an instance of the "complex" type.
Am I totally wrong or are you wrong? I mean the INIT_TRIG_XXX activated the trigger to be runned on the map init. The function which is runned is the _Action function, but without the init trigger, the action function won't be runned, would it?
No, you're wrong (sorry )
The InitTrig action runs on map initialization, regardless of whether you want or not. InitTrig makes sure the trigger itself gets initialized by adding events, conditions and actions to it.
Without the InitTrig function, there IS no trigger.
However, through 'run on map init', you can run the Actions, regardless of whatever you wrote in InitTrig.
Also, I don't understand the purpose of using interface ?
An interface is there so you can use the same rules for your structs. For example, if you implement:
JASS:
interface Creature
method moveTo takes real x, real y returns nothing
endinterface
struct Human extends Creature // Notice: a human "extends" a Creature. It means that a Human "is" a creature, just with some more specific features
method moveTo takes real x, real y returns nothing
// Do stuff to make the human move
endmethod
endstruct
struct Fish extends Creature
method moveTo takes real x, real y returns nothing
// Do different stuff to make the fish move
endmethod
endstruct
// Somewhere...
local Creature c = Human.create() // c is of type "Human" but can also be called "Creature" because a "Creature" is a more general way of calling you "Human".
local Creature d = Fish.create()
call c.moveTo(-2.0, 52.0)
call d.moveTo(-5.0, 50.0)
A struct that extends an interface inherits all of the interface's abilities (this means: a struct must have all the interface's members and methods), and is supposed to extend on this interface.
I personally don't use interfaces now that struct inheritance & stub methods are possible (read more on this further in the vjass manual).
Yes, I know its an example but a funny one
________________________________________________
JASS:
interface withpos
real x
real y
endinterface
struct rectangle extends withpos
real a
real b
static method from takes real x, real y, real a, real b returns rectangle
local rectangle r=rectangle.create()
set r.x=x
set r.y=y
set r.a=a
set r.b=b
return r
endmethod
endstruct
struct circle extends withpos
real radius=67.0
static method from takes real x, real y, real rad returns circle
local circle r=circle.create()
set r.x=x
set r.y=y
set r.radius=rad
return r
endmethod
endstruct
function distance takes withpos A, withpos B returns real
local real dy=A.y-B.y
local real dx=A.x-B.x
return SquareRoot( dy*dy+dx*dx)
endfunction
function test takes nothing returns nothing
local circle c= circle.from(12.0, 45.0 , 13.0)
local rectangle r = rectangle.from ( 12.3 , 67.8, 12.0 , 10.0)
call BJDebugMsg(R2S(distance(c,r)))
endfunction
Will the message displayed be 22.801 ?
If it is right then I have understood how interface works.
Also another question, the function distance takes withpos A, withpos B yet when it was called through BJDebugMsg(R2S(distance(c,r)) neither c nor r are withpos, this is allowed because both circle and rectangle extend withpos ?
class withpos
{
...
};
class rectangle:public withpos
{
...
};
class circle:public withpos
{
...
};
float distance(withpos* A,withpos* B)
{
...
}
It isn't important to you, don't worry about it.
Also, about the "what's the difference between a struct and a class" question - originally in the 'C' programming language you could define your own data types called structures (structs for short) which could contain other data types inside them (not functions).
Later on, 'C++' - which is kind of an extension to C - added 'classes', which are structs, but you can also put instance functions in them (aka methods). In C++ you can also do this to structs, so today they basically have no differences (there are a few, but they don't really matter).
Anyway, most programming languages today just have classes, which are equivalent to JASS's structs.
interface A
integer x
endinterface
struct B extends A
integer y
endstruct
struct C extends A
integer y
integer z
endstruct
function test takes A inst returns nothing
if (inst.getType()==C.typeid) then
// We know for sure inst is actually an instance of type C
set C(inst).z=5 //notice the typecast operator
endif
if (inst.getType()==B.typeid) then
call BJDebugMsg("It was of type B with value "+I2S( B(inst).y ) )
endif
endfunction
1) How can we compare inst type (Which is an interface) by C type (Which is a struct) like in this line
JASS:
inst.getType()==C.typeid
2) C(inst).z What is this argument of C; C is a struct type how can a it take an argument, also the integer z is already in C struct so I should say
You would like to know the type of the sturct in case it has different members and/or methods then the other extending structs.
Here's an example:
JASS:
interface Rect
real x
real y
real z // not really needed in warcraft
method setPosition takes real x,real y,real z returns nothing
.x = x
.y = y
.z = z
endmethod
endinterface
struct Rect2D extends Rect
real width
real length
method setSize takes real width,real length returns nothing
.width = width
.length = length
endmethod
endstruct
struct Rect3D extends Rect
real width
real length
real height
method setSize takes real width,real length,real height returns nothing
.width = width
.length = length
.height = height
endmethod
endstruct
In order to know what setSize() to call, you need to know the type of the struct.
I am not sure if you actually HAVE to use it in Jass, but looking at the example you gave it looks like you do.
What was shown there is a concept called typecasting, in which you make a type "act" like another type.
A C++ easy example would be int i = (int)1.5 which will make the 1.5 which is a float (equivalent to Jass's "real") to act like an integer and by that it will convert it to 1.
In Jass that would be the R2I function.
Now, by saying inst.getType()==C.typeid you compare the type of the instance called "inst" to the type of the struct 'C'.
I -suppose- that Vexorian stuck an integer that represents that type.
So, for example, the first struct you define will get the type '0', the second '1', etc. Of course this is just a guess, I have no idea how he actually did it.
By C(inst).z what that example means is - make the struct instance called "inst" act like a C type. This is used here because you do not know before-hand what the type is.
Again, I am not sure if you must use these things, although in C++ you'd probably end up with the same thing (a constant member that represents what that struct/class is).
Why in some (or most) vJASS spells we use structs; since they already contain variables like integers, units and unit group etc why can't we use them in the functions directly without using structs ?
Why in some (or most) vJASS spells we use structs; since they already contain variables like integers, units and unit group etc why can't we use them in the functions directly without using structs ?
Why in some (or most) vJASS spells we use structs; since they already contain variables like integers, units and unit group etc why can't we use them in the functions directly without using structs ?
This is as far as I read, must I continue to read all the contents ?
There are many things that I read I still not understand it properly. (It marked in the hidden part)
It's basically used when you want to get the prefix of a private member outside the scope, but you probably don't.
The onDestroy method
Useful little fella. It's mostly for organizing your code, this method will run when you destroy that struct instance. So there you can do all the detaching, destroying effects blabla, since it runs right before the struct is destroyed (I think).
The onInit method
Like an initializer in libraries and scopes. This method will run on map initialization. What don't you understand about it?
Interfaces
Handy thingies, but I never seem to use them. For example, you know that units are widgets and widgets are handles? So widget is everything that has a health bar (destructable, unit, item etc.) so it's like a parent, but a handle is everything except real, integer, string, boolean and code, so handle is a parent to widget. Get it?
In the same manner, interfaces are parents to some structs which extend them. When you have multiple structs which extend a single interface and you need a function which takes those structs as parameters, you can use that interface as parameter (if you don't know which struct you're going to pass as a parameter).
It's basically used when you want to get the prefix of a private member outside the scope, but you probably don't.
The onDestroy method
Useful little fella. It's mostly for organizing your code, this method will run when you destroy that struct instance. So there you can do all the detaching, destroying effects blabla, since it runs right before the struct is destroyed (I think).
The onInit method
Like an initializer in libraries and scopes. This method will run on map initialization. What don't you understand about it?
Interfaces
Handy thingies, but I never seem to use them. For example, you know that units are widgets and widgets are handles? So widget is everything that has a health bar (destructable, unit, item etc.) so it's like a parent, but a handle is everything except real, integer, string, boolean and code, so handle is a parent to widget. Get it?
In the same manner, interfaces are parents to some structs which extend them. When you have multiple structs which extend a single interface and you need a function which takes those structs as parameters, you can use that interface as parameter (if you don't know which struct you're going to pass as a parameter).
This is a template for creating spells which need to, for example, move something smoothly (such as a missile). Use it if you want.
JASS:
scope SpellTemplate initializer Init
private keyword Data
globals
private constant real TIMER_INTERVAL = 0.035
private constant integer ABIL_ID = 'A000' //change this to the rawcode of your spell
//Other constant globals here...
private Data array data
private integer index=0
private timer tim
//Other changeable globals here...
endglobals
private function Execute takes nothing returns nothing
local integer i=0
local Data d
//Other local variables here...
loop
exitwhen i>=index
set d=data[i]
//Code to run each timer execution here...
set i=i+1
endloop
//Any leak cleaning code here...
endfunction
private struct Data
//Declare struct members here...
unit caster
integer ID
static method create takes unit caster returns Data //make sure you change this based on what data you need
local Data d = Data.allocate()
//Other create code here...
set data[index]=d
set d.ID=index
if index==0 then
call TimerStart(tim, TIMER_INTERVAL, true, function Execute)
endif
set index=index+1
return d
endmethod
method onDestroy takes nothing returns nothing
set index=index-1
set data[this.ID]=data[index]
set data[this.ID].ID=this.ID
if index==0 then
call PauseTimer(tim)
endif
//Other destroy code here (such as leak cleaning, removing units etc)...
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == ABIL_ID
endfunction
private function Actions takes nothing returns nothing
call Data.create(GetTriggerUnit()) //make sure you change this based on what data your spell needs
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddAction(t, function Actions)
call TriggerAddCondition(t, Condition(function Conditions))
set tim = CreateTimer()
//Other initialisation things here...
endfunction
endscope
scope SpellTemplate initializer Init
private keyword Data
globals
private constant real TIMER_INTERVAL = 0.035
private constant integer ABIL_ID = 'A000' //change this to the rawcode of your spell
//Other constant globals here...
private Data array data
private integer index=0
private timer tim
//Other changeable globals here...
endglobals
private function Execute takes nothing returns nothing
local integer i=0
local Data d
//Other local variables here...
loop
exitwhen i>=index
set d=data[i]
//Code to run each timer execution here...
set i=i+1
endloop
//Any leak cleaning code here...
endfunction
private struct Data
//Declare struct members here...
unit caster
integer ID
static method create takes unit caster returns Data //make sure you change this based on what data you need
local Data d = Data.allocate()
//Other create code here...
set data[index]=d
set d.ID=index
if index==0 then
call TimerStart(tim, TIMER_INTERVAL, true, function Execute)
endif
set index=index+1
return d
endmethod
method onDestroy takes nothing returns nothing
set index=index-1
set data[this.ID]=data[index]
set data[this.ID].ID=this.ID
if index==0 then
call PauseTimer(tim)
endif
//Other destroy code here (such as leak cleaning, removing units etc)...
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == ABIL_ID
endfunction
private function Actions takes nothing returns nothing
call Data.create(GetTriggerUnit()) //make sure you change this based on what data your spell needs
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddAction(t, function Actions)
call TriggerAddCondition(t, Condition(function Conditions))
set tim = CreateTimer()
//Other initialisation things here...
endfunction
endscope
Some Questions:
1) I can't find the action that moves the unit (Missile Unit) to the destination.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.