Jumping Spell Template v3
A re-release of my old jump template, the first of its kind mind you, that I simply ported to structs and updated some of the non-optimized parts of. Its a simple template for simple needs, however, its easy to use and works as intended.
This allows you to jump a unit from here to there, while being able to edit every little aspect you can think of: speed, animation, effects, area, damage, arc, and even the offset between where the unit lands and where the spell was cast.
Version Info:
- 4: Jumping Spell Template v3 - Minor coding updates, syntax change dramatically (check it out in the Read Me), no longer requires CSSafety or CSCache and now runs on only 1 timer, now supports jumping over and onto different terrain heights (check it out in game!), new public function to check terrain pathability added, added error messages for invalid inputs
- 3: Jumping Spell Template v2 - Now works in radians, a few other minor improvements to the code, a pathability check is now ran to keep jumping units in the map, now damages all ground units correctly
- 2: Jumping Spell Template v1 - Ported to structs, updated some stupid coding methods, made it an actual template
, new test map!
- 1: Jump Template - Original release
JASS:
//***************************************************************************
//* *
//* Jumping Spell Template v3 *
//* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ **URL in the works *
//* Parabola function by Shadow1500 *
//* System by emjlr3 *
//* *
//* Requires: *
//* ¯¯¯¯¯¯¯¯¯ *
//* *
//* - A vJASS Preprocessor *
//* *
//***************************************************************************
library JST initializer InitJST
globals
// Speed at which unit's periodic movement is completed (.01-.04 recommended)
private constant real Interval = .025
// Value which represents the arc of the jump movement (1.-2.), closer to 2. for a flatter arc
private constant real Arc = 1.3
// Rawcode of the Crow Form ability in your map. This need only be changed if you have edited this ability
// in which case, create a new, unedited copy and use it here
private constant integer CrowForm = 'Amrf'
// Rawcode of peasant unit in your map. This need only be changed if you have edited this unit
// in which case, create a new, unedited copy and ise it here
private constant integer Peasant = 'hpea'
endglobals
//=====No touching past this point=====\\
globals
private real Game_MaxX
private real Game_MinX
private real Game_MaxY
private real Game_MinY
private constant real Runs = 1./Interval
private constant integer HalfRuns = R2I(Runs/2.)
private location L
private sound S = CreateSoundFromLabel( "InterfaceError",false,false,false,10,10)
endglobals
private function Parabola takes real dist, real maxdist returns real
local real t = (dist*2)/maxdist-1
return (-t*t+1)*(maxdist/Arc)
endfunction
private function InitJST takes nothing returns nothing
set Game_MaxX = GetRectMaxX(bj_mapInitialPlayableArea)-50.
set Game_MinX = GetRectMinX(bj_mapInitialPlayableArea)+50.
set Game_MaxY = GetRectMaxY(bj_mapInitialPlayableArea)-50.
set Game_MinY = GetRectMinY(bj_mapInitialPlayableArea)+50.
endfunction
public function CheckLocPathing takes location l returns boolean
local unit u = CreateUnitAtLoc( Player(13), Peasant, l, 0. )
local real x = GetUnitX(u) - GetLocationX(l)
local real y = GetUnitY(u) - GetLocationY(l)
local boolean b = false
if x < 1. and x > -1. and y < 1. and y > -1. then
set b = true
endif
call ShowUnit(u,false)
call KillUnit(u)
call RemoveLocation(l)
set u = null
return b
endfunction
private function SafeX takes real x returns real
if x<Game_MinX then
return Game_MinX
elseif x>Game_MaxX then
return Game_MaxX
endif
return x
endfunction
private function SafeY takes real y returns real
if y<Game_MinY then
return Game_MinY
elseif y>Game_MaxY then
return Game_MaxY
endif
return y
endfunction
private struct dat
unit u
real area
real damage
real maxdist
real movedist
real cos
real sin
real diff
real start_z
string sfx
integer i = 0
endstruct
globals
private timer T = CreateTimer()
private dat array D
private integer Total = 0
endglobals
//Spell:
private function Filt takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(),bj_groupEnumOwningPlayer) and IsUnitType(GetFilterUnit(),UNIT_TYPE_FLYING)!=true
endfunction
private function Damage takes unit u, real dam, real x, real y, real area returns nothing
local group g = CreateGroup()
local unit v
set bj_groupEnumOwningPlayer = GetOwningPlayer(u)
call GroupEnumUnitsInRange(g, x, y, area, Condition(function Filt))
loop
set v = FirstOfGroup(g)
exitwhen v == null
call GroupRemoveUnit(g,v)
call UnitDamageTarget(u,v,dam,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)
endloop
call DestroyGroup(g)
set g = null
endfunction
private function Movement takes nothing returns nothing
local dat d
local integer i = 1
local real dist
local real height
local real x
local real y
loop
exitwhen i>Total
set d = D<i>
set d.i = d.i + 1
set dist = d.i*d.movedist
set L = GetUnitLoc(d.u)
set height = GetLocationZ(L)
if height<d.start_z then
set height = (d.start_z-height)+Parabola(dist,d.maxdist)
elseif height>d.start_z then
if d.start_z+Parabola(dist,d.maxdist)<=height then
set height = 0.
else
set height = Parabola(dist,d.maxdist)-(height-d.start_z)
endif
else
set height = Parabola(dist,d.maxdist)
endif
call RemoveLocation(L)
call SetUnitX(d.u,SafeX(GetUnitX(d.u)+d.movedist*d.cos))
call SetUnitY(d.u,SafeY(GetUnitY(d.u)+d.movedist*d.sin))
call SetUnitFlyHeight(d.u,height,0.)
call DisplayTextToPlayer(Player(0),0.,0.,"ZLoc = "+R2S(GetLocationZ(GetUnitLoc(d.u)))+" : FlyHeight = "+R2S(GetUnitFlyHeight(d.u)))
if d.i == HalfRuns then
call SetUnitTimeScale(d.u, 1.)
elseif height<=1. then
call PauseUnit( d.u,false )
call SetUnitPathing( d.u, true )
call SetUnitFlyHeight(d.u,GetUnitDefaultFlyHeight(d.u),0.)
set x = GetUnitX(d.u) + d.diff * d.cos
set y = GetUnitY(d.u) + d.diff * d.sin
call DestroyEffect(AddSpecialEffect(d.sfx, x,y))
call Damage(d.u, d.area, x, y, d.damage)
call d.destroy()
set D<i> = D[Total]
set Total = Total - 1
set i = i - 1
if Total==0 then
call PauseTimer(T)
endif
endif
set i = i + 1
endloop
endfunction
//===========================================================================
public function Cast takes unit u, real damage, real area, real diff, string anim, string sfx returns boolean
local dat d
local real ux
local real uy
local location l
local real ang
local real x
local real y
if u==null or damage<0. or area<0. then
if GetLocalPlayer()==GetOwningPlayer(u) then
call ClearTextMessages()
call BJDebugMsg("|c00FF0000JST Error: Invalid inputs in function Cast.")
call StartSound(S)
endif
return false
endif
set d = dat.create()
set ux = GetUnitX(u)
set uy = GetUnitY(u)
set l = GetSpellTargetLoc()
set ang = Atan2((GetLocationY(l)-uy),(GetLocationX(l)-ux))
set x = GetLocationX(l) - diff * Cos(ang)
set y = GetLocationY(l) - diff * Sin(ang)
set d.u = u
set d.damage = damage
set d.area = area
set d.sfx = sfx
set d.maxdist = SquareRoot((ux-x)*(ux-x) + (uy-y)*(uy-y))
set d.cos = Cos(ang)
set d.sin = Sin(ang)
set d.movedist = d.maxdist/Runs
set d.diff = diff
set L = GetUnitLoc(d.u)
set d.start_z = GetLocationZ(L)
call RemoveLocation(L)
call PauseUnit( u,true )
call SetUnitPathing( u, false )
call UnitAddAbility( u,CrowForm )
call UnitRemoveAbility( u,CrowForm )
call SetUnitAnimation(u, anim)
call SetUnitTimeScale(u, .30)
set Total = Total + 1
if Total == 1 then
call TimerStart(T,Interval,true,function Movement)
endif
set D[Total] = d
call RemoveLocation(l)
set l = null
return true
endfunction
endlibrary</i></i>
Please test, comment, and enjoy!
Attachments
-
168.5 KB Views: 1,472
-
72.6 KB Views: 1,096