• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Need some help with JASS

Status
Not open for further replies.
Level 4
Joined
Oct 16, 2006
Messages
48
Hi . can someone help me with my spell trigger. I believe it is relatively simple, I just don't know where does it go wrong.
Been trying it in a few different ways. doesn't seems to work.
This current way still doesn't work.

When casting, it tests to see if they're in same cliff level and if target is more than 250 range away.

If not , it will slide the caster towards the target unit's initial location for 1.5 seconds. If it hits the target, it will do damage and stun. If not, it will just remove effect.

It detects the hitting by continually check range of Target and caster while sliding, and if it's less than 200, it's consider hit. It does this by looping the check for 15 times via for loop. each loop doing a 0.1 second pause.

Now here's the problem, i did a debug message on each loop to show the looping variable. doesn't work. The debug message only showed 1.which means it never looped. Sometimes, it still hits the unit even after 1.5 seconds ( which shouldn't ) any idea?
Also, it doesn't seem to detect the hits properly sometimes.

I tried doing it without loop, using exitwhen to change the range, but then again, if target misses, the loop will not stop. So I use Exitwhen to do a OR comparison for the range and time( max 1.5 second) , still don't work. So I i'm utterly confused.

I hope someone can advised. thanks


JASS:
function Trig_Ramstrike_Actions takes nothing returns nothing
local effect wave
local unit target
local unit caster
local location x
local real angle
local integer wait

set caster = GetTriggerUnit()
set target = GetSpellTargetUnit()
set x = GetUnitLoc(target)
set wait = 0
set angle = AngleBetweenPoints(GetUnitLoc(caster), GetUnitLoc(target))
if ( Trig_Ramstrike_Func001C() ) then
    if ( DistanceBetweenPoints(GetUnitLoc(caster), GetUnitLoc(target)) >= 250.00 ) then
        call SetUnitAnimation( caster , "spell throw" )
        call PolledWait(0.30)
        call SetUnitPathing( GetTriggerUnit(), false )
        call Knockback(GetTriggerUnit(), 400, AngleBetweenPoints(GetUnitLoc(GetTriggerUnit()), GetUnitLoc(GetSpellTargetUnit())) * bj_DEGTORAD, 1.5) 
        call AddSpecialEffectTargetUnitBJ( "origin", caster, "Abilities\\Spells\\Orc\\Shockwave\\ShockwaveMissile.mdl" )
        set wave = GetLastCreatedEffectBJ()      
            loop
                exitwhen wait > 15                               
                call ErrorMsg( GetOwningPlayer(GetTriggerUnit()), I2S(wait) )
                        if ( DistanceBetweenPoints(GetUnitLoc(target), GetUnitLoc(caster)) <= 200.00 ) then    //checks if target unit is near caster. Or if he already run off   
                                call DestroyEffectBJ(wave)
                                call PlaySoundAtPointBJ( gg_snd_MetalHeavySliceFlesh1, 100.00, GetUnitLoc(target), 0 )
                                call SetUnitPathing( caster, true )
                                call Knockback(target, 150, angle * bj_DEGTORAD, 1 )      
                                call Knockback(caster, 75, (angle - 180 ) * bj_DEGTORAD, 1 )
                                call UnitDamageTargetBJ( caster , target, udg_RamstrikeDMG[GetUnitAbilityLevelSwapped('A00B', GetTriggerUnit())], ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
                                set wait = 16                          
                                call Stun( caster , target , udg_RamstrikeSTUN[GetUnitAbilityLevelSwapped('A00B', caster)] )
                                call ErrorMsg( GetOwningPlayer(GetTriggerUnit()), I2S(wait) )
                        else
                                call AddSpecialEffectLocWithTimer(GetUnitLoc(caster), "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl" , 2 )                            
                                set wait = wait + 1
                                call ErrorMsg( GetOwningPlayer(GetTriggerUnit()), I2S(wait) )
                        endif
                call TriggerSleepAction(0.10)
            endloop
    else
        call ErrorMsg( GetOwningPlayer(GetTriggerUnit()), "Unit too close to ram" )
        call CancelOrders(caster) 
    endif
else
    call ErrorMsg( GetOwningPlayer(GetTriggerUnit()), "Cannot ram unit in different cliff level." )
    call CancelOrders(caster)
endif             
             call DestroyEffectBJ( wave )
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
This is what I've got:

JASS:
function Trig_Ramstrike_Actions takes nothing returns nothing
 local effect wave
 local location loc
 local unit caster  = GetTriggerUnit()
 local unit target  = GetSpellTargetUnit()
 local real x       = GetWidgetX(caster)
 local real y       = GetWidgetY(caster)
 local real x2      = GetSpellTargetX()
 local real y2      = GetSpellTargetY()
 local integer wait = 0

    if ( Trig_Ramstrike_Func001C() ) then
        if SquareRoot((x2-x)*(x2-x) + (y2-y)*(y2-y)) >= 250.00 then
            call SetUnitAnimation( caster , "spell throw" )
            call PolledWait(0.30)
            call Knockback(caster, 400, Atan2(y2 - y, x2 - x), 1.5) 
            set wave = AddSpecialEffectTarget( "Abilities\\Spells\\Orc\\Shockwave\\ShockwaveMissile.mdl", caster, "origin" )
            set loc = Location(0,0)
            loop
                call BJDebugMsg(I2S(wait))
                call TriggerSleepAction(0.00)
                x = GetWidgetX(caster) 
                y = GetWidgetY(caster)
                x2 = GetWidgetX(target)
                y2 = GetWidgetY(target)
                if SquareRoot((x2-x)*(x2-x) + (y2-y)*(y2-y)) <= 200.00 then
                    call DestroyEffect(wave)
                    call MoveLocation(loc, x2, y2)
                    call PlaySoundAtPointBJ( gg_snd_MetalHeavySliceFlesh1, 100.00, loc, 0 )
                    
                    call Knockback(target, 150, Atan2(y2 - y, x2 - x), 1 )
                    call Knockback(caster, 75, Atan2(y - y2, x - x2), 1 )
                    
                    call UnitDamageTarget( caster , target, udg_RamstrikeDMG[GetUnitAbilityLevel(caster, 'A00B')], true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
                    call Stun( caster , target , udg_RamstrikeSTUN[GetUnitAbilityLevel(caster, 'A00B')] )
                    exitwhen true
                else
                    call MoveLocation(loc, x, y)
                    call AddSpecialEffectLocWithTimer(loc, "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl" , 2 )
                    exitwhen wait == 15
                    set wait = wait + 1
                    call BJDebugMsg(I2S(wait))
                endif
            endloop
            call RemoveLocation(loc)
            call DestroyEffect(wave)
        else
            call ErrorMsg(GetTriggerPlayer(), "Unit too close to ram")
            call IssueImmediateOrder(caster, "stop")
        endif
    else
        call ErrorMsg(GetTriggerPlayer(), "Cannot ram unit in different cliff level.")
        call IssueImmediateOrder(caster, "stop")
    endif
    set caster = null
    set target = null
    set loc = null
endfunction

UnitDamageTargetBJ has inexplicable problems and many other BJ's have weird glitches.
 
Last edited:
Level 9
Joined
Dec 12, 2007
Messages
489
i'm just wondering... the custom function that you use, does it bug-free?
and just an idea, you might want to use your declared var
because from what i see for example
JASS:
local unit caster = GetTriggerUnit()
but in your actual code, you still use GetTriggerUnit() not that variable.
and you use too much BJ, probably like what Bribe said, that could cause rare glitch in your code.

o yeah, and Bribe:
JASS:
....
                call TriggerSleepAction(0.00)
                x = GetWidgetX(caster) 
                y = GetWidgetY(caster)
                x2 = GetWidgetX(target)
                y2 = GetWidgetY(target)
                if SquareRoot((x2-x)*(x2-x) + (y2-y)*(y2-y)) <= 200.00 then
....
i believe there are something wrong with it isn't? =)
 
Level 4
Joined
Oct 16, 2006
Messages
48
Ok I'll try to kill the BJ functions.

Anyway the Trig_Ramstrike_Func001C are as below. I don't think they cause problem because it works until the the caster is slide to target. but it just won't detect the hit UNTIL the loops are finished. it doesn't make sense. and debug msg doesn't show the loop. I'll try with the BJ first then we'll see what happens.

JASS:
 function Trig_Ramstrike_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A00B' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Ramstrike_Func001C takes nothing returns boolean
    if ( not ( GetTerrainCliffLevelBJ(GetUnitLoc(GetTriggerUnit())) == GetTerrainCliffLevelBJ(GetUnitLoc(GetSpellTargetUnit())) ) ) then
        return false
    endif
    return true
endfunction
 
Level 4
Joined
Oct 16, 2006
Messages
48
JASS:
function Trig_Ramstrike_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A00B' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Ramstrike_Func001C takes nothing returns boolean
    if ( not ( GetTerrainCliffLevelBJ(GetUnitLoc(GetTriggerUnit())) == GetTerrainCliffLevelBJ(GetUnitLoc(GetSpellTargetUnit())) ) ) then
        return false
    endif
    return true
endfunction

function Trig_Ramstrike_Actions takes nothing returns nothing
local effect wave
local unit target
local unit caster
local location x
local real angle
local integer wait

set caster = GetTriggerUnit()
set target = GetSpellTargetUnit()
set x = GetUnitLoc(target)
set wait = 0
set angle = AngleBetweenPoints(GetUnitLoc(caster), GetUnitLoc(target))
if ( Trig_Ramstrike_Func001C() ) then
    if ( DistanceBetweenPoints(GetUnitLoc(caster), GetUnitLoc(target)) >= 250.00 ) then
        call SetUnitAnimation( caster , "spell throw" )
        call PolledWait(0.30)
        call SetUnitPathing( caster, false )
        call KnockbackTarget(target, caster, angle, 600, 400, true, true, false) 
        set wave = AddSpecialEffectTarget( "Abilities\\Spells\\Orc\\Shockwave\\ShockwaveMissile.mdl" , caster , "origin" )
            loop
                exitwhen wait > 15                               
                call ErrorMsg( GetOwningPlayer(GetTriggerUnit()), I2S(wait) )
                        if ( DistanceBetweenPoints(GetUnitLoc(target), GetUnitLoc(caster)) <= 200.00 ) then    //checks if target unit is near caster. Or if he already run off   
                                call DestroyEffect(wave)
                                call PlaySoundAtPointBJ( gg_snd_MetalHeavySliceFlesh1, 100.00, GetUnitLoc(target), 0 )
                                call SetUnitPathing( caster, true )
                                call KnockbackTarget(caster, target, angle, 200, 100 , true, true, false )       
                                call UnitDamageTarget(caster, target, udg_RamstrikeDMG[GetUnitAbilityLevelSwapped('A00B', GetTriggerUnit())],true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                                set wait = 16                          
                                call Stun( caster , target , udg_RamstrikeSTUN[GetUnitAbilityLevelSwapped('A00B', caster)] )
                                call ErrorMsg( GetOwningPlayer(GetTriggerUnit()), I2S(wait) )
                        else
                                call AddSpecialEffectLocWithTimer(GetUnitLoc(caster), "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl" , 2 )                            
                                set wait = wait + 1
                                call ErrorMsg( GetOwningPlayer(GetTriggerUnit()), I2S(wait) )
                        endif
                call TriggerSleepAction(0.10)
            endloop
    else
        call SimError( GetOwningPlayer(GetTriggerUnit()), "Unit too close to ram" )
        call CancelOrders(caster) 
    endif
else
    call ErrorMsg( GetOwningPlayer(GetTriggerUnit()), "Cannot ram unit in different cliff level." )
    call CancelOrders(caster)
endif             
             call DestroyEffect(wave)

             
endfunction

//===========================================================================
function InitTrig_Ramstrike takes nothing returns nothing
    set gg_trg_Ramstrike = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Ramstrike, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Ramstrike, Condition( function Trig_Ramstrike_Conditions ) )
    call TriggerAddAction( gg_trg_Ramstrike, function Trig_Ramstrike_Actions )
endfunction


Still don't work.. It doensn't break the loop even when the caster is right ON TOP of the target. I'm beginning to wonder if this have anything to do with knockback library
 
Level 3
Joined
May 21, 2010
Messages
17
JASS:
function Trig_Ramstrike_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A00B' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Ramstrike_Func001C takes nothing returns boolean
    if ( not ( GetTerrainCliffLevelBJ(GetUnitLoc(GetTriggerUnit())) == GetTerrainCliffLevelBJ(GetUnitLoc(GetSpellTargetUnit())) ) ) then
        return false
    endif
    return true
endfunction
These are not really needed to be that big.

If you think about it, an IF statement takes if a value is true or false anyway, therefore it can be returned off the bat. For example:
JASS:
function Trig_Ramstrike_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B'
endfunction

function Trig_Ramstrike_Func001C takes nothing returns boolean
    return GetTerrainCliffLevelBJ(GetUnitLoc(GetTriggerUnit())) == GetTerrainCliffLevelBJ(GetUnitLoc(GetSpellTargetUnit()))
endfunction
It still returns the same value as your previous ones, but looks a whole lot cleaner.



I know this isn't really neccessary to your problem but it is a good habit to get into!
 
Level 4
Joined
Oct 16, 2006
Messages
48
Yeah, test what I gave you, b&n.

Doesn't work. I changed some stuff... don't work. Everything ended AFTER the character show the Spell Throw animation. Effect didn't even appear. knockback didn't happen.

anyway I don't quite get your code, why is your exitwhen right at the bottom? does that work with loop?
also why the exitwhen == true? won't that break the loop immediately?
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Try this, and tell me exactly what you see when the spell is cast:

JASS:
function Trig_Ramstrike_Actions takes nothing returns nothing
 local effect wave
 local location loc
 local unit caster  = GetTriggerUnit()
 local unit target  = GetSpellTargetUnit()
 local real x       = GetWidgetX(caster)
 local real y       = GetWidgetY(caster)
 local real x2      = GetSpellTargetX()
 local real y2      = GetSpellTargetY()
 local integer wait = 0

    if GetTerrainCliffLevel(x, y) == GetTerrainCliffLevel(x2, y2) then
        if SquareRoot((x2-x)*(x2-x) + (y2-y)*(y2-y)) >= 250.00 then
            call SetUnitAnimation( caster , "spell throw" )
            call Knockback(caster, 400, Atan2(y2 - y, x2 - x), 1.5) 
            set wave = AddSpecialEffectTarget( "Abilities\\Spells\\Orc\\Shockwave\\ShockwaveMissile.mdl", caster, "origin" )
            set loc = Location(0,0)
            call PolledWait(0.30)
            loop
                call BJDebugMsg(I2S(wait))
                call TriggerSleepAction(0.00)
                x = GetWidgetX(caster) 
                y = GetWidgetY(caster)
                x2 = GetWidgetX(target)
                y2 = GetWidgetY(target)
                if SquareRoot((x2-x)*(x2-x) + (y2-y)*(y2-y)) <= 150.00 then
                    call DestroyEffect(wave)
                    call MoveLocation(loc, x2, y2)
                    call PlaySoundAtPointBJ( gg_snd_MetalHeavySliceFlesh1, 100.00, loc, 0 )
                    
                    call Knockback(target, 150, Atan2(y2 - y, x2 - x), 1 )
                    call Knockback(caster, 75, Atan2(y - y2, x - x2), 1 )
                    
                    call UnitDamageTarget( caster , target, udg_RamstrikeDMG[GetUnitAbilityLevel(caster, 'A00B')], true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
                    call Stun( caster , target , udg_RamstrikeSTUN[GetUnitAbilityLevel(caster, 'A00B')] )
                    exitwhen true
                else
                    call MoveLocation(loc, x, y)
                    call AddSpecialEffectLocWithTimer(loc, "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl" , 2 )
                    exitwhen wait == 15
                    set wait = wait + 1
                    call BJDebugMsg(I2S(wait))
                endif
            endloop
            call RemoveLocation(loc)
            call DestroyEffect(wave)
        else
            call ErrorMsg(GetTriggerPlayer(), "Unit too close to ram")
            call IssueImmediateOrder(caster, "stop")
        endif
    else
        call ErrorMsg(GetTriggerPlayer(), "Cannot ram unit in different cliff level.")
        call IssueImmediateOrder(caster, "stop")
    endif
    set caster = null
    set target = null
    set loc = null
endfunction

function Trig_Ramstrike_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B'
endfunction

//===========================================================================
function InitTrig_Ramstrike takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( t, Condition( function Trig_Ramstrike_Conditions ) )
    call TriggerAddAction( t, function Trig_Ramstrike_Actions )
endfunction
 
Level 4
Joined
Oct 16, 2006
Messages
48
okay just tried.. doesn't seems to work but then I didn't use your code right away. because I changed the knockback function and it takes in Degree for this one instead of Radians, yours take in Radian right?
SO Am i allowed to use AngleBetweenPoints?


Anyway
so here's the new code. for this code, after I change the angle as mentioned, I get nothing, not a single debug msg.
btw do you have MSN? if you do. please add me [email protected]



JASS:
function Trig_Ramstrike_Actions takes nothing returns nothing
 local effect wave
 local location loc
 local unit caster  = GetTriggerUnit()
 local unit target  = GetSpellTargetUnit()
 local real x       = GetWidgetX(caster)
 local real y       = GetWidgetY(caster)
 local real x2      = GetSpellTargetX()
 local real y2      = GetSpellTargetY()
 local integer wait = 0
 local real angle = AngleBetweenPoints(GetUnitLoc(caster), GetUnitLoc(target))

    if GetTerrainCliffLevel(x, y) == GetTerrainCliffLevel(x2, y2) then
        if SquareRoot((x2-x)*(x2-x) + (y2-y)*(y2-y)) >= 250.00 then
            call SetUnitAnimation( caster , "spell throw" )
            call PolledWait(0.30)
            call KnockbackTarget(target, caster, angle, 600, 400, true, true, false) 
            set wave = AddSpecialEffectTarget( "Abilities\\Spells\\Orc\\Shockwave\\ShockwaveMissile.mdl", caster, "origin" )
            set loc = Location(0,0)
            loop
                call BJDebugMsg(I2S(wait))
                call TriggerSleepAction(0.00)
                set x = GetWidgetX(caster) 
                set y = GetWidgetY(caster)
                set x2 = GetWidgetX(target)
                set y2 = GetWidgetY(target)
                if SquareRoot((x2-x)*(x2-x) + (y2-y)*(y2-y)) <= 150.00 then
                    call DestroyEffect(wave)
                    call MoveLocation(loc, x2, y2)
                    call PlaySoundAtPointBJ( gg_snd_MetalHeavySliceFlesh1, 100.00, loc, 0 )
                    
                    call KnockbackTarget(caster, target, angle, 200, 100 , true, true, false )     
                    
                    call UnitDamageTarget( caster , target, udg_RamstrikeDMG[GetUnitAbilityLevel(caster, 'A00B')], true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
                    call Stun( caster , target , udg_RamstrikeSTUN[GetUnitAbilityLevel(caster, 'A00B')] )
                    exitwhen true
                else
                    call MoveLocation(loc, x, y)
                    call AddSpecialEffectLocWithTimer(loc, "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl" , 2 )
                    exitwhen wait == 15
                    set wait = wait + 1
                    call BJDebugMsg(I2S(wait))
                endif
            endloop
            call RemoveLocation(loc)
            call DestroyEffect(wave)
        else
            call ErrorMsg(GetTriggerPlayer(), "Unit too close to ram")
            call IssueImmediateOrder(caster, "stop")
        endif
    else
        call ErrorMsg(GetTriggerPlayer(), "Cannot ram unit in different cliff level.")
        call IssueImmediateOrder(caster, "stop")
    endif
    set caster = null
    set target = null
    set loc = null
endfunction

function Trig_Ramstrike_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B'
endfunction

//===========================================================================
function InitTrig_Ramstrike takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( t, Condition( function Trig_Ramstrike_Conditions ) )
    call TriggerAddAction( t, function Trig_Ramstrike_Actions )
endfunction
 
Status
Not open for further replies.
Top