Help making line spells

MagnaGuard

Active Member
Reaction score
49
Hey, I'm having trouble trying to create line spells in jass. It's difficult for me to find the distance between two places, angle between two targets and finally putting it together to enable it to work in jass :( So if someone could take me through little step by step, tha'd be nice :D

Thanks
 

Komaqtion

You can change this now in User CP.
Reaction score
469
Ok...

First, let me ask you why you would want to know the distance between to point ? :S
It's quite irrelevant to making a line spell, though maybe you want to like do 6 effects from the caster to the target, and you want to split the range inbetween there in 6 intervals ? :S
(Anyways, I'm going to assume that now :p)

Second, let's take a look at how it works in GUI:
Trigger:
  • Line Spells GUI
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Ability 1
    • Actions
      • -------- Just setting some variables to prevent leakage... --------
      • Set TempPoint = (Position of (Triggering unit))
      • Set TempPoint2 = (Target point of ability being cast)
      • -------- Here we're setting the distance between the previously set points... --------
      • Set TempReal = (Distance between TempPoint and TempPoint2)
      • -------- And now I divide it into 6 different parts <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink ;)" loading="lazy" data-shortname=";)" /> --------
      • Set TempReal2 = (TempReal / 6.00)
      • -------- And here, the angle between the two points... --------
      • -------- Notice that I&#039;m doing the angle FROM the caster TO the target ! <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin :D" loading="lazy" data-shortname=":D" /> --------
      • Set TempReal3 = (Angle from TempPoint to TempPoint2)
      • -------- Now we use a loop to create the different effects --------
      • For each (Integer A) from 1 to 6, do (Actions)
        • Loop - Actions
          • -------- Setting a new point offset the casters position --------
          • Set TempPoint3 = (TempPoint offset by TempReal2 towards TempReal3 degrees)
          • -------- And here we&#039;re creating the effects... --------
          • Special Effect - Create a special effect at TempPoint3 using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
          • -------- And also prevent leakage <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink ;)" loading="lazy" data-shortname=";)" /> --------
          • Special Effect - Destroy (Last created special effect)
          • Custom script: call RemoveLocation(udg_TempPoint3)
      • Custom script: call RemoveLocation(udg_TempPoint2)
      • Custom script: call RemoveLocation(udg_TempPoint)


There I added some comments for you to look at ;)

Now, as you can see, it's not that hard in GUI...

Now, if I convert that into JASS, it'll look like this:
JASS:
function Trig_Line_Spells_JASS_Converted_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == &#039;A00C&#039; ) ) then
        return false
    endif
    return true
endfunction

function Trig_Line_Spells_JASS_Converted_Actions takes nothing returns nothing
    // Just setting some variables to prevent leakage...
    set udg_TempPoint = GetUnitLoc(GetTriggerUnit())
    set udg_TempPoint2 = GetSpellTargetLoc()
    // Here we&#039;re setting the distance between the previously set points...
    set udg_TempReal = DistanceBetweenPoints(udg_TempPoint, udg_TempPoint2)
    // And now I divide it into 6 different parts <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink    ;)" loading="lazy" data-shortname=";)" />
    set udg_TempReal2 = ( udg_TempReal / 6.00 )
    // And here, the angle between the two points...
    // Notice that I&#039;m doing the angle FROM the caster TO the target ! <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
    set udg_TempReal3 = AngleBetweenPoints(udg_TempPoint, udg_TempPoint2)
    // Now we use a loop to create the different effects
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 6
    loop
        exitwhen bj_forLoopAIndex &gt; bj_forLoopAIndexEnd
        // Setting a new point offset the casters position
        set udg_TempPoint3 = PolarProjectionBJ(udg_TempPoint, udg_TempReal2, udg_TempReal3)
        // And here we&#039;re creating the effects...
        call AddSpecialEffectLocBJ( udg_TempPoint3, &quot;Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl&quot; )
        // And also prevent leakage <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink    ;)" loading="lazy" data-shortname=";)" />
        call DestroyEffectBJ( GetLastCreatedEffectBJ() )
        call RemoveLocation(udg_TempPoint3)
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
    call RemoveLocation(udg_TempPoint2)
    call RemoveLocation(udg_TempPoint)
endfunction

//===========================================================================
function InitTrig_Line_Spells_JASS_Converted takes nothing returns nothing
    set gg_trg_Line_Spells_JASS_Converted = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Line_Spells_JASS_Converted, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Line_Spells_JASS_Converted, Condition( function Trig_Line_Spells_JASS_Converted_Conditions ) )
    call TriggerAddAction( gg_trg_Line_Spells_JASS_Converted, function Trig_Line_Spells_JASS_Converted_Actions )
endfunction


And as you can see there, we're using quite a few "BJ"s there (If you don't know what BJ's are, it's just a whole function that Blizzard premade in JASS to mostly be used in GUI ;))

Those we always want to get rid of, since they are not as efficient as just typing in what the BJ's consist of.

The BJ's used here are:
JASS:
function DistanceBetweenPoints takes location locA, location locB returns real

JASS:
function AngleBetweenPoints takes location locA, location locB returns real


And:
JASS:
function PolarProjectionBJ takes location source, real dist, real angle returns location


Now all of them really look like this:
JASS:
function DistanceBetweenPoints takes location locA, location locB returns real
    local real dx = GetLocationX(locB) - GetLocationX(locA)
    local real dy = GetLocationY(locB) - GetLocationY(locA)
    return SquareRoot(dx * dx + dy * dy)
endfunction
function AngleBetweenPoints takes location locA, location locB returns real
    return bj_RADTODEG * Atan2(GetLocationY(locB) - GetLocationY(locA), GetLocationX(locB) - GetLocationX(locA))
endfunction
function PolarProjectionBJ takes location source, real dist, real angle returns location
    local real x = GetLocationX(source) + dist * Cos(angle * bj_DEGTORAD)
    local real y = GetLocationY(source) + dist * Sin(angle * bj_DEGTORAD)
    return Location(x, y)
endfunction


And, those really are exactly what you use instead of the BJ's (Though instead of all those [ljass]location[/ljass] everywhere, you really should try to use coordinates instead ;))

And also, we won't need those global GUI variables either, since we have local variables in JASS...

So, this is how it'd look without the BJ's and globals:
JASS:
function Trig_Line_Spells_JASS_Converted_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == &#039;A00C&#039; ) ) then
        return false
    endif
    return true
endfunction

function Trig_Line_Spells_JASS_Converted_Actions takes nothing returns nothing
    local location TempPoint = GetUnitLoc(GetTriggerUnit())
    local location TempPoint2 = GetSpellTargetLoc()
    local location TempPoint3
    local real dx = GetLocationX(TempPoint2) - GetLocationX(TempPoint)
    local real dy = GetLocationY(TempPoint2) - GetLocationY(TempPoint)
    local real TempReal = SquareRoot(dx * dx + dy * dy)
    local real TempReal2 = ( TempReal / 6.00 )
    local real TempReal3 = bj_RADTODEG * Atan2(GetLocationY(TempPoint2) - GetLocationY(TempPoint), GetLocationX(TempPoint2) - GetLocationX(TempPoint))
    local real x
    local real y
    local integer i = 0
    loop
        set x = GetLocationX(TempPoint) + TempReal2 * Cos(TempReal3 * bj_DEGTORAD)
        set y = GetLocationY(TempPoint) + TempReal2 * Sin(TempReal3 * bj_DEGTORAD)
        set TempPoint3 = Location(x, y)
        call DestroyEffect( AddSpecialEffectLoc( &quot;Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl&quot;, TempPoint3 ) )
        call RemoveLocation(TempPoint3)
        set i = i + 1
        exitwhen i &gt; 5
    endloop
    call RemoveLocation(TempPoint2)
    call RemoveLocation(TempPoint)
endfunction

//===========================================================================
function InitTrig_Line_Spells_JASS_Converted takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer i = 0
    loop
        call TriggerRegisterPlayerUnitEvent( t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
        set i = i + 1
        exitwhen i &gt; 11
    endloop
    call TriggerAddCondition( t, Condition( function Trig_Line_Spells_JASS_Converted_Conditions ) )
    call TriggerAddAction( t, function Trig_Line_Spells_JASS_Converted_Actions )
endfunction


And that is the basic stuff you need to know, but as I said...
You really should use coordinates instead of locations ;)

Here's a version using that:
JASS:
function Trig_Line_Spells_JASS_Converted_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == &#039;A00C&#039;
endfunction

