//TESH.scrollpos=0
//TESH.alwaysfold=0
//inico
Name | Type | is_array | initial_value |
//TESH.scrollpos=30
//TESH.alwaysfold=0
library bloodeyeQQQL initializer init
native UnitAlive takes unit id returns boolean //Easy and fast way to check if a unit is alive.
globals
private integer SPELL_ID = 'XXX1' //|The ability rawcode of the bloodeye.|\\
private integer EYE_ID = 'h000' //|The unit rawcode of the eye.|\\
private integer CROW_FORM = 'Arav' //|The Crow Form rawcode, actually it should be this in any map.|\\
private boolean DESTROY_ON_WALL = true //|If true then it will destroy when reaching a cliff wall.|\\
private real MOVE_INTERVAL = 0.02 //|The eye moves DEGREES_PER_MOVE_INTERVAL degree each 0.02 second.|\\
private real DEGREES_PER_MOVE_INTERVAL = 4. //|The eye moves 4. degrees each 0.02 seconds.|\\
private integer DURATION = 6 //|The maximum loop number, the loop number raises each MOVE_INTERVAL|\\
private real DISTANCE_BETWEEN_CASTER_AND_EYE = 300. //|The distance between the eye and the target.|\\
private real HEIGHT = 300. //|The constant height of the eye.|\\
private string DAMAGE_EFFECT = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl" //|The effect each time the target get damaged.|\\
private attacktype ATTACK_TYPE = ATTACK_TYPE_CHAOS //|The attack type of the damage dealt.|\\
private damagetype DAMAGE_TYPE = DAMAGE_TYPE_UNKNOWN //|The damage type of the damage dealt.|\\
private weapontype WEAPON_TYPE = null //|The weapon type of the damage dealt.|\\
private real array Damage
private real array TBDamage
endglobals
//Time for setting Damage and time between each damage.
private function SetDamage takes nothing returns nothing
set Damage[1] = 80
set Damage[2] = 120
set Damage[3] = 160
//Now time between damage.
set TBDamage[1] = 2.
set TBDamage[2] = 1.5
set TBDamage[3] = 1.
endfunction
//////////////////////////////////////////||||||||||||||||||||\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//////////////////////////////////////////|DO NOT TOUCH BELOW|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//////////////////////////////////////////||||||||||||||||||||\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
globals
private timer T = CreateTimer()
private integer array Data
private integer Total = 0
private constant location loc = Location(0.,0.)
endglobals
struct bloodeye
integer c //|Counter, it counts +1 every rotate step when it reaches ROTATIONS * 360 it stops.|\\
real max_c //|The maximum number of c.|\\
real i //|Time for damage|\\
unit u //|Caster.|\\
unit tt //|Target.|\\
unit e //|The eye.|\\
real h //h
real f //|The eye rotating degree.|\\
real x //|The target x coordinate.|\\
real y //|The target y coordinate.|\\
real ex //|The eye's x coordinate|\\
real ey //|The eye's y coordinate|\\
real d //|Distance between target and eye.|\\
static method Create takes unit c, unit t returns bloodeye
local bloodeye this = bloodeye.allocate()
local integer l
call MoveLocation(loc, GetSpellTargetX(),GetSpellTargetY())
set .u = c
set .f = 0.
set .tt = t
set l = GetUnitAbilityLevel(.u, SPELL_ID)
set .i = TBDamage[l] //Storing the time between each damage so I can subtract it from that variable (.i)
set .d = DISTANCE_BETWEEN_CASTER_AND_EYE
set .c = 0
set .e = CreateUnit(GetOwningPlayer(.u), EYE_ID, 0.0, 0.0, 0.0)
set .h = GetLocationZ(loc) + HEIGHT
call UnitAddAbility(.e, CROW_FORM)
call UnitRemoveAbility(.e, CROW_FORM)
set .max_c = DURATION * (MOVE_INTERVAL * 2500.)
set Data[Total] = this
if Total == 0 then
call TimerStart(T, MOVE_INTERVAL, true, function bloodeye.OnRotate)
endif
set Total = Total + 1
return this
endmethod
static method OnRotate takes nothing returns nothing
local bloodeye dat
local integer i = 0
local real xx
local real yy
local integer l
loop
exitwhen i == Total
set dat = Data[i]
set l = GetUnitAbilityLevel(dat.u, SPELL_ID)
set dat.x = GetUnitX(dat.tt)
set dat.y = GetUnitY(dat.tt)
set dat.ex = GetUnitX(dat.e)
set dat.ey = GetUnitY(dat.e)
if dat.i <= 0. then //If Time for damage less than or equal to 0 then do damage.
call UnitDamageTarget(dat.u, dat.tt, Damage[l], false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call DestroyEffect(AddSpecialEffect(DAMAGE_EFFECT, dat.x, dat.y))
set dat.i = TBDamage[l]
else
set dat.i = dat.i - MOVE_INTERVAL
endif
if dat.c > dat.max_c then
//Eye duration is over, kill the eye.
call dat.Destroy()
set Total = Total - 1
set Data[i] = Data[Total]
set i = i - 1
else
//Moving the eye.
set xx = dat.x + dat.d * Cos(dat.f * bj_DEGTORAD)
set yy = dat.y + dat.d * Sin(dat.f * bj_DEGTORAD)
call SetUnitY(dat.e, yy)
call SetUnitX(dat.e, xx)
call SetUnitFacingTimed(dat.e, bj_RADTODEG * Atan2(dat.y - dat.ey, dat.x - dat.ex), 0.)
call MoveLocation(loc, xx, yy)
call SetUnitFlyHeight(dat.e, dat.h - GetLocationZ(loc), 0.)
set dat.f = dat.f + DEGREES_PER_MOVE_INTERVAL
set dat.c = dat.c + 1
if DESTROY_ON_WALL then
if dat.h - GetLocationZ(loc) <= 0 then
call dat.Destroy()
endif
endif
if not UnitAlive(dat.tt) then
call dat.Destroy()
set Total = Total - 1
set Data[i] = Data[Total]
set i = i - 1
endif
endif
set i = i + 1
endloop
if Total == 0 then
call PauseTimer(T)
endif
endmethod
method Destroy takes nothing returns nothing
call KillUnit(.e)
set .u = null
set .tt = null
set .e = null
call .deallocate()
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
private function Actions takes nothing returns nothing
call bloodeye.Create(GetTriggerUnit(), GetSpellTargetUnit())
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
call SetDamage()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function Conditions))
call TriggerAddAction(t, function Actions)
endfunction
endlibrary