Trollvottel
never aging title
- Reaction score
- 262
SIMPLE DASH, made by Trollvottel.....
DESCRIPTION:
- The caster dashes to the target point
- Units standing in his way will be dragged with him
- At the target point the caster (well actually a dummy) stomps the ground and stunns all units
near him
Screenshot( it's bad, look at it ingame ):
Code (hope its not too bad, the first jass code i have written since month...):
Q: why is it called Simple dash?
A: because i simply was to lazy to think a better name. and because it's effect and coding are quite simple.
DESCRIPTION:
- The caster dashes to the target point
- Units standing in his way will be dragged with him
- At the target point the caster (well actually a dummy) stomps the ground and stunns all units
near him
Screenshot( it's bad, look at it ingame ):
Code (hope its not too bad, the first jass code i have written since month...):
JASS:
scope SimpleDash initializer Init
//=================================================================================================
//So thats my Simple Dash Spell
// DESCRIPTION:
// - The caster dashes to the target point
// - Units standing in his way will be dragged with him
// - At the target point the caster (well actually a dummy) stomps the ground and stunns all units
// near him
//==================================================================================================
// HOW TO IMPORT:
// - Import the custom Buff
// - Import the custom Abilities ( the caster spell and the dummy spell)
// - Import the fade dummy
// - Import the Fading System
// - Import this trigger
// - Change the values below
//==================================================================================================
globals
// The rawcode of the Spell your hero is casting
private constant integer SpellId = 039;A000039;
// The rawcode of the Unit which is created as Fade-Dummy
private constant integer UnitID = 039;h000039;
// The rawcode of your caster dummy, you can use your own dummy if you alread have one
private constant integer DummyCasterId = 039;h001039;
// The rawcode of the spell casted by the caster dummy, should be an instant spell (without target)
private constant integer DummyCastSpellId = 039;A001039;
// Life time of the fading dummys
private constant real Dur = 0.6
// Speed the caster is dashing forward with
private constant real DashSpeed = 800.
// Radius of the Units to be picked and takes with the caster
private constant real PickRadius = 180.
// Frequence of the timer = 1 / Period
private constant real Period = 0.03125
// Creates a new fade dummy every XXX ticks
private constant integer NewEffectEvery = 5
// Animation played by the fade dummys
private constant string Animation = "attack"
// Animationspeed of the fade dummys
private constant real AnimationSpeed = 0.6
// Path of the effect which is attached to the caster while dashing
private constant string AttachedEffectPath = "Abilities\\Spells\\Other\\CrushingWave\\CrushingWaveMissile.mdl"
// Path of the effect which is created at the end of dashing
private constant string SpecialEndEffectPath = "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl"
// Attachment point for the AttachedEffectPath
private constant string AttachedEffectPoint = "origin"
// Order string for the dummy spell which is casted at the end of dashing
private constant string DummyCastOrderString = "stomp"
endglobals
// ==================================================================================================
// END OF EDITING ZONE !!!! END OF EDITING ZONE !!!! END OF EDITING ZONE !!!! END OF EDITING ZONE !!!
// ==================================================================================================
// (has some comments, so jass beginners can learn from it)
private struct SimpleDash
// struct members
unit which
integer ticks = 0
real xSpeed
real ySpeed
real cx
real cy
real facing
effect e
endstruct
globals
// needed for the timer loop
private integer N = 0 // number of struct instances at the moment
private SimpleDash array D // thats where we store all the values in
private integer MaxAlloc = 0 // number of max amount of structs allocated at the same time
private timer T = CreateTimer()
endglobals
// some filter which checks if the filter unit meets some conditions
private function IsGroundUnit takes nothing returns boolean
local unit g = GetFilterUnit()
local boolean b = IsUnitType(g, UNIT_TYPE_STRUCTURE) == false and IsUnitType(g, UNIT_TYPE_FLYING) == false and IsUnitType(g, UNIT_TYPE_MAGIC_IMMUNE) == false
set g = null
return b
endfunction
// function which gets units in the front of the caster, dont want to explain how it works...
private function UnitsInFront takes unit which, real radius returns group
local real x = GetUnitX(which)
local real y = GetUnitY(which)
local real xx
local real yy
local real angle
local real face = GetUnitFacing(which)
local real absmod
local group g = CreateGroup()
local group gg = CreateGroup()
local unit u
call GroupEnumUnitsInRange(g, x, y, radius, Condition(function IsGroundUnit))
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g, u)
set xx = GetUnitX(u)
set yy = GetUnitY(u)
set angle = Atan2(y-yy,x-xx) * bj_RADTODEG
set absmod = ModuloReal(RAbsBJ(angle-face), 360)
if absmod > 90 and absmod < 270 then
call GroupAddUnit(gg, u)
endif
endloop
call DestroyGroup(g)
set g = null
return gg
endfunction
// just loops through a unit group and adds x/y-offset to their current position
private function Looping takes group g, real xOffset, real yOffset returns nothing
local unit u
loop
set u = FirstOfGroup(g)
exitwhen u == null
call GroupRemoveUnit(g, u)
call SetUnitX(u, GetUnitX(u)+xOffset)
call SetUnitY(u, GetUnitY(u)+yOffset)
endloop
endfunction
// this actually does the work
private function Callback takes nothing returns nothing
local integer i = N
local SimpleDash sw
local group g
local unit dummy
// this loop works through all instances
loop
exitwhen i <= 0
set sw = D<i> // makes the code easier to read
if ModuloInteger(sw.ticks, NewEffectEvery) == 0 then
// creates a fade dummy
call UFSYS_CreateFadeUnitAnimation(UnitID, sw.cx, sw.cy, sw.facing, Dur, Animation, AnimationSpeed)
call SetUnitAnimation(sw.which, Animation)
endif
// this moves the unit
set sw.cx = sw.cx + sw.xSpeed
set sw.cy = sw.cy + sw.ySpeed
call SetUnitX(sw.which, sw.cx)
call SetUnitY(sw.which, sw.cy)
// this picks the units in front and moves them
set g = UnitsInFront(sw.which, PickRadius)
call GroupRemoveUnit(g, sw.which)
call Looping.execute(g, sw.xSpeed, sw.ySpeed)
call DestroyGroup(g)
set g = null
set sw.ticks = sw.ticks - 1
if sw.ticks == 0 then
// END SPELL
call DestroyEffect(AddSpecialEffect(SpecialEndEffectPath, sw.cx, sw.cy)) // Eyecandy
// Creates a dummy and let cast him some ability
set dummy = CreateUnit(GetOwningPlayer(sw.which), DummyCasterId, sw.cx, sw.cy, 0)
call UnitAddAbility(dummy, DummyCastSpellId)
call SetUnitAbilityLevel(dummy, DummyCastSpellId, GetUnitAbilityLevel(dummy, SpellId))
call IssueImmediateOrder(dummy, DummyCastOrderString)
call UnitApplyTimedLife(dummy, 0, 1.5)
set dummy = null
// swap the current struct instance with the last active struct instance
set D<i> = D[N]
set D[N] = sw
// dont loop through this struct instance anymore
set N = N - 1
if N == 0 then
call PauseTimer(T)
endif
// make unit invulnerable and remove effect
call SetUnitInvulnerable(sw.which, false)
call SetUnitTimeScale(sw.which, 1)
call DestroyEffect(sw.e)
endif
set i = i - 1
endloop
endfunction
private function SpellActions takes unit caster, location point returns nothing
local real xx = GetLocationX(point)
local real yy = GetLocationY(point)
local real x = GetUnitX(caster)
local real y = GetUnitY(caster)
// get the deltas for:
local real deltaX = xx-x
local real deltaY = yy-y
//pythagoras....
local real dist = SquareRoot(deltaX*deltaX+deltaY*deltaY)
// calculates the number of ticks needed to move a certain distance with a certain speed
local integer ticks = R2I(dist / DashSpeed / Period)
// x and y moved with each tick
local real tickX = deltaX / I2R(ticks)
local real tickY = deltaY / I2R(ticks)
local real facing = Atan2(tickY, tickX) * bj_RADTODEG
//Blahblahblah....blah
call SetUnitAnimation(caster, "Attack")
call SetUnitFacing(caster, facing)
call SetUnitInvulnerable(caster, true)
call SetUnitTimeScale(caster, AnimationSpeed)
// increases number of instances we will loop through
set N = N + 1
if N > MaxAlloc then
// if the current number of instances is higher than the max-number we have to allocate a new
// instance:
set MaxAlloc = MaxAlloc + 1
set D[N] = SimpleDash.create()
endif
// applies the values
set D[N].which = caster
set D[N].cx = x
set D[N].cy = y
set D[N].xSpeed = tickX
set D[N].ySpeed = tickY
set D[N].ticks = ticks
set D[N].facing = facing
set D[N].e = AddSpecialEffectTarget(AttachedEffectPath, caster, AttachedEffectPoint)
call RemoveLocation(point)
set point = null
if N == 1 then
call TimerStart(T, Period, true, function Callback)
endif
endfunction
private function Actions takes nothing returns boolean
// does this need a comment? no...
if SpellId == GetSpellAbilityId() then
call SpellActions(GetTriggerUnit(), GetSpellTargetLoc())
endif
// dont even run the trigger
return false
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CHANNEL)
// add it as a condition
call TriggerAddCondition(t, Condition(function Actions))
endfunction
endscope
</i></i>
Q: why is it called Simple dash?
A: because i simply was to lazy to think a better name. and because it's effect and coding are quite simple.