library Psychic initializer init requires RepeatData, GroupUtils
/*
spell Write by Daric Nguyen"
thanks to Rising_Dusk
//=============================================================
The spell very suitable with Blood Mage or Shaman :)
Description:
Your char make enemies around fly up
and when flyheight of enemy got to max
use Psychic and knock all enemies down
make enemies effected deal damage!
Hope useful!
Requires:
Group Utils
Repeat Data (or similar Time System )
*/
globals
private constant real DAMAGE=100 //Ability Damage
private constant real TIME=.03 //Time loop
private constant real RANGE=700 //Area of effect
private constant string FX="Models\\PsychicTarget.mdl" //Effect on target unit
private constant string SFX="Models\\GrandUndeadAura.mdl" // Effect on caster unit
private constant string SFX2="Models\\NewGroundEX.mdx" // Effect Explosion
private constant attacktype ATT=ATTACK_TYPE_HERO
private constant damagetype DMT=DAMAGE_TYPE_MAGIC
endglobals
function trig_con takes nothing returns boolean
return ( GetSpellAbilityId() == 'A000' )
endfunction
private struct Psychic extends RepeatData
unit caster
unit target
real fly
real mfly
boolean isfly
effect deff
real per
// variables
method onLoop takes nothing returns nothing
local real x
local real y
local real dx
local real dy
set x=GetUnitX(this.target)
set y=GetUnitY(this.target)
set dx=x+GetRandomReal(0,5)*Cos((GetUnitFacing((this.target)))*bj_DEGTORAD)
set dy=y+GetRandomReal(0,5)*Sin((GetUnitFacing((this.target)))*bj_DEGTORAD)
call UnitAddAbility((this.target),'Amrf')
call SetUnitPosition((this.target),dx,dy)
call SetUnitFlyHeight((this.target),this.fly,0)
call UnitRemoveAbility((this.target),'Amrf')
if this.isfly==true then // check is unit fly up
if this.fly>=this.mfly then
set this.isfly=false
endif
set this.fly=this.fly+4
else
if this.fly<=0 then
call this.stop()
endif
set this.fly=this.fly-100
endif
endmethod
method onStart takes nothing returns nothing
call PauseUnit(this.target,true)
call SetUnitTimeScalePercent(this.target,0) // stop target unit animation
set this.deff=AddSpecialEffectTarget(FX,this.target,"chest") // add effect on target
endmethod
method onEnd takes nothing returns nothing
set this.per=(this.mfly / 500) // calculate damage increases percent or decreases percent follow max fly height
if this.per<=.5 then
set this.per=.5 // if decreases damage percent less than 50%, set it's 50%
endif
if this.per>=1.2 then
set this.per=1.2 // if increases damage percent greater than 120%, set it's 120%
endif
call DestroyEffect(this.deff) // destroy effect attackment in target unit
call UnitDamageTarget(this.caster,this.target,DAMAGE*this.per,false,false,ATT,DMT,null)
call PauseUnit(this.target,false) // deal damage and unpause target unit
call SetUnitTimeScalePercent(this.target,100) // unstop unit animation
call DestroyEffect(AddSpecialEffect(SFX2,GetUnitX(this.target),GetUnitY(this.target))) // create explosion effect
set this.target=null
set this.caster=null
endmethod
endstruct
private function PsychicAUnit takes unit source, unit t, real max returns nothing
local Psychic ps=Psychic.create(0.03,0)
set ps.caster=source
set ps.target=t
set ps.mfly=max
set ps.isfly=true
set ps.fly=0
endfunction
private struct Psychic2 extends RepeatData
unit caster
unit dum
effect deff
real nfly
real xx
real yy
real t1
real t2
real scale
group g
// variables
method onLoop takes nothing returns nothing
local unit e
if this.t1<= 3.4 then
if this.t1==0 then
call SetUnitTimeScalePercent(this.caster,0)
endif
set this.t1=this.t1+0.06
// check unit around caster
call GroupEnumUnitsInRange(this.g,this.xx,this.yy,700,null)
loop
set e=FirstOfGroup(g)
exitwhen e==null
if IsUnitEnemy(e,GetOwningPlayer(this.caster)) and GetWidgetLife(e)>0.405 and IsUnitType(e,UNIT_TYPE_STRUCTURE)==false and IsUnitPaused(e)==false then
call PsychicAUnit(this.caster,e,(this.nfly+(GetRandomReal(-40,50)))) // pick up enum unit
endif
call GroupRemoveUnit(this.g,e)
endloop
call GroupRefresh(this.g)
set this.nfly=this.nfly-8
else
if this.t2 ==255 then
// unpause caster
call PauseUnit(this.caster,false)
call SetUnitTimeScalePercent(this.caster,100)
set this.caster=null
endif
set this.t2=this.t2-10
set this.scale=this.scale+0.02
endif
if this.t2<=0 then
call this.stop()
else
call SetUnitVertexColor(this.dum,R2I(this.t2),R2I(this.t2),R2I(this.t2),R2I(this.t2))
call SetUnitScale(this.dum, this.scale, this.scale, this.scale)
endif
set e=null
endmethod
method onStart takes nothing returns nothing
call PauseUnit(this.caster,true)
set this.dum=CreateUnit(Player(15),'h000',this.xx,this.yy,0)
set this.deff=AddSpecialEffectTarget(SFX,this.dum,"origin")
endmethod
method onEnd takes nothing returns nothing
// remove leak when method end
call DestroyEffect(this.deff)
call RemoveUnit(this.dum)
call ReleaseGroup(this.g)
set this.dum=null
endmethod
endstruct
function trig_act takes nothing returns nothing
local unit cast=GetTriggerUnit()
local real x=GetUnitX(cast)
local real y=GetUnitY(cast)
local Psychic2 this=Psychic2.create(0.05,0) // (0.05= time loop per 0.05s,0= never end if don't use call this.stop() in any method)
// now add some variables you need save in struct Psychic2
set this.caster=cast
set this.t1=0 // time tick one
set this.t2=255 // time tick two, also is alpha real
set this.yy=y // save Yof caster
set this.xx=x // save X of caster
set this.nfly=500 // save maximun fly height
set this.scale=1.00 // save scale
set this.g=NewGroup()
set cast=null
endfunction
//===========================================================================
function init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( trig, Condition( function trig_con ) )
call TriggerAddAction( trig, function trig_act )
set trig=null
endfunction
endlibrary