[jass=Condense]scope Condense initializer OnInit
//Condense by Strikest
globals
//Configurables
private constant integer ABIL_ID = 'A000' //Raw code of ability
private constant integer DBFF_ID = 'A004' //Raw code of magic amplification ability
private constant integer ORB_ID = 'h001' //Raw code of the water orb dummy
private constant integer CROW_ID = 'Amrf' //Raw code of Crow Form ability in your map. Should be 'Amrf', unless you modified it.
private constant string EFFECT = "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl" //Path of the special effect model when orb makes contact
private constant string ATTACH_POINT = "origin" //String of the attachment point you want
private constant boolean BOOLEAN_INCLUDE_GREEN_INT = true //Choose whether or not to include green int bonuses in damage calculations(If factoring int).
private constant real AOE = 116. //Area of effect of the orb
private constant attacktype ATK_TYPE = ATTACK_TYPE_NORMAL //Attacktype you want
private constant damagetype DMG_TYPE= DAMAGE_TYPE_NORMAL //Damagetype you want
private constant group GROUP = CreateGroup()//Dont touch this
private group GROUP2 //Or this
private unit CASTER //Or this
private integer CAST_LVL //Nor this
endglobals
private constant function DAMAGE takes integer levelofpassive,integer levelofcastspell, integer heroint returns real //Configure damage in this function
return levelofcastspell*heroint + 0.
endfunction
private constant function AMOUNT_OF_REVOLUTIONS takes integer levelofpassive,integer levelofcastspell returns integer //Configure how many times the orb will make a complete revolution around the caster
return levelofcastspell
endfunction
private constant function DURATION_NORMAL takes integer levelofpassive,integer levelofcastspell, integer heroint returns real //Configure the duration of the debuff for non-hero units
return 10.
endfunction
private constant function DURATION_HERO takes integer levelofpassive,integer levelofcastspell, integer heroint returns real //Configure the duration of the debuff for hero units
return 5.
endfunction
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~NO TOUCHY PAST THIS POINT UNLESS YOU KNOW WHAT YOU ARE DOING~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private struct Cdnse
unit cast
unit orb
integer lvl
integer dur
real a
group g
static method create takes nothing returns Cdnse
local Cdnse data=Cdnse.allocate()
if data.g==null then
set data.g=CreateGroup()
endif
return data
endmethod
method onDestroy takes nothing returns nothing
call GroupClear(.g)
endmethod
endstruct
private struct Dbuff
unit u
endstruct
native UnitAlive takes unit id returns boolean
private function Handler2 takes nothing returns nothing
local timer t = GetExpiredTimer()
local Dbuff data = GetTimerData(t)
call UnitRemoveAbility(data.u,DBFF_ID)
call data.destroy()
call ReleaseTimer(t)
set t = null
endfunction
private function FilterActions takes nothing returns boolean
local unit u = GetFilterUnit()
local integer i = GetUnitAbilityLevel(CASTER,ABIL_ID)
local integer int = GetHeroInt(CASTER,BOOLEAN_INCLUDE_GREEN_INT)
local real damage = DAMAGE(i,CAST_LVL,int)
local Dbuff data
local timer t
if UnitAlive(u) and IsUnitEnemy(u, GetOwningPlayer(CASTER)) and not IsUnitInGroup(u,GROUP2) and not IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE) then
call UnitDamageTarget(CASTER,u,damage,false,false,ATK_TYPE,DMG_TYPE,WEAPON_TYPE_WHOKNOWS)
call GroupAddUnit(GROUP2,u)
call DestroyEffect(AddSpecialEffectTarget(EFFECT,u,ATTACH_POINT))
//If you are capable enough, you can add any extra effects you want here
if GetUnitAbilityLevel(u,DBFF_ID) != 1 then
call UnitAddAbility(u,DBFF_ID)
set data = Dbuff.create()
set data.u = u
set t = NewTimer()
call SetTimerData(t,data)
if IsUnitType(u,UNIT_TYPE_HERO) then
call TimerStart(t,DURATION_HERO(i,CAST_LVL,int),false,function Handler2)
else
call TimerStart(t,DURATION_NORMAL(i,CAST_LVL,int),false,function Handler2)
endif
endif
endif
set u = null
set t= null
return false
endfunction
private function Handler takes nothing returns nothing
local timer t = GetExpiredTimer()
local Cdnse data = GetTimerData(t)
local real x
local real y
if data.dur <= 0 then
call RemoveUnit(data.orb)
call data.destroy()
call ReleaseTimer(t)
else
set data.a = data.a + 4.
set x = GetUnitX(data.cast) + 400. * Cos(data.a*bj_DEGTORAD)
set y = GetUnitY(data.cast) + 400. * Sin(data.a*bj_DEGTORAD)
call SetUnitX(data.orb,x)
call SetUnitY(data.orb,y)
if GetUnitFlyHeight(data.cast) >0 then
call SetUnitFlyHeight(data.orb,GetUnitFlyHeight(data.cast),0)
endif
set CASTER = data.cast
set CAST_LVL = data.lvl
set GROUP2 = data.g
call GroupEnumUnitsInRange(GROUP,x,y,AOE,Filter(function FilterActions))
set data.dur = data.dur - 4
call SetTimerData(t,data)
call TimerStart(t,.0325,false,function Handler)
endif
set t = null
endfunction
private function Actions takes nothing returns nothing
local unit cast = GetTriggerUnit()
local real casx = GetUnitX(cast)
local real casy = GetUnitY(cast)
local integer i = GetUnitAbilityLevel(cast,GetSpellAbilityId())
local real a = GetRandomReal(0.,360.) + GetUnitFacing(cast)
local real tarx
local real tary
local timer t = NewTimer()
local Cdnse data = Cdnse.create()
set tarx = casx + 400. * Cos(a*bj_DEGTORAD)
set tary = casy + 400. * Sin(a*bj_DEGTORAD)
set data.cast = cast
set data.lvl = i
set data.dur = 360*AMOUNT_OF_REVOLUTIONS(GetUnitAbilityLevel(cast,ABIL_ID),i)
set data.a = a
set data.orb = CreateUnit(GetOwningPlayer(cast),ORB_ID,tarx,tary,0.0)
call SetUnitPathing(data.orb,false)
call UnitAddAbility(data.orb,CROW_ID)
call SetTimerData(t,data)
call TimerStart(t,.0325,false,function Handler)
set cast = null
set t = null
endfunction
private function OnSpell takes nothing returns boolean
if GetUnitAbilityLevel(GetTriggerUnit(),ABIL_ID) != 0 then
call Actions()
endif
return false
endfunction
private function OnInit takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trig,Condition(function OnSpell))
set trig = null
endfunction
endscope[/code]