- Joined
- Nov 22, 2006
- Messages
- 1,260
Jump v2.0
By: Silvenon
Credits to:
- Shadow1500 - JumpParabola function
- PitzerMike - TreeFilter function (not the original function name, though)
- PurplePoot - improvement suggestions
- PipeDream, Vexorian and the rest listed in the credits there - Jass NewGen Pack
- Vexorian - caster (Caster System) unit
- Yixx - helped me with a bit with efficiency and testing
v.0.1
- first release
- removed the Jump wrapper function
- minor performance improvements
- polished the function a bit
- remove an accidentally commented piece of line
- removed the Data returnage
- replaced the TreeFilter function, thanks to Av3n
- removed the CSSafety requirement since only one timer is used, thanks to PurplePoot (I was obviously too stupid to figure that out myself)
- fixed a syntax error (again, thanks to PurplePoot)
- added a new parameter: animation
- made the jumping unit stop any order
- fixed a bug with jumping on terrains that are higher or lower than 0
- the jumping unit cannot jump over map boundaries anymore
- fixed the code completely
- code actually works properly now
- maybe bezier later
- an efficiency fix, thanks to Yixx
- edited so it now uses the caster unit from Vexorian's CasterSystem
JASS:
library Jump initializer Init
// ****************************************************************************
// ** **
// ** Jump v.20 **
// ** —————————— **
// ** **
// ** Just a function I made for efficient jumping **
// ** **
// ****************************************************************************
//=======//
//Globals//
//=======//
globals
private integer DUMMY_ID = 'e000'
private integer array Ar
private constant real Interval = 0.035
private boolexpr Bool
private location Loc1 = Location(0, 0)
private location Loc2 = Location(0, 0)
private unit Dummy
private timer Tim = CreateTimer()
private integer Total = 0
private real MAX_X
private real MAX_Y
private real MIN_X
private real MIN_Y
endglobals
//===========================================================================
//========================================//
//Credits to Shadow1500 for this function!//
//========================================//
private function JumpParabola takes real dist, real maxdist, real curve returns real
local real t = (dist * 2) / maxdist - 1
return (- t * t + 1) * (maxdist / curve)
endfunction
//=======================================//
//Credits to PitzerMike for this function//
//=======================================//
private function TreeFilter takes nothing returns boolean
local destructable d = GetFilterDestructable()
local boolean i = IsDestructableInvulnerable(d)
local boolean result = false
call SetUnitPosition(Dummy, GetWidgetX(d), GetWidgetY(d))
if i then
call SetDestructableInvulnerable(d, false)
endif
set result = IssueTargetOrder(Dummy, "harvest", d)
if i then
call SetDestructableInvulnerable(d, true)
endif
call IssueImmediateOrder(Dummy, "stop")
set d = null
return result
endfunction
//===========================================================================
private function TreeKill takes nothing returns nothing
call KillDestructable(GetEnumDestructable())
endfunction
public struct Data
unit u
integer q
real md
real d
real c
real sin
real cos
integer i = 1
real p
real r
string s
static method create takes unit u, integer q, real x2, real y2, real c, real r, string s1, string s2, string anim returns Data
local Data dat = Data.allocate()
local real x1 = GetUnitX(u)
local real y1 = GetUnitY(u)
local real dx = x1 - x2
local real dy = y1 - y2
local real a = Atan2(y2 - y1, x2 - x1)
local location l1 = Location(x1, y1)
local location l2 = Location(x2, y2)
call MoveLocation(Loc1, x1, y1)
set dat.u = u
set dat.q = q
set dat.md = SquareRoot(dx * dx + dy * dy)
set dat.d = dat.md / q
set dat.c = c
set dat.sin = Sin(a)
set dat.cos = Cos(a)
set dat.p = (GetLocationZ(l2) - GetLocationZ(l1)) / q
set dat.r = r
set dat.s = s2
if s1 != "" and s1 != null then
call DestroyEffect(AddSpecialEffect(s1, x1, y1))
endif
call UnitAddAbility(u, 'Amrf')
call UnitRemoveAbility(u, 'Amrf')
call PauseUnit(u, true)
call SetUnitAnimation(u, anim)
call RemoveLocation(l1)
call RemoveLocation(l2)
set l1 = null
set l2 = null
return dat
endmethod
method onDestroy takes nothing returns nothing
local real x = GetUnitX(.u)
local real y = GetUnitY(.u)
local rect r
if .r != 0 then
set r = Rect(x - .r, y - .r, x + .r, y + .r)
call EnumDestructablesInRect(r, Bool, function TreeKill)
call RemoveRect(r)
set r = null
endif
if .s != "" and .s != null then
call DestroyEffect(AddSpecialEffect(.s, x, y))
endif
call PauseUnit(.u, false)
call IssueImmediateOrder(.u, "stop")
call SetUnitAnimation(.u, "stand")
call SetUnitFlyHeight(.u, 0, 0)
endmethod
endstruct
private function Execute takes nothing returns nothing
local Data dat
local integer i = 0
local real x
local real y
local location l
local real h
local rect r
loop
exitwhen i >= Total
set dat = Ar[i]
set x = GetUnitX(dat.u) + (dat.d) * dat.cos
set y = GetUnitY(dat.u) + (dat.d) * dat.sin
call MoveLocation(Loc2, x, y)
set h = JumpParabola(dat.d * dat.i, dat.md, dat.c) - (GetLocationZ(Loc2) - GetLocationZ(Loc1)) + dat.p * dat.i
if x < MAX_X and y < MAX_Y and x > MIN_X and y > MIN_Y then
call SetUnitX(dat.u, x)
call SetUnitY(dat.u, y)
endif
call SetUnitFlyHeight(dat.u, h, 0)
if dat.i >= dat.q then
call dat.destroy()
set Total = Total - 1
set Ar[i] = Ar[Total]
else
set dat.i = dat.i + 1
endif
set i = i + 1
endloop
if Total == 0 then
call PauseTimer(Tim)
endif
set l = null
endfunction
function Jump takes unit whichUnit, real dur, real destX, real destY, real curve, real radius, string sfx1, string sfx2, string anim returns nothing
local Data dat = Data.create(whichUnit, R2I(dur / Interval), destX, destY, curve, radius, sfx1, sfx2, anim)
if Total == 0 then
call TimerStart(Tim, Interval, true, function Execute)
endif
set Ar[Total] = dat
set Total = Total + 1
endfunction
//==================================================================================
private function Init takes nothing returns nothing
set Bool = Filter(function TreeFilter)
set Dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_ID, 0, 0, 0)
call UnitAddAbility(Dummy, 'Amrf')
call UnitRemoveAbility(Dummy, 'Amrf')
call UnitAddAbility(Dummy, 'Aloc')
call SetUnitAnimationByIndex(Dummy, 90)
call UnitAddAbility(Dummy, 'Ahrl')
set MAX_X = GetRectMaxX(bj_mapInitialPlayableArea) - 64
set MAX_Y = GetRectMaxY(bj_mapInitialPlayableArea) - 64
set MIN_X = GetRectMinX(bj_mapInitialPlayableArea) + 64
set MIN_Y = GetRectMinY(bj_mapInitialPlayableArea) + 64
endfunction
endlibrary
This is just Shadow1500's JumpParabola function put in use. Jump function makes a unit jump according to the following parameters:
- whichUnit = jumping unit
- dur = duration of the jump
- destX = x of the destination point
- destY = y of the destination point
- curve = well, uhmm, better look here for explanation
- radius = when the unit lands, it will kill all trees in this radius (if you don't want any tree killing, just put 0)
- sfx1 = jumping effect, if you don't want any, just put ""
- sfx2 = landing effect, if you don't want any, just put ""
- anim = animation played once during the jump (e. g. "attack"), you can put "", if you don't want any, just put ""
Copy the dummy unit called caster (Caster System) from Vexorian's CasterSystem map. The id of the copied unit in your map will most probably be 'e000', but if it's not, you MUST change the DUMMY_ID constant integer (in the code above) to that unit's id.
The reason why I used this specific version of a dummy unit is because I want to make you start using it (if you already haven't), because it's really great. You can have a single dummy unit for casting, effects etc. For effects you can just attach an effect to its origin, then you can modify the size, the vertex and whatever else with just applying the changes for the unit! Having that unit really simplifies everything and you don't have to create a dummy unit for each moving special effect.
All you need to do to be able to modify everything is do the following sequence:
JASS:
call UnitAddAbility(<caster>, 'Amrf')
call UnitRemoveAbility(<caster>, 'Amrf')
call UnitAddAbility(<caster>, 'Aloc')
call SetUnitAnimationByIndex(<caster>, 90)
You can change the Interval constant to modify the interval of the timer that's executing the jump, but it's really unnecessary.
Example of usage:
JASS:
function Test takes nothing returns nothing
local unit u = GetTriggerUnit()
local real d = 500
local real a = GetUnitFacing(u) * bj_DEGTORAD
local real dur = 1
local real x1 = GetUnitX(u)
local real y1 = GetUnitY(u)
local real x2 = x1 + d * Cos(a)
local real y2 = y1 + d * Sin(a)
local real c = 1.8
local real r = 200
local string sfx2 = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl"
call Jump(u, dur, x2, y2, c, r, "", sfx2, "")
endfunction
Requires: Jass NewGen Pack
Report any bugz plz!!!!111oneone
Last edited: