• 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] begginer mistake

Status
Not open for further replies.
Level 2
Joined
May 9, 2010
Messages
22
I really need help regarding my first jass script.
After reading a lot of tutorials, I decided to start off with something simple.
And there was only one error! But I don't know how to fix it.
this is what I did:
JASS:
//custom trigger

function Take_Actions takes nothing returns nothing
       local unit a = GetAttackedUnitBJ()
       local unit b = GetAttacker()
       local location boom = GetUnitLoc(b)
       call KillUnit(a)
       call AddSpecialEffectLocBJ(GetUnitLoc(b), "Abilites\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl")
endfunction

//initializing event
function InitTrig_Take takes nothing  returns nothing
    set gg_trg_Take = CreateTrigger(  )
14    call TriggerRegisterAnyUnitEventBJ( gg_trg_Take, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddAction( gg_trg_Take, function Take_Actions)
endfunction

and mistake is:
Line 14: Undeclared variable: gg_trg_Take
How do I declare it then?
 
Last edited by a moderator:
Level 18
Joined
Jan 21, 2006
Messages
2,552
Do you use JNGP? You're using the World Editor's default setup for having triggers run at map initialization - whenever you create a "new trigger", by default it will create a trigger variable named gg_trg_TrigName. If you're using JNGP then you can declare your own initializers within scopes and libraries, which blows InitTrig_TrigName out of the water and doesn't require you to name your triggers like this.

In any event, you can just as easily use a local trigger variable.

JASS:
//custom trigger

function Take_Actions takes nothing returns nothing
       local unit a = GetAttackedUnitBJ()
       local unit b = GetAttacker()
       local location boom = GetUnitLoc(b)
       call KillUnit(a)
       call AddSpecialEffectLocBJ(GetUnitLoc(b), "Abilites\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl")
endfunction

//initializing event
function InitTrig_Take takes nothing  returns nothing
    local trigger t = CreateTrigger( )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddAction( t, function Take_Actions)

endfunction

Also worth mentioning, you should be setting your unit variables to null once you are done using them and destroy/remove the location that you initiate. I'll show you an example of how to do this;

JASS:
function Take_Actions takes nothing returns nothing
       local unit a = GetAttackedUnitBJ()
       local unit b = GetAttacker()
       local location boom = GetUnitLoc(b)
       call KillUnit(a)
       call AddSpecialEffectLocBJ(GetUnitLoc(b), "Abilites\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl")

       // cleanup
       call RemoveLocation(boom)
       set boom = null
       set a = null
       set b = null
endfunction

Handles need to be destroyed once they are no longer used. Units by default are removed a certain amount of time after their death, so typically you don't need to worry about removing/destroying them.
 
Level 2
Joined
May 9, 2010
Messages
22
ah! thanks a lot! It is working now.
Btw thanks for the cleaning part as well. I'm completely new to jass so information like that is valuable :) Though I did use GUI for an awfully long time and can do most of the complicated things, but I would reallly like to learn jass as well.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
I didn't see this before, but you also reference GetUnitLoc(b) inside your AddSpecialEffectLocBJ call; why not just use your variable "boom". Referencing the location again like that will create a new location handle, and you'll have to clean that one too (but why have two exact same locations).

Instead you do:

JASS:
call AddSpecialEffectLocBJ(boom, "Abilites\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl")
 
Last edited:
Level 2
Joined
May 9, 2010
Messages
22
boom

I created boom but I didn't use it at first. I tried, but I didn't work so I replaced it. I probably did something wrong, cant remember what, but now it is working!
 
Level 2
Joined
May 9, 2010
Messages
22
I plan on using getriggerunit in my future scripts. and just one thing: GetTriggerUnit refers to unit stored in event (such as player_unit_attacked in my case), right?
 
It's not actually stored, it's a reference to the event. The event fires, once certain actions are made. The unit that fires the event is the triggering unit. So, a Unit is attacked event is fired by the attacked unit, not the attacking one. Using TriggerUnit() over other event responses results a faster proc of your triggered actions.
 
Level 11
Joined
Apr 6, 2008
Messages
760
You should try to remove bj's aswell

JASS:
call AddSpecialEffectLocBJ(GetUnitLoc(b), "Abilites\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl")

can be changed in to this

JASS:
call AddSpecialEffectLoc("Abilites\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl", GetUnitLoc(b))
 
Level 16
Joined
May 1, 2008
Messages
1,605
Moin moin =)

You trigger in the better way:
JASS:
function Take_Actions takes nothing returns nothing
    local unit u1 = GetTriggerUnit()
    local unit u2 = GetAttacker()
    local real x = GetUnitX(u2)
    local real y = GetUnitY(u2)
    
    call KillUnit(u1)
    call DestroyEffect(AddSpecialEffectLoc("Abilites\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl", Location(x, y)))
    
    set u1 = null
    set u2 = null
endfunction

//===========================================================================
function InitTrig_Take takes nothing  returns nothing
    set gg_trg_Take = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Take, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddAction( gg_trg_Take, function Take_Actions)
endfunction
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
Actually Dr. Boom, that would create a location which would cause a leak since it never gets removed.
JASS:
function Take_Actions takes nothing returns nothing
    local unit u1 = GetTriggerUnit() // You don't really need to use a local variable if you only refer to it once. It's up to you though.
    local unit u2 = GetAttacker()
    local real x = GetUnitX(u2)
    local real y = GetUnitY(u2)
    
    call KillUnit(u1)
    call DestroyEffect(AddSpecialEffect("Abilites\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl",x, y))
    
    set u1 = null
    set u2 = null
endfunction

//===========================================================================
function InitTrig_Take takes nothing  returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ATTACKED)
    call TriggerAddAction(t, function Take_Actions)
endfunction
 
Level 16
Joined
May 1, 2008
Messages
1,605
Moin moin =)

Nop you wrong, there isn't a leak. The location is created with local reals and real doesn't leak, so the Location(x, y) never leaks. Edit: Yes u1 is useless, you can use directly call KillUnit(GetTriggerUnit())

[ You can look at Jass Spells, they never remove x and y because it isn't a leak ]

Greetings
~ The Bomb King > Dr. Boom
 
Moin moin =)

Nop you wrong, there isn't a leak. The location is created with local reals and real doesn't leak, so the Location(x, y) never leaks.

[ You can look at Jass Spells, they never remove x and y because it isn't a leak ]

Greetings
~ The Bomb King > Dr. Boom

Location is a function that returns a location, it doesn't return a set of reals. It does leak ;)
 
The reals themselves don't leak, the location conversion leaks.
GetUnitX doesn't leak, but Location(x, y) leaks, since it's a location, converted from two reals, but it still is a location.
It should be
JASS:
local real x = GetUnitX (u2)
local real y = GetUnitY (u2)
local location l = Location (x, y)
set l = null
call RemoveLocation (l)

If you know how to use coordinates, you will use the AddSpecialEffect() function, suggested by watermelon_1234, which takes reals as parameters.
It's dumb to have the coordinates and convert them into a location afterwards. If you are using a location, why not using a location directly: GetUnitLoc (u2)?

It's like doing this:
JASS:
local unit u = GetTriggerUnit()
local real x = GetUnitX (u)
local real y = GetUnitY (u)
local location l = Location (x, y)
local unit a = CreateUnitAtLoc (GetOwningPlayer(u), 'hfoo', l, 0)
set u = null
set l = null
call RemoveLocation (l)
set a = null
when it could be:
JASS:
local unit u = GetTriggerUnit()
local real x = GetUnitX (u)
local real y = GetUnitY (u)
local unit a = CreateUnit (GetOwningPlayer(u), 'hfoo', x, y, 0)
set u = null
set a = null

See the difference? ;)
 
Level 16
Joined
May 1, 2008
Messages
1,605
Moin moin =)

Let me thing, as I know reals are faster then locations ( all say that ). But when I use reals to create a location and use the location in my action and set l = null and remove this... so I can use a location directly not reals or?

Greetings
~ The Bomb King > Dr. Boom
 
Yes, you can use locations directly, but like you said, reals do work faster. You can eternally get rid of the locations, unless you need GetLocationZ(); this is the only case, where you will need a location, since there is no GetUnitZ() function.

Just spot the difference:
JASS:
local unit u = GetTriggerUnit()
local real x = GetUnitX (u)
local real y = GetUnitY (u)
call DestroyEffect (AddSpecialEffect ("xxx//xx.mdx", x, y))
set u = null

JASS:
local unit u = GetTriggerUnit()
local location l = GetUnitLoc()
call DestroyEffect (AddSpecialEffectLoc ("xxx//xx.mdx", l))
set u = null
set l = null
call RemoveLocation (l)

It's the same, but the first method is used mostly, because of the coordinates' pros:
• They don't leak.
• They don't need to be cleaned.
• They proc faster.
• They shorten out the code.
 
Level 16
Joined
May 1, 2008
Messages
1,605
Moin moin =)

The last think I don't understand, why you "Set l = null" and after "call RemoveLocation"? In your second example in your last post this doesn't make any sense =O
In addition, even if you set the location with x and y, you don't need to null it you can directly remove the location because the x and y doesn't leak or?

Greetings
~ The Bomb King > Dr. Boom
 
This is how you remove the locations in Jass. This is why people say that GUI can't fully clean the leaks of a trigger, because you will most likely only use the RemoveLocation() function. You also need to null it.

You are missing my point here.
x and y are reals, which do not leak. The Location() function you are using is this:
JASS:
native Location                 takes real x, real y returns location
See? It returns a location, while this:
JASS:
native GetUnitX            takes unit whichUnit returns real
returns a real. In this case, the result doesn't need to be cleaned, while the first one needs to be cleaned, because locations leak.
 
Level 2
Joined
May 9, 2010
Messages
22
//

thanks a lot everyone for these helpful posts. I'm getting used to jass, it is a bit hard because I used GUI for 5-6 years.... Though still need the benefits explained to me. I figured out removing the leaks is what makes jass far better, but multi instance spells are still a myth to me. What does that even mean?
 
That a unit can still be affected by your spell or system, even if another instance of the same spell or system runs at that time (or at the same time). There are generally no collisions between casts. Different units, casting the same spell at the same time, without having each other's instances affected.

Indexing systems, Hashtables and Game Caches can provide you with MUI enhancement.

• The first ones are the fastest, but they can only store 8192 instances at a time.

• Hashtables are a bit slower, but the speed difference is not even visible, compared to indexing systems, they are much more easier to handle and understand and they can hold way more instances than indexing systems.

• Finally, Game Cache is the slowest of all.
 
Status
Not open for further replies.
Top