kingkingyyk3
Visitor (Welcome to the Jungle, Baby!)
- Reaction score
- 216
Fountain of Fire
Spell Info(Most people love this) :
GUI/Jass/vJass : vJass
MUI/non-MUI : MUI
System required : PUI
vJass here :
As usual, map is attached :
Spell Info(Most people love this) :
GUI/Jass/vJass : vJass
MUI/non-MUI : MUI
System required : PUI
vJass here :
JASS:
/////////////////////////////////////////////////////////////////////////////////////////////
// * * * //
// * * * * * kingking present : //
// * * * * * FOUNTAIN OF FIRE //
// * ~*~~ * //
// * | * | * Caster concentrates his fire energy //
// * | * | * to rip out waves of fire. //
// * | * | * //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Requires : Jass NewGen Pack v5d //
// PUI by Cohadar //
// Implement instruction : //
// 1) Copy this trigger. //
// 2) Copy PUI(If you don't have or already have another similar system) //
// 3) Copy dummy in Object Editor. (If you don't have) //
// 4) Copy ability in Object Editor. //
// 5) Adjust the rawcode to match your map. //
// 6) You may adjust the constants to meet your needs. //
// 7) Put the ability on a unit, save the map and enjoy it! //
// //
// //
// Current version : 2.0 //
/////////////////////////////////////////////////////////////////////////////////////////////
scope VolcanoEruption initializer Init
globals
//Ability's Settings//////
private constant integer ABIL_ID = 039;A000039;
private constant integer DUMMY_ID = 039;n000039;
private constant integer ORDER_ID = 852221//Order Id of ability. =)
private constant real RIP_OUT_RATE = .1
private constant real MANA_PER_BOLT = 2. //MANA_PER_BOLT * Level = Mana needed to fire a bolt
//////////////////////////
//Dummy's Settings////////
private constant real SLIDE_PERIOD = .03125
private constant real MAX_AOE = 600.
private constant real MAX_DUMMY_HEIGHT = 500.
private constant integer SLIDE_TICKS = 20 //Range * SLIDE_TICKS = Distance travelled by dummy
private constant real ANGLE_INCREASEMENT = 20.
private constant real AOE_INCREASEMENT = 50.
///////////////////////////
//Damage Settings//////////
private constant real DAMAGE = 20. //DAMAGE * Level = Total damage
private constant real DAMAGE_AOE = 150.
private constant attacktype ATK_TYPE = ATTACK_TYPE_NORMAL
private constant damagetype DMG_TYPE = DAMAGE_TYPE_NORMAL
private constant weapontype WPN_TYPE = null //Just for sound.
//////////////////////////
//Eye Candy Settings//////
private constant string GROUND_FIRE_EFFECT = "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeTarget.mdl"
private constant string GROUND_TEXTURE = "Textures\\VolcanoMed.blp"
private constant string FIRE_BALL = "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl"
//////////////////////////
endglobals
//==============================No more touching, children..===============================\\
private struct Data
unit cs
player p
integer lvl
real x
real y
real dmg
real manaPerBolt
real range
effect e
real angle
boolean stop
method onDestroy takes nothing returns nothing
call DestroyEffect(.e)
endmethod
endstruct
private struct DummyData
unit cs
unit dummy
player p
effect e
real x
real y
real angle
real range
real totalrange
real dis
real cos
real sin
real dmg
integer ticks
method onDestroy takes nothing returns nothing
call KillUnit(.dummy)
call DestroyEffect(.e)
endmethod
endstruct
private function GetParabolaZ takes real x,real d,real h returns real
return 4 * h * x * (d - x) / (d * d)
endfunction
globals//locals
private boolexpr PickUnitz // Pick and Damage =D
private group G = CreateGroup()
private unit U
private integer tempdata
private integer array CasterData
private integer Id
endglobals
globals//Caster Struct Stack?
private timer RipTimer = CreateTimer()
private integer array RipData
private integer RipCounter = 0
endglobals
globals//Dummy Struct Stack?
private timer SlideTimer = CreateTimer()
private integer array SlideData
private integer SlideCounter = 0
endglobals
private function DamageUnits takes nothing returns boolean
set U = GetFilterUnit()
if GetWidgetLife(U) > .405 and IsUnitEnemy(U,DummyData(tempdata).p) then
call UnitDamageTarget(DummyData(tempdata).cs,U,DummyData(tempdata).dmg,false,false,ATK_TYPE,DMG_TYPE,WPN_TYPE)
endif
return false
endfunction
private function Slide takes nothing returns nothing
local integer N_Slide = SlideCounter
local DummyData dd
loop
exitwhen N_Slide == 0
set dd = SlideData[N_Slide]
if dd.ticks > 0 then
set dd.ticks = dd.ticks - 1
set dd.x = dd.x + dd.cos
set dd.y = dd.y + dd.sin
set dd.dis = dd.dis + dd.range
call SetUnitPosition(dd.dummy,dd.x,dd.y)
call SetUnitFlyHeight(dd.dummy,GetParabolaZ(dd.dis,dd.totalrange,MAX_DUMMY_HEIGHT),0.)
else
set tempdata = dd
call GroupEnumUnitsInRange(G,dd.x,dd.y,DAMAGE_AOE,PickUnitz)
call dd.destroy()
set SlideData[N_Slide] = SlideData[SlideCounter]
set SlideCounter = SlideCounter - 1
endif
set N_Slide = N_Slide - 1
endloop
if SlideCounter == 0 then
call PauseTimer(SlideTimer)
endif
endfunction
private function CreateFire takes Data d, real ang returns nothing
local DummyData dd = DummyData.create()
set dd.x = d.x
set dd.y = d.y
set dd.p = d.p
set dd.cs = d.cs
set dd.dmg = d.dmg
set dd.ticks = SLIDE_TICKS
set dd.range = d.range / dd.ticks
set dd.angle = d.angle + ang
set dd.dummy = CreateUnit(dd.p,DUMMY_ID,dd.x,dd.y,dd.angle)
set dd.cos = dd.range * Cos(dd.angle * .0175)
set dd.sin = dd.range * Sin(dd.angle * .0175)
set dd.totalrange = dd.ticks * dd.range
set dd.dis = 0.
set dd.e = AddSpecialEffectTarget(FIRE_BALL,dd.dummy,"origin")
set SlideCounter = SlideCounter + 1
set SlideData[SlideCounter] = dd
if SlideCounter == 1 then
call TimerStart(SlideTimer,SLIDE_PERIOD,true,function Slide)
endif
endfunction
private function Rip takes nothing returns nothing
local integer N_Rip = RipCounter
local Data d
local DummyData dd
loop
exitwhen N_Rip == 0
set d = RipData[N_Rip]
if GetUnitCurrentOrder(d.cs) == ORDER_ID and GetUnitState(d.cs,UNIT_STATE_MANA) > d.manaPerBolt and not d.stop then
if d.range < 0. or d.range > MAX_AOE then
set d.range = 0.
endif
set d.range = d.range + AOE_INCREASEMENT
if d.angle > 360. then
set d.angle = 0.
endif
set d.angle = d.angle + ANGLE_INCREASEMENT
call CreateFire(d,0.)
call CreateFire(d,180.)
call SetUnitState(d.cs,UNIT_STATE_MANA,GetUnitState(d.cs,UNIT_STATE_MANA) - d.manaPerBolt)
else
if not d.stop then
set CasterData[GetUnitIndex(d.cs)] = 0
endif
call d.destroy()
set RipData[N_Rip] = RipData[RipCounter]
set RipCounter = RipCounter - 1
endif
set N_Rip = N_Rip - 1
endloop
if RipCounter == 0 then
call PauseTimer(RipTimer)
endif
endfunction
private function Act takes nothing returns nothing
local Data d = Data.create()
set d.cs = GetTriggerUnit()
set d.x = GetUnitX(d.cs)
set d.y = GetUnitY(d.cs)
set d.p = GetOwningPlayer(d.cs)
set d.lvl = GetUnitAbilityLevel(d.cs,ABIL_ID)
set d.dmg = DAMAGE * d.lvl
set d.manaPerBolt = MANA_PER_BOLT + d.lvl
set d.e = AddSpecialEffect(GROUND_FIRE_EFFECT,d.x,d.y)
set d.angle = GetRandomReal(0.,360.)
set d.range = 0.
set d.stop = false
set Id = GetUnitIndex(d.cs)
if CasterData[Id] != 0 then
set Data(CasterData[Id]).stop = true
endif
set CasterData[Id] = d
set RipCounter = RipCounter + 1
set RipData[RipCounter] = d
if RipCounter == 1 then
call TimerStart(RipTimer,RIP_OUT_RATE,true,function Rip)
endif
endfunction
private function Cond takes nothing returns boolean
return GetSpellAbilityId() == ABIL_ID
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_CHANNEL)
call TriggerAddCondition(t,Condition(function Cond))
call TriggerAddAction(t,function Act)
set PickUnitz = Condition(function DamageUnits)//Pick and damage. =D
endfunction
endscope
As usual, map is attached :