Tom_Kazansky
--- wraith it ! ---
- Reaction score
- 157
TSUNAMI
Calls forth the power of the sea, sending out a powerful tidal wave that travels a long distance, damages and knocks enemy units in its wake.
Calls forth the power of the sea, sending out a powerful tidal wave that travels a long distance, damages and knocks enemy units in its wake.
Some Info:
- vJass
- MUI
- Leakless (I think)
- Lagless
Screenshots
Code
JASS:
//===============================================================
//|
//| Tsunami
//| ¯¯¯¯¯¯¯
//| Requires:
//| - JassNewGen
//| - TimerUtils
//|
//| How to Import:
//| - Copy ability: "Tsunami" (A000)
//| - Copy unit: Dummy Unit - Tidal Wave (n000)
//| - Copy trigger: Tsunami and TimerUtils (if you don't have it)
//| - Changes the raw id of abilities, units,... in the globals block
//|
//| Modification:
//| - Values in the globals block and functions below it
//|
//| Credit
//| - Thanks Vexorian for TimerUtils
//| - Thanks Tinki3 for the Test Map Template
//|
//===============================================================
scope Tsunami initializer Init
globals
private constant integer AbilId = 039;A000039; //raw id of the ability
private constant integer WaveId = 039;n000039; //raw id of Wave dummy
private constant real SPEED = 1000. //speed of the wave
private constant string HITSFX = "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl" //sfx when the wave hit a unit
private constant string HITSFX_A = "origin" //attachment point of the above effect
endglobals
private function GetInitialDamage takes integer lvl returns real
return 100.+50*lvl //inital damage of the wave
endfunction
private function GetAdditionalDamage takes integer lvl returns real
return 50. * lvl //additinal damage of the wave
endfunction
private function GetWaveDistance takes integer lvl returns real
return 600. + 100 * lvl //distance of Tsunami
endfunction
//------ do not touch those below --------
//------ unless you know what are you doing -----
globals
private group ENUMER = CreateGroup()
private integer TEMPINT = 0
private real MinX
private real MinY
private real MaxX
private real MaxY
endglobals
private function GetPPX takes real x, real dist, real angle returns real
local real X = x + dist * Cos(angle * bj_DEGTORAD)
if X < MinX then
return MinX
endif
if X > MaxX then
return MaxX
endif
return X
endfunction
private function GetPPY takes real y, real dist, real angle returns real
local real Y = y + dist * Sin(angle * bj_DEGTORAD)
if Y < MinY then
return MinY
endif
if Y > MaxY then
return MaxY
endif
return Y
endfunction
private function GeometricDistance takes real x1,real y1, real x2, real y2,real x0,real y0 returns real
local real d
set d = ((y2-y1)*(x0-x1)-(x2-x1)*(y0-y1))/(SquareRoot( (y2-y1)*(y2-y1) + (x2-x1)*(x2-x1) ))
if d < 0 then
return -d
endif
return d
endfunction
private struct data
unit c
real cx
real cy
real dx
real dy
real cf
real dmg
real dps
unit array d [10]
group h
integer tick
integer tickmax
timer t
endstruct
private function TsunamiF takes nothing returns boolean
local data d = TEMPINT
local unit f = GetFilterUnit()
local boolean ok = false
if GetWidgetLife(f) > 0.405 then
if IsUnitEnemy(f,GetOwningPlayer(d.c)) then
if not IsUnitType(f,UNIT_TYPE_STRUCTURE ) then
set ok = true
endif
endif
endif
set f = null
return ok
endfunction
private function TsunamiE takes nothing returns nothing
local data d = GetTimerData( GetExpiredTimer() )
local integer i = 0
local unit p
local real x
local real y
local real gd
set d.tick = d.tick - 1
if d.tick == 0 then
loop
exitwhen i > 9
call SetUnitVertexColor(d.d<i>,255,255,255,0)
call SetUnitTimeScale(d.d<i>,1.)
call UnitApplyTimedLife(d.d<i>,039;BTLF039;,0.2)
set i = i + 1
endloop
call DestroyGroup(d.h)
call ReleaseTimer(d.t)
call d.destroy()
return
endif
if d.tick == d.tickmax - 1 then
loop
exitwhen i > 9
call SetUnitTimeScale(d.d<i>,3.)
set i = i + 1
endloop
endif
if d.tick == d.tickmax - 5 then
loop
exitwhen i > 9
call SetUnitTimeScale(d.d<i>,0.)
set i = i + 1
endloop
endif
set d.cx = GetPPX( d.cx, SPEED / 25., d.cf)
set d.cy = GetPPY( d.cy, SPEED / 25., d.cf)
set i = 0
loop
exitwhen i > 9
set x = GetPPX(d.cx, 200 - 50 * i ,d.cf+90)
set y = GetPPY(d.cy, 200 - 50 * i ,d.cf+90)
call SetUnitX(d.d<i>,x)
call SetUnitY(d.d<i>,y)
set i = i + 1
endloop
set d.dx = GetPPX( d.cx, 250, d.cf+90 )
set d.dy = GetPPY( d.cy, 250, d.cf+90 )
set TEMPINT = d
call GroupEnumUnitsInRange( ENUMER, d.cx, d.cy, 300., Condition( function TsunamiF ) )
loop
set p = FirstOfGroup(ENUMER)
exitwhen p == null
call GroupRemoveUnit(ENUMER,p)
set x = GetUnitX(p)
set y = GetUnitY(p)
set gd = GeometricDistance( d.cx, d.cy, d.dx, d.dy, x, y )
if gd <= 100. then
if not IsUnitInGroup(p,d.h) then
call DestroyEffect( AddSpecialEffectTarget( HITSFX,p,HITSFX_A))
call UnitDamageTarget(d.c,p,d.dmg,false,true,null,DAMAGE_TYPE_COLD ,null)
call GroupAddUnit(d.h,p)
else
call UnitDamageTarget(d.c,p, d.dps/25. ,false,true,null,DAMAGE_TYPE_COLD,null)
endif
call SetUnitPosition(p, GetPPX( x, 100. - gd , d.cf ), GetPPY( y, 125. - gd , d.cf ) )
endif
endloop
endfunction
private function Cond takes nothing returns boolean
return GetSpellAbilityId() == AbilId
endfunction
private function Act takes nothing returns nothing
local data d = data.create()
local integer i = 0
local location loc = GetSpellTargetLoc()
local integer lvl
local real x
local real y
set d.c = GetTriggerUnit()
set d.cx = GetUnitX(d.c)
set d.cy = GetUnitY(d.c)
set d.cf = bj_RADTODEG * Atan2(GetLocationY(loc) - d.cy,GetLocationX(loc) - d.cx)
set d.h = CreateGroup()
loop
exitwhen i > 9
set x = GetPPX(d.cx, 200 - 50 * i ,d.cf+90)
set y = GetPPY(d.cy, 200 - 50 * i ,d.cf+90)
set d.d<i> = CreateUnit(Player(15),WaveId, x,y,d.cf)
call SetUnitVertexColor(d.d<i>,255,255,255,67)
call SetUnitAnimation(d.d<i>,"Birth")
call SetUnitTimeScale(d.d<i>,0.)
set i = i + 1
endloop
set lvl = GetUnitAbilityLevel(d.c,AbilId )
set d.dmg = GetInitialDamage( lvl )
set d.dps = GetAdditionalDamage( lvl )
set d.tick = R2I( GetWaveDistance(lvl) / 25. )
set d.tickmax = d.tick
set d.t = NewTimer()
call SetTimerData(d.t,d)
call TimerStart( d.t, 0.04, true, function TsunamiE )
call RemoveLocation(loc)
set loc = null
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t, Condition( function Cond ) )
call TriggerAddAction( t, function Act )
set MinX = GetRectMinX( bj_mapInitialPlayableArea )
set MaxX = GetRectMaxX( bj_mapInitialPlayableArea )
set MinY = GetRectMinY( bj_mapInitialPlayableArea )
set MaxY = GetRectMaxY( bj_mapInitialPlayableArea )
endfunction
endscope
</i></i></i></i></i></i></i></i></i></i></i>
-----
Please comment