Condition() ?

Some1Sneakin

New Member
Reaction score
5
I just did my first trigger in jass. Its supossed to be a spell that shoots a bullet in a targeted location. And if it hits it dissapears. But theres a problem. I need to check if it hits your own units or enemy units. So i did a trigger that looked like this:

Code:
Set X = Get Units in Range Matching Condition:  Units within 200 of "Bullet" matching ((Owner of Matching Unit) not equal to (Triggering Player))

And converted that to custom text and got:

Code:
GetUnitsInRangeOfLocMatching(200.00, GetUnitLoc(bullet), Condition(function Trig_Cannon_Func001002003))

I added that to the code but then it didnt work to run the code.
I get this error: Expected a function name!

Any ideas why?

If you're intressted, my whple trigger looks like this:


Code:
                                                 function Trig_Cannon_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A006' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Cannon_Actions takes nothing returns nothing

local integer time
local location target
local location caster_loc
local unit caster
local unit bullet
local real angle
local boolean hit
local location slide
local unit victim
local group hitarea
local integer hitarea_count

set caster = GetTriggerUnit ()
set caster_loc = GetUnitLoc (caster)
set target = GetSpellTargetLoc ()
set angle = AngleBetweenPoints(caster_loc, target)


call CreateUnitAtLoc (GetTriggerPlayer (), 'h001', GetUnitLoc(caster), bj_UNIT_FACING)
set bullet = GetLastCreatedUnit ()
call SetUnitFacingToFaceLocTimed (bullet, target, 0)

set time = 40

    loop
        exitwhen hit == true  
           set time = time - 1
           set slide = PolarProjectionBJ (GetUnitLoc (bullet), 50, angle)
           call SetUnitPositionLoc( bullet, slide )
               if time == 0 then
                   set hit = true
               endif
               set hitarea = GetUnitsInRangeOfLocMatching(200.00, GetUnitLoc(bullet), Condition(function Trig_Cannon_Func001002003))
               set hitarea_count = CountUnitsInGroup (hitarea)
               if hitarea_count > 0 then
                    set victim = GroupPickRandomUnit (hitarea)
                    call UnitDamageTargetBJ(caster, victim, 100, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL )
                    set hit = true  
               endif
            call TriggerSleepAction (0.05)
    endloop
call RemoveUnit (bullet)    
call RemoveLocation (target)
call RemoveLocation (caster_loc)       
endfunction


//===========================================================================
function InitTrig_Cannon takes nothing returns nothing
    set gg_trg_Cannon = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Cannon, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Cannon, Condition( function Trig_Cannon_Conditions ) )
    call TriggerAddAction( gg_trg_Cannon, function Trig_Cannon_Actions )
endfunction
 

phyrex1an

Staff Member and irregular helper
Reaction score
447
Trig_Cannon_Func001002003 <- is the important part.

It's a function that looks something like this:
JASS:
function Trig_Cannon_Func001002003 takes nothing returns boolean
     return GetOwningPlayer(GetFilterUnit()) != GetTriggerPlayer()
endfunction


The Condition creates a boolexpr, when that boolexpr (and therefore function) evaluates to true the unit will be added to the group. The reason why your code doesn't work is because you don't have a Trig_Cannon_Func001002003 (extremely bad name btw, rename it asap) or the Trig_Cannon_Func001002003 function is placed below your code.

With that said, a few things about your code:
There is no Triggering Player on a spell cast event.
You're leaking pretty much everywhere. You need to destroy every location you create not just the ones that are assigned to a variable at the end of the function.
 

Some1Sneakin

New Member
Reaction score
5
I feel stupid, it still doesnt work. It doesnt give me syntax error now but the spell wont work. The bullets wont move. After they been crated they just stand at the same spot.

The trigger look like this:
Code:
                              function Trig_Cannon_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A006' ) ) then
        return false
    endif
    return true
endfunction


function cond takes nothing returns boolean
return GetOwningPlayer(GetFilterUnit()) != GetTriggerPlayer()
endfunction






function Trig_Cannon_Actions takes nothing returns nothing

local integer time
local location target
local location caster_loc
local unit caster
local unit bullet
local real angle
local boolean hit
local location slide
local unit victim
local group hitarea
local integer hitarea_count
local player trigplayer

set caster = GetTriggerUnit ()
set caster_loc = GetUnitLoc (caster)
set target = GetSpellTargetLoc ()
set angle = AngleBetweenPoints(caster_loc, target)
set trigplayer = GetOwningPlayer (caster)

call CreateUnitAtLoc (trigplayer, 'h001', GetUnitLoc(caster), bj_UNIT_FACING)
set bullet = GetLastCreatedUnit ()
call SetUnitFacingToFaceLocTimed (bullet, target, 0)