function Trig_Line_Spells_JASS_Converted_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local real cx = GetUnitX( u )
    local real cy = GetUnitY( u )
    local real tx = GetSpellTargetX()
    local real ty = GetSpellTargetY()
    //local location TempPoint = GetUnitLoc(GetTriggerUnit())
    //local location TempPoint2 = GetSpellTargetLoc()
    //local location TempPoint3
    local real dx = tx - cx
    local real dy = ty - cy
    local real TempReal = SquareRoot(dx * dx + dy * dy)
    local real TempReal2 = ( TempReal / 6.00 )
    local real TempReal3 = bj_RADTODEG * Atan2(ty - cy, tx - cx)
    local real x
    local real y
    local integer i = 0
    loop
        set x = cx + TempReal2 * Cos(TempReal3 * bj_DEGTORAD)
        set y = cx + TempReal2 * Sin(TempReal3 * bj_DEGTORAD)
        call DestroyEffect( AddSpecialEffect( &quot;Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl&quot;, x, y ) )
        set i = i + 1
        exitwhen i &gt; 5
    endloop
endfunction

//===========================================================================
function InitTrig_Line_Spells_JASS_Converted takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer i = 0
    loop
        call TriggerRegisterPlayerUnitEvent( t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
        set i = i + 1
        exitwhen i &gt; 11
    endloop
    call TriggerAddCondition( t, Condition( function Trig_Line_Spells_JASS_Converted_Conditions ) )
    call TriggerAddAction( t, function Trig_Line_Spells_JASS_Converted_Actions )
endfunction


Hope you understand a bit more now at least ;)
 

Furby

Current occupation: News poster
Reaction score
144
BJ functions:

JASS:
function DistanceBetweenPoints takes location locA, location locB returns real
    local real dx = GetLocationX(locB) - GetLocationX(locA)
    local real dy = GetLocationY(locB) - GetLocationY(locA)
    return SquareRoot(dx * dx + dy * dy)
endfunction


JASS:
function AngleBetweenPoints takes location locA, location locB returns real
    return bj_RADTODEG * Atan2(GetLocationY(locB) - GetLocationY(locA), GetLocationX(locB) - GetLocationX(locA))
endfunction


You can use this ones or you can make or edit this ones and use those in your map.

EDIT: Komaqtion was faster. :(
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Use radian, so that you do not need to convert it to angle.

JASS:
local real TempReal3 = Atan2(ty - cy, tx - cx)
set x = cx + TempReal2 * Cos(TempReal3)
set y = cx + TempReal2 * Sin(TempReal3)
 

ultimate11

Active Member
Reaction score
25
i try this in gui and dont work its make me only one effect :((


Untitled Trigger 001
Events
Unit - A unit Starts the effect of an ability
Conditions
Actions
Set Tpoint[1] = (Position of (Triggering unit))
Set Tpoint[2] = (Target point of ability being cast)
Set Treal[1] = (Distance between Tpoint[1] and Tpoint[2])
Set Treal[2] = (Treal[1] / 6.00)
Set Treal[3] = (Angle from Tpoint[1] to Tpoint[2])
For each (Integer A) from 1 to 6, do (Actions)
Loop - Actions
Set Tpoint[3] = (Tpoint[1] offset by Treal[2] towards Treal[3] degrees)
Special Effect - Create a special effect at Tpoint[3] using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
Special Effect - Destroy (Last created special effect)
Custom script: call RemoveLocation(udg_Tpoint[3])
Custom script: call RemoveLocation(udg_Tpoint[1])
Custom script: call RemoveLocation(udg_Tpoint[2])
 

Komaqtion

You can change this now in User CP.
Reaction score
469
You need to make sure it looks like this:
Trigger:
  • Line Spells GUI
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Ability 1
    • Actions
      • -------- Just setting some variables to prevent leakage... --------
      • Set TempPoint = (Position of (Triggering unit))
      • Set TempPoint2 = (Target point of ability being cast)
        • -------- Here we&#039;re setting the distance between the previously set points... --------
      • et TempReal = (Distance between TempPoint and TempPoint2)
      • -------- And now I divide it into 6 different parts <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink ;)" loading="lazy" data-shortname=";)" /> --------
      • Set TempReal2 = (TempReal / 6.00)
      • -------- And here, the angle between the two points... --------
      • -------- Notice that I&#039;m doing the angle FROM the caster TO the target ! <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin :D" loading="lazy" data-shortname=":D" /> --------
      • Set TempReal3 = (Angle from TempPoint to TempPoint2)
      • -------- Now we use a loop to create the different effects --------
      • For each (Integer A) from 1 to 6, do (Actions)
        • Loop - Actions
          • -------- Setting a new point offset the casters position --------
          • Set TempPoint3 = (TempPoint offset by TempReal2 towards TempReal3 degrees)
          • -------- And here we&#039;re creating the effects... --------
          • Special Effect - Create a special effect at TempPoint3 using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
          • -------- And also prevent leakage <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink ;)" loading="lazy" data-shortname=";)" /> --------
          • Special Effect - Destroy (Last created special effect)
          • Custom script: call RemoveLocation(udg_TempPoint3)
      • Custom script: call RemoveLocation(udg_TempPoint2)
      • Custom script: call RemoveLocation(udg_TempPoint)


And not like this:
Trigger:
  • Line Spells GUI
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Ability 1
    • Actions
      • -------- Just setting some variables to prevent leakage... --------
      • Set TempPoint = (Position of (Triggering unit))
      • Set TempPoint2 = (Target point of ability being cast)
        • -------- Here we&#039;re setting the distance between the previously set points... --------
      • et TempReal = (Distance between TempPoint and TempPoint2)
      • -------- And now I divide it into 6 different parts <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink ;)" loading="lazy" data-shortname=";)" /> --------
      • Set TempReal2 = (TempReal / 6.00)
      • -------- And here, the angle between the two points... --------
      • -------- Notice that I&#039;m doing the angle FROM the caster TO the target ! <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin :D" loading="lazy" data-shortname=":D" /> --------
      • Set TempReal3 = (Angle from TempPoint to TempPoint2)
      • -------- Now we use a loop to create the different effects --------
      • For each (Integer A) from 1 to 6, do (Actions)
        • Loop - Actions
      • -------- Setting a new point offset the casters position --------
      • Set TempPoint3 = (TempPoint offset by TempReal2 towards TempReal3 degrees)
      • -------- And here we&#039;re creating the effects... --------
      • Special Effect - Create a special effect at TempPoint3 using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
      • -------- And also prevent leakage <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink ;)" loading="lazy" data-shortname=";)" /> --------
      • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation(udg_TempPoint3)
      • Custom script: call RemoveLocation(udg_TempPoint2)
      • Custom script: call RemoveLocation(udg_TempPoint)


So you really do have the actions inside the loop ;)

Oh, and I also noticed a mistake I've made...

You need to do this:
Code:
Set TempPoint3 = (TempPoint offset by [COLOR="Red"]((Real((Integer A))) x TempReal2)[/COLOR] towards TempReal3 degrees)

So it'll look like this:
Trigger:
  • Line Spells GUI
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Ability 1
    • Actions
      • -------- Just setting some variables to prevent leakage... --------
      • Set TempPoint = (Position of (Triggering unit))
      • Set TempPoint2 = (Target point of ability being cast)
      • -------- Here we&#039;re setting the distance between the previously set points... --------
      • Set TempReal = (Distance between TempPoint and TempPoint2)
      • -------- And now I divide it into 6 different parts <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink ;)" loading="lazy" data-shortname=";)" /> --------
      • Set TempReal2 = (TempReal / 6.00)
      • -------- And here, the angle between the two points... --------
      • -------- Notice that I&#039;m doing the angle FROM the caster TO the target ! <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin :D" loading="lazy" data-shortname=":D" /> --------
      • Set TempReal3 = (Angle from TempPoint to TempPoint2)
      • -------- Now we use a loop to create the different effects --------
      • For each (Integer A) from 1 to 6, do (Actions)
        • Loop - Actions
          • -------- Setting a new point offset the casters position --------
          • Set TempPoint3 = (TempPoint offset by ((Real((Integer A))) x TempReal2) towards TempReal3 degrees)
          • -------- And here we&#039;re creating the effects... --------
          • Special Effect - Create a special effect at TempPoint3 using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
          • -------- And also prevent leakage <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink ;)" loading="lazy" data-shortname=";)" /> --------
          • Special Effect - Destroy (Last created special effect)
          • Custom script: call RemoveLocation(udg_TempPoint3)
      • Custom script: call RemoveLocation(udg_TempPoint2)
      • Custom script: call RemoveLocation(udg_TempPoint)
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top