Nestharus - CTL; nestharus/JASS
Bribe - SpellEffectEvent; [Snippet] SpellEffectEvent
Magtheridon96 - RegisterPlayerUnitEvent; [Snippet] RegisterPlayerUnitEvent
Changelog
v1.0
-relase
v1.0a
-Fix Waves
-Fix SpellEffectEvent
-Fix Filter
v1.0b
-Add Vaccum Effect
-Fix Lightning deindex
-Fix Spell Effect Optional
v1.0c
-Prevent create/destroy lightning
-Infunction Index and DeIndex
Code: Select all
//***************************************************************************
//*
//* DOOM FUSE vJASS
//* v1.0c
//* by JC Helas
//*
//* FAQ
//* Q.How to Import?
//* A1. Goto File>Preferences>General> Mark "Automatically create unknown variable while pasting trigger data".
//* A2. Copy all custom object that spell need into your map.
//* A3. Copy Doom Fuse category into your map.
//* A4. Then done, have fun.
//*
//* Q.Is it Configurable?
//* A.1 You can configure all detailed constant functions what ever you want.
//* A.2 You can even remodel the spell and change some values amount.
//*
//*
//* Report any Bugs
//* Contact:[email protected]
//*
//* Credits
//* Magtheridn96
//* Nestharus
//* Bribe
//*
//* Changelog
//* v1.0
//* Initial Release
//* v1.0a
//* Fix Waves
//* Fix SpellEffectEvent
//* Fix Filter
//* v1.0b
//* Add Vaccum Effect
//* Fix Lightning deindex
//* Fix Spell Effect Optional
//* v1.0c
//* Prevent create/destroy lightning
//* Infunction Index and DeIndex
//*
//*
//***************************************************************************
scope DoomFuse
globals
// CONFIGURE SPELL
//
// Ability ID of spell
private integer ABILITY_ID = 'A000'
// Ability ID that makes dummy flyable
private integer FLY_ABILITY_ID = 'Amrf'
// Unit Type ID of dummy
private integer DUMMY_ID = 'u000'
// Model of dummy that was place at center
private string BALL_MODEL = "Abilities\\Spells\\Undead\\AntiMagicShell\\AntiMagicShell.mdl"
// Attach location of ball model
private string BALL_MODEL_ATTACH = "origin"
// Model of turning dummy
// attach to dummy that will turn to ball dummy
private string POST_MODEL = "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl"
// Attach location of post model
private string POST_MODEL_ATTACH = "origin"
// Effect that stands as vacuumer
private string VACUUM_MODEL = "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeTarget.mdl"
// Lighting Type
//
// "CLPB":Chain Lightning - Primary
// "CLSB":Chain Lightning - Secondary
// "DRAB":Drain
// "DRAM":Drain Mana
// "AFOD":Finger of Death
// "FORK":Fork Lightning
// "HWPB":Healing Wave
// "CHIM":Lightning Attack
// "LEAS":Magic Leash
// "MBUR":Mana Burn
// "MFPB":Mana Flare
// "SPLK":Spirit Link
//
// This lightning was use at damaging the target
// and summon every interval damage.
private string LIGHTNING_TYPE = "SPLK"
// Lightning life time
private real LIGHTNING_DURATION = 0.125
// Lightning type of damaging effect
// Effect that will stand as thunders hits the ground.
private string LIGHTNING_MARKS = "Abilities\\Weapons\\CannonTowerMissile\\CannonTowerMissile.mdl"
// Loop Periodic PS: Changing this may cause bigger change
private real PERIODIC = 0.031250
// Owner of all dummies
private player DUMMY_OWNER = Player(PLAYER_NEUTRAL_PASSIVE)
// Height of the center dummy
private real CENTER_BALL_HEIGHT = 400.0
// Duration of center dummy's travling to its height limit
private real FLY_DURATION = 2.0
// Duration of post dummies traveling to its distance limit from center
private real POST_TRAVEL_DURATION = 2.0
// Amount of post line that will rotate
private integer POST_NUMBERS = 6
// Max distance of post to center
private real POST_DISTANCE = 400.0
// Speed turning of 360 deg.
private real ROTATE_SPEED = 2.0//seconds
// Attack Type of damaging
private attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
// Damage Type of damaging
private damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
// Damage Per Interval
private real DAMAGE = 150.0
// Damage Base+(Amount Added each lvl)
private real DAMAGE_LVL = 25.0
// Damage Interval
private real DAMAGE_INTERVAL = 0.25
// Damage Range per interval
private real DAMAGE_RADIUS = 100.0
// Drop speed of all dummies at last wave
private real DROP_SPEED = 15.0
// Vacuum force speed
private real VACUUM_FORCE = 2.0
// Duration of damaging and post rotate
private real DURATION = 10.0
//END CONFIGURE
//***************************************************************************
// In this wave ball will raise,
// Upon reaching its height, ball will
// call forth of thunders that scars its
// designated area and causing damage
// as well as vacuuming enemy in area.
private constant integer WaveBall = 1
//***************************************************************************
// In this wave post are being summoned
private constant integer WaveCreatePost = 2
//***************************************************************************
// In this wave post are rotating
private constant integer WaveRotatePost = 3
//***************************************************************************
// In this wave every dummies are falling
// and deindex instance.
private constant integer WaveEnd = 4
endglobals
//***************************************************************************
native UnitAlive takes unit id returns boolean
//***************************************************************************
private constant function Damage takes integer lv returns real
return DAMAGE+(DAMAGE_LVL*lv)
endfunction
private constant function SinMax takes nothing returns real
return 90.0
endfunction
//***************************************************************************
private function SinSpeed takes real sm,real d returns real
return sm/(d/PERIODIC)
endfunction
//***************************************************************************
private function Filters takes unit u,unit t returns boolean
return UnitAlive(t) and not IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE) and not (GetUnitAbilityLevel(u,'Bvul') > 0) and not IsUnitAlly(u,GetOwningPlayer(t))
endfunction
//***************************************************************************
private struct LightningLifeTime
private static integer ix=0
private static integer array ic
private lightning l
private real r
implement CTL
local integer i=1
local real c
implement CTLExpire
loop
exitwhen i>ix
set this=ic[i]
if r>PERIODIC then
set r=r-PERIODIC
set c=Sin(((SinMax()/LIGHTNING_DURATION)*r)*bj_DEGTORAD)
call SetLightningColor(l,c,c,c,c)
else
set i=DeIndex(i)
endif
set i=i+1
endloop
implement CTLEnd
private static method DeIndex takes integer i returns integer
local thistype this=ic[i]
set l=null
call destroy()
set ic[i]=ic[ix]
set ix=ix-1
return i-1
endmethod
private static method Index takes nothing returns thistype
local thistype this=create()
set ix=ix+1
set ic[ix]=this
return this
endmethod
static method SetTime takes lightning lh,real d returns nothing
local thistype this
set this=Index()
set l=lh
set r=d
endmethod
endstruct
private struct DoomFuse
private unit Caster
private unit Dummy
private real SpellX
private real SpellY
private real Sins
private real SinW2
private real HeightW3
private real Duration
private real AngleW23
private integer Waves
private integer Level
private boolean LeftRightW3
private effect Models
private lightning Lightning
private static group GroupDamage=CreateGroup()
private static boolean LeftRight=false
private static integer ix=0
private static integer array ic
implement CTL
local integer i=1
local thistype dis
local real x
local real y
local real a
local unit u
implement CTLExpire
loop
exitwhen i>ix
set this=ic[i]
if Waves==WaveBall then
if Sins<SinMax() then
set Sins=Sins+SinSpeed(SinMax(),FLY_DURATION+POST_TRAVEL_DURATION)
call SetUnitFlyHeight(Dummy,Sin(Sins*bj_DEGTORAD)*CENTER_BALL_HEIGHT,0.0)
if Sins>=SinMax() then
call DestroyEffect(Models)
set Models=AddSpecialEffect(VACUUM_MODEL,GetUnitX(Dummy),GetUnitY(Dummy))
endif
else
set Sins=Sins+SinSpeed(SinMax(),DAMAGE_INTERVAL)
call GroupEnumUnitsInRange(GroupDamage,SpellX,SpellY,POST_DISTANCE,null)
loop
set u=FirstOfGroup(GroupDamage)
exitwhen u==null
if Filters(Caster,u) then
set x=GetUnitX(u)
set y=GetUnitY(u)
set a=Atan2(y-SpellY,x-SpellX)*bj_RADTODEG
call SetUnitX(u,x-VACUUM_FORCE*Cos(a*bj_DEGTORAD))
call SetUnitY(u,y-VACUUM_FORCE*Sin(a*bj_DEGTORAD))
endif
call GroupRemoveUnit(GroupDamage,u)
endloop
call GroupClear(GroupDamage)
if Sins>=(SinMax()*2) then
set a=GetRandomReal(0,359)
set x=SpellX+GetRandomReal(20.0,CENTER_BALL_HEIGHT)*Cos(a*bj_DEGTORAD)
set y=SpellY+GetRandomReal(20.0,CENTER_BALL_HEIGHT)*Sin(a*bj_DEGTORAD)
call DestroyEffect(AddSpecialEffect(LIGHTNING_MARKS,x,y))
call GroupEnumUnitsInRange(GroupDamage,x,y,DAMAGE_RADIUS,null)
loop
set u=FirstOfGroup(GroupDamage)
exitwhen u==null
if Filters(Caster,u) then
call UnitDamageTarget(Caster,u,Damage(Level),false,false,ATTACK_TYPE,DAMAGE_TYPE,null)
endif
call GroupRemoveUnit(GroupDamage,u)
endloop
call GroupClear(GroupDamage)
set Sins=SinMax()
call MoveLightningEx(Lightning,false,SpellX,SpellY,CENTER_BALL_HEIGHT,x,y,0.0)
call LightningLifeTime.SetTime(Lightning,LIGHTNING_DURATION)
endif
set Duration=Duration+PERIODIC
if Duration>=DURATION then
call DestroyLightning(Lightning)
set Waves=WaveEnd
set Duration=0.0
endif
endif
elseif Waves==WaveCreatePost then
if Sins<SinMax() then
set Sins=Sins+SinSpeed(SinMax(),POST_TRAVEL_DURATION)
set a=(POST_DISTANCE/SinMax())*Sins
set x=SpellX+a*Cos(AngleW23*bj_DEGTORAD)
set y=SpellY+a*Sin(AngleW23*bj_DEGTORAD)
if SinW2>=SinMax()/POST_NUMBERS then
if LeftRight then
set LeftRight=false
else
set LeftRight=true
endif
set dis=Index()
set dis.Waves=WaveRotatePost
set dis.Sins=0.0
set dis.Duration=0.0
set dis.HeightW3=POST_DISTANCE-a
set dis.Caster=Caster
set dis.SpellX=SpellX
set dis.SpellY=SpellY
set dis.AngleW23=AngleW23
set dis.LeftRightW3=LeftRight
set dis.Level=Level
set dis.Dummy=CreateUnit(DUMMY_OWNER,DUMMY_ID,x,y,0)
set dis.Models=AddSpecialEffectTarget(POST_MODEL,dis.Dummy,POST_MODEL_ATTACH)
call UnitAddAbility(dis.Dummy,FLY_ABILITY_ID)
call UnitRemoveAbility(dis.Dummy,FLY_ABILITY_ID)
set SinW2=0
endif
set SinW2=SinW2+SinSpeed(SinMax(),POST_TRAVEL_DURATION)
else
set Waves=WaveEnd
endif
elseif Waves==WaveRotatePost then
if Sins<SinMax() then
set Sins=Sins+SinSpeed(SinMax(),FLY_DURATION)
set a=Sin(Sins*bj_DEGTORAD)*(POST_DISTANCE-HeightW3)
set x=SpellX+a*Cos(AngleW23*bj_DEGTORAD)
set y=SpellY+a*Sin(AngleW23*bj_DEGTORAD)
elseif LeftRightW3 then
set AngleW23=AngleW23+(360/(ROTATE_SPEED/PERIODIC))
set a=Sin(Sins*bj_DEGTORAD)*(POST_DISTANCE-HeightW3)
set x=SpellX+a*Cos(AngleW23*bj_DEGTORAD)
set y=SpellY+a*Sin(AngleW23*bj_DEGTORAD)
if AngleW23==360 then
set AngleW23=0
endif
set Duration=Duration+PERIODIC
else
set AngleW23=AngleW23-(360/(ROTATE_SPEED/PERIODIC))
set a=Sin(Sins*bj_DEGTORAD)*(POST_DISTANCE-HeightW3)
set x=SpellX+a*Cos(AngleW23*bj_DEGTORAD)
set y=SpellY+a*Sin(AngleW23*bj_DEGTORAD)
if AngleW23==0 then
set AngleW23=360
endif
set Duration=Duration+PERIODIC
endif
call SetUnitFlyHeight(Dummy,Sin(Sins*bj_DEGTORAD)*HeightW3,0.0)
call SetUnitX(Dummy,x)
call SetUnitY(Dummy,y)
if Duration>=DURATION then
set Waves=WaveEnd
set Duration=0.0
endif
elseif Waves==WaveEnd then
if Dummy!=null then
set a=GetUnitFlyHeight(Dummy)
if a>=DROP_SPEED then
call SetUnitFlyHeight(Dummy,a-DROP_SPEED,0.0)
elseif Caster!=null then
call DestroyEffect(Models)
set Duration=1.0
set Caster=null
elseif Duration>PERIODIC then
set Duration=Duration-PERIODIC
elseif Duration<=PERIODIC then
call RemoveUnit(Dummy)
set Dummy=null
set Models=null
endif
else
set i=DeIndex(i)
endif
endif
set i=i+1
endloop
implement CTLEnd
private static method DeIndex takes integer i returns integer
local thistype this=ic[i]
call destroy()
set ic[i]=ic[ix]
set ix=ix-1
return i-1
endmethod
private static method Index takes nothing returns thistype
local thistype this=create()
set ix=ix+1
set ic[ix]=this
return this
endmethod
static method onCast takes nothing returns nothing
local integer i
local thistype this=Index()
set Waves=WaveBall
set Sins=0.0
set Duration=0.0
set Caster=GetTriggerUnit()
set SpellX=GetSpellTargetX()
set SpellY=GetSpellTargetY()
set Level=GetUnitAbilityLevel(Caster,ABILITY_ID)
set Dummy=CreateUnit(DUMMY_OWNER,DUMMY_ID,SpellX,SpellY,0)
set Models=AddSpecialEffectTarget(BALL_MODEL,Dummy,BALL_MODEL_ATTACH)
set Lightning=AddLightningEx(LIGHTNING_TYPE,false,0,0,0,0,0,0.0)
call SetLightningColor(Lightning,1,1,1,0)
call UnitAddAbility(Dummy,FLY_ABILITY_ID)
call UnitRemoveAbility(Dummy,FLY_ABILITY_ID)
set i=1
loop
exitwhen i>POST_NUMBERS
set this=Index()
set Waves=WaveCreatePost
set Sins=0.0
set SinW2=SinMax()/POST_NUMBERS
set AngleW23=(360/POST_NUMBERS)*i
set Caster=GetTriggerUnit()
set SpellX=GetSpellTargetX()
set SpellY=GetSpellTargetY()
set i=i+1
endloop
endmethod
private static method onCheckAbi takes nothing returns boolean
return GetSpellAbilityId()==ABILITY_ID
endmethod
static method onInit takes nothing returns nothing
local integer index
static if LIBRARY_SpellEffectEvent then
call RegisterSpellEffectEvent(ABILITY_ID, function thistype.onCast)
else
set gg_trg_Doom_Fuse = CreateTrigger()
set index = 0
loop
call TriggerRegisterPlayerUnitEvent(gg_trg_Doom_Fuse, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(gg_trg_Doom_Fuse, Condition(function thistype.onCheckAbi))
call TriggerAddAction(gg_trg_Doom_Fuse, function thistype.onCast)
endif
endmethod
endstruct
endscope