//////////////////////////////////
//LASER v1.2 //
// by: Nherwyziant //
//==============================//
//Requires: //
// T32 //
// GT //
// Recycle //
//==============================//
//Credits: //
// Jesus4Lyf //
// Nestharus //
// Vexorian //
//==============================//
//How to copy //
// Copy the dummy unit //
// Copy the codes below //
// Set values to the desired //
//////////////////////////////////
scope Laser
native UnitAlive takes unit id returns boolean
globals
private constant integer RAWCODE = 'A000' //~Spell Rawcode
private constant integer DUMMY = 'h000' //~Shadow Dummy Rawcode
private constant string L_FX = "AFOD" //~The lightning effect
private constant string L_FX2 = "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnMissile.mdl" //~The effect on the happy trails
private constant string L_FX3 = "Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl" //~The effect on hit
private constant string ANIMATION = "spell third" //The animation of the shadow
private constant real L_HEIGHT = 225 //~Height of lightning. Just right for Balnazzar :D
private constant real AOE = 150 //~AoE of lightning
private constant real DURATION = .75 //~DURATION OF SPELL ^___^
private constant real SHADOWLIFE = 2.5 //~The duration of the shadow
private constant attacktype ATK_TYPE = ATTACK_TYPE_HERO //~Attack type
private constant damagetype DMG_TYPE = DAMAGE_TYPE_MAGIC //~Damage type
endglobals
private function RANGE takes integer lvl returns real
return 1000. + (lvl * 500.)
endfunction
private function DMG takes integer lvl returns real
return lvl * 75.
endfunction
//Do not touch the remaining part, or else you will be a victim of a killer.
private struct Data
private static group GROUP = CreateGroup()
private static thistype this
private static conditionfunc cf
unit caster
unit shadow
player p
group dmgUnits
real x
real y
real z
real tx
real ty
real tz
real angle
real range
real speed
real dmg
real cos
real sin
integer lvl
integer ticks
lightning l
private static method DoDamage takes nothing returns boolean
local thistype this = thistype.this
local unit u = GetFilterUnit()
if IsUnitEnemy(u,.p) and UnitAlive(u) and IsUnitType(u,UNIT_TYPE_STRUCTURE) == false and not IsUnitInGroup(u,.dmgUnits) then
call UnitDamageTarget(.caster,u,.dmg,true,false,ATK_TYPE,DMG_TYPE,null)
call DestroyEffect(AddSpecialEffectTarget(L_FX3,u,"origin"))
call GroupAddUnit(.dmgUnits,u)
endif
return false
endmethod
private method periodic takes nothing returns nothing
if .ticks >= T32_Tick then
set .tx = .tx + .cos
set .ty = .ty + .sin
set .tz = GetLocationZ(Location(.tx,.ty))
if UnitAlive(.caster) then
call MoveLightningEx(.l,true,.x,.y,.z,.tx,.ty,.tz)
call DestroyEffect(AddSpecialEffect(L_FX2,.tx,.ty))
set thistype.this = this
call GroupEnumUnitsInRange(thistype.GROUP,.tx,.ty,AOE,thistype.cf)
else
call DestroyLightning(.l)
endif
else
call DestroyLightning(.l)
call .stopPeriodic()
call Group.release(.dmgUnits)
set .caster = null
set .l = null
endif
endmethod
implement T32x
private static method Action takes nothing returns boolean
local thistype this = thistype.create()
set .caster = GetTriggerUnit()
set .p = GetOwningPlayer(.caster)
set .x = GetUnitX(.caster)
set .y = GetUnitY(.caster)
set .z = GetLocationZ(Location(.x,.y)) + L_HEIGHT + GetUnitFlyHeight(.caster)
set .tx = GetSpellTargetX()
set .ty = GetSpellTargetY()
set .tz = GetLocationZ(Location(.tx,.ty))
set .lvl = GetUnitAbilityLevel(.caster,RAWCODE)
set .angle = Atan2(.ty-.y,.tx-.x)
set .range = RANGE(.lvl)
set .speed = .range / R2I(DURATION/T32_PERIOD)
set .dmg = DMG(.lvl)
set .cos = .speed * Cos(.angle)
set .sin = .speed * Sin(.angle)
set .l = AddLightningEx(L_FX,true,.x,.y,.z,.x,.y,.tz)
set .ticks = T32_Tick + R2I(DURATION/T32_PERIOD)
set .dmgUnits = Group.get()
set .tx = .x
set .ty = .y
call .startPeriodic()
return false
endmethod
private static method Action2 takes nothing returns boolean
local thistype this = thistype.create()
set .caster = GetTriggerUnit()
set .p = GetOwningPlayer(.caster)
set .x = GetUnitX(.caster)
set .y = GetUnitY(.caster)
set .tx = GetSpellTargetX()
set .ty = GetSpellTargetY()
set .angle = Atan2(.ty-.y,.tx-.x)
set .shadow = CreateUnit(.p,DUMMY,.x,.y,.angle*bj_RADTODEG)
call SetUnitAnimation(.shadow,ANIMATION)
call SetUnitVertexColor(.shadow,100,100,100,50)
call SetUnitScale(.shadow,1.5,1.5,1.5)
call UnitApplyTimedLife(.shadow,'BTLF',SHADOWLIFE)
call UnitAddAbility(.shadow,'Amrf')
call UnitRemoveAbility(.shadow,'Amrf')
call SetUnitFlyHeight(.shadow,GetUnitFlyHeight(.caster),0)
//Optional only.==========================================================//
call PlaySoundAtPointBJ(gg_snd_Ama_Firen_Mah_Lazar,100,Location(.x,.y),.z)
//========================================================================//
set .shadow = null
set .caster = null
return false
endmethod
private static method onInit takes nothing returns nothing
call GT_AddStartsEffectAction(function thistype.Action,RAWCODE)
call GT_AddBeginsCastingAction(function thistype.Action2,RAWCODE)
set thistype.cf = Condition(function thistype.DoDamage)
endmethod
endstruct
endscope