set time = 40

    loop
        exitwhen hit == true  
           set time = time - 1
           set slide = PolarProjectionBJ (GetUnitLoc (bullet), 50, angle)
           call SetUnitPositionLoc( bullet, slide )
               if time == 0 then
                   set hit = true
               endif
               set hitarea = GetUnitsInRangeOfLocMatching(200.00, GetUnitLoc(bullet), Condition(function cond))
               set hitarea_count = CountUnitsInGroup (hitarea)
               if hitarea_count > 0 then
                    set victim = GroupPickRandomUnit (hitarea)
                    call UnitDamageTargetBJ( caster, victim, 100, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL )
                    set hit = true  
               endif
            call TriggerSleepAction (0.05) 
    endloop
call RemoveUnit (bullet)    
call RemoveLocation (target)
call RemoveLocation (caster_loc)
      
endfunction





//===========================================================================
function InitTrig_Cannon takes nothing returns nothing
    set gg_trg_Cannon = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Cannon, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Cannon, Condition( function Trig_Cannon_Conditions ) )
    call TriggerAddAction( gg_trg_Cannon, function Trig_Cannon_Actions )
endfunction

Do you see any stupid mistake that i made?
 
Reaction score
456
Try setting the hit value to false.

JASS:
function Trig_Cannon_Actions takes nothing returns nothing
    local integer time
    local location target
    local location caster_loc
    local unit caster
    local unit bullet
    local real angle
    local boolean hit = false


Then some messages there:
JASS:
if time == 0 then
    set hit = true
    call BJDebugMsg(&quot;Hit&quot;) //Here and
endif
set hitarea = GetUnitsInRangeOfLocMatching(200.00, GetUnitLoc(bullet), Condition(function cond))
set hitarea_count = CountUnitsInGroup (hitarea)
if hitarea_count &gt; 0 then
    call BJDebugMsg(&quot;Hit&quot;) //here
    set victim = GroupPickRandomUnit (hitarea)
    call UnitDamageTargetBJ( caster, victim, 100, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL )
    set hit = true  
endif


Use jass tags from now on, when you're pasting jass codes.
 

Some1Sneakin

New Member
Reaction score
5
Thanks it works now. Except for one thing. The bullets move to "slow". I mean they like only move like 5 times a second. It makes it look "laggy". Hard to explain. But if i set the wait action to 0.01 sec that means the bullet should move 100 times/seconds, but why does it only move like 5 times/sec?
 

Romek

Super Moderator
Reaction score
963
Waits aren't known for their accuracy :p If you want to do a slide/projectile-type thing, you're going to need to use timers to do it properly
I know them for their lack of it :p

A 0.01 wait will actually wait ~0.15 seconds.

A 0.01 timer will wait ~0.01 seconds.
 

Romek

Super Moderator
Reaction score
963

Romek

Super Moderator
Reaction score
963
JASS:
call TimerStart(T, 0.01, true, function &lt;Name&gt;)

T is the timer.
0.01 is the amount
true means periodic. false means it runs once.
<Name> is the name of the function that should be ran when the timer expires.
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Will it be still be MUI if i use timers?
If you use local variables. However, since all it does is run another function when it expires, you're going to need to take a look at Attachment systems so that you can use the local variables you created in the first function in the new function. You will probably want vJASS for this, which means you'll need Newgen.

As for attachment systems, take a look at ABCT, TT, ABC, CSData, HSAS, or HAIL. Those are some of the more well known ones.

Once you learn how to use Timers in combination with Structs and attachment systems, you can do many things with sliding and spells. :)
 

Some1Sneakin

New Member
Reaction score
5
All i want is to is to have the trigger to wait 0.01 everytime before it repeats the loop. Can it be that hard to make? Do i really need to download alot of this just to make a simple Bullet trigger? Im getting a feeling this isnt the right thing to do as your first Jass trigger.

Please can you just tell me how the trigger should look like? Edit my trigger if you got the time? My trigger look like at the moment:

JASS:



                                                 function Trig_Cannon_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == &#039;A006&#039; ) ) then
        return false
    endif
    return true
endfunction


function cond takes nothing returns boolean
return GetOwningPlayer(GetFilterUnit()) != GetTriggerPlayer()
endfunction






function Trig_Cannon_Actions takes nothing returns nothing

local integer time
local location target
local location caster_loc
local unit caster
local unit bullet
local real angle
local boolean hit = false
local location slide
local unit victim
local group hitarea
local integer hitarea_count
local player trigplayer

set caster = GetTriggerUnit ()
set caster_loc = GetUnitLoc (caster)
set target = GetSpellTargetLoc ()
set angle = AngleBetweenPoints(caster_loc, target)
set trigplayer = GetOwningPlayer (caster)

set bullet = CreateUnitAtLoc (trigplayer, &#039;h001&#039;, caster_loc, bj_UNIT_FACING)
call SetUnitFacingToFaceLocTimed (bullet, target, 0)

set time = 40

    loop
        exitwhen hit == true  
           set time = time - 1
           set slide = PolarProjectionBJ (GetUnitLoc (bullet), 50, angle)
           call SetUnitPositionLoc( bullet, slide )
               if time == 0 then
                   set hit = true
               endif
               set hitarea = GetUnitsInRangeOfLocMatching(75.00, GetUnitLoc(bullet), Condition(function cond))
               set hitarea_count = CountUnitsInGroup (hitarea)
               if hitarea_count &gt; 0 then
                    set victim = GroupPickRandomUnit (hitarea)
                    call UnitDamageTargetBJ( caster, victim, 100, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL )
                    set hit = true  
               endif
             
    endloop
call RemoveUnit (bullet)    
call RemoveLocation (target)
call RemoveLocation (caster_loc)
call RemoveLocation (slide)
      
endfunction





//===========================================================================
function InitTrig_Cannon takes nothing returns nothing
    set gg_trg_Cannon = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Cannon, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Cannon, Condition( function Trig_Cannon_Conditions ) )
    call TriggerAddAction( gg_trg_Cannon, function Trig_Cannon_Actions )
endfunction
 

Viikuna

No Marlo no game.
Reaction score
265
All i want is to is to have the trigger to wait 0.01 everytime before it repeats the loop.

That is impossible.

Timers aint that hard to use. Juts try to make some non - MUI, bullet thingie first, so you can see how timers work.

If you want it MUI, just use Cohadars TT -system. Its ridicilous easy to use.
You just need vJass for that, so just download NewGen. NewGen makes Jassing a lot of easier.

EDIT. link There is also a test map, check it out.
 

Some1Sneakin

New Member
Reaction score
5
I got a better idea now, making the spell non-MUI and making 12 copies of it (one for each player) in that way it will be MPI which is all i actually need. Anyway another problem, syntax error proably.

Code

JASS:
                                                function Trig_Cannon_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == &#039;A006&#039; ) ) then
        return false
    endif
    return true
endfunction


function cond takes nothing returns boolean
return GetOwningPlayer(GetFilterUnit()) != GetTriggerPlayer()
endfunction

function movefunc takes unit slider, location dist returns nothing
call SetUnitPositionLoc(slider, dist)
endfunction




function Trig_Cannon_Actions takes nothing returns nothing

local integer time
local location target
local location caster_loc
local unit caster
local unit bullet
local real angle
local boolean hit = false
local location slide
local unit victim
local group hitarea
local integer hitarea_count
local player trigplayer
local timer slidetimer = CreateTimer ()

set caster = GetTriggerUnit ()
set caster_loc = GetUnitLoc (caster)
set target = GetSpellTargetLoc ()
set angle = AngleBetweenPoints(caster_loc, target)
set trigplayer = GetOwningPlayer (caster)

call CreateUnitAtLoc (trigplayer, &#039;h001&#039;, GetUnitLoc(caster), bj_UNIT_FACING)
set bullet = GetLastCreatedUnit ()
call SetUnitFacingToFaceLocTimed (bullet, target, 0)

set time = 40

    loop
        exitwhen hit == true  
           set time = time - 1
           set slide = PolarProjectionBJ (GetUnitLoc (bullet), 50, angle)
               call TimerStart (slidetimer, 0.05, false, function movefunc(bullet, slide))
               if time == 0 then
                   set hit = true
               endif
               set hitarea = GetUnitsInRangeOfLocMatching(200.00, GetUnitLoc(bullet), Condition(function cond))
               set hitarea_count = CountUnitsInGroup (hitarea)
               if hitarea_count &gt; 0 then
                    set victim = GroupPickRandomUnit (hitarea)
                    call UnitDamageTargetBJ( caster, victim, 100, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL )
                    set hit = true  
               endif
               
    endloop
call RemoveUnit (bullet)    
call RemoveLocation (target)
call RemoveLocation (caster_loc)
call RemoveLocation (slide)      
endfunction





//===========================================================================
function InitTrig_Cannon takes nothing returns nothing
    set gg_trg_Cannon = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Cannon, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Cannon, Condition( function Trig_Cannon_Conditions ) )
    call TriggerAddAction( gg_trg_Cannon, function Trig_Cannon_Actions )
endfunction


The error is:
JASS:
call TimerStart (slidetimer, 0.05, false, function movefunc(bullet, slide))

Why?
 

Forty

New Member
Reaction score
6
you cant pass arguments to a callback function means

call TimerStart (slidetimer, 0.05, false, function movefunc(bullet, slide))

->
call TimerStart (slidetimer, 0.05, false, function movefunc)

if your method was possible, we wouldnt have to use ABCT, TT and so on.
 

Builder Bob

Live free or don't
Reaction score
249
a callback function cannot take arguments. That means movefunc must take nothing
JASS:
function movefunc takes nothing returns nothing
    //call SetUnitPositionLoc(slider, dist)
endfunction


the timer is started like this without any brackets after movefunc
JASS:
call TimerStart (slidetimer, 0.05, false, function movefunc)


To get slider and dist variables into the movefunc function, you'll have to use an attachment system and attach a struct containing those two variables to the timer slidetimer.


If you use vJass and an attachment system (like CSData), I can set up the trigger for you. If not, I cannot help you
 
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