Name | Type | is_array | initial_value |
//TESH.scrollpos=9
//TESH.alwaysfold=0
globals
unit LastUnit
endglobals
function Revive takes nothing returns nothing
local integer u = GetUnitTypeId(LastUnit)
local real x = GetUnitX(LastUnit)
local real y = GetUnitY(LastUnit)
local real f = GetUnitFacing(LastUnit)
call TriggerSleepAction(15)
call CreateUnit(Player(12), u, x, y, f)
endfunction
function Trig_Respawn_Actions takes nothing returns nothing
if IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO) then
call ReviveHero(GetTriggerUnit(), GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), false)
else
set LastUnit = GetTriggerUnit()
call ExecuteFunc("Revive")
endif
endfunction
//===========================================================================
function InitTrig_Respawn takes nothing returns nothing
set gg_trg_Respawn = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Respawn, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddAction( gg_trg_Respawn, function Trig_Respawn_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
library GroupUtils initializer Init requires optional xebasic
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This library is a combination of several features relevant to groups. First
//* and foremost, it contains a group stack that you can access dynamic groups
//* from. It also provides means to refresh groups and clear any shadow
//* references within them. The included boolexprs are there for backwards
//* compatibility with maps that happen to use them. Since the 1.24c patch,
//* null boolexprs used in GroupEnumUnits* calls no longer leak, so there is no
//* performance gain to using the BOOLEXPR_TRUE constant.
//*
//* Instead of creating/destroying groups, we have moved on to recycling them.
//* NewGroup pulls a group from the stack and ReleaseGroup adds it back. Always
//* remember to call ReleaseGroup on a group when you are done using it. If you
//* fail to do so enough times, the stack will overflow and no longer work.
//*
//* GroupRefresh cleans a group of any shadow references which may be clogging
//* its hashtable. If you remove a unit from the game who is a member of a unit
//* group, it will 'effectively' remove the unit from the group, but leave a
//* shadow in its place. Calling GroupRefresh on a group will clean up any
//* shadow references that may exist within it. It is only worth doing this on
//* groups that you plan to have around for awhile.
//*
//* Constants that can be used from the library:
//* [group] ENUM_GROUP As you might expect, this group is good for
//* when you need a group just for enumeration.
//* [boolexpr] BOOLEXPR_TRUE This is a true boolexpr, which is important
//* because a 'null' boolexpr in enumeration
//* calls results in a leak. Use this instead.
//* [boolexpr] BOOLEXPR_FALSE This exists mostly for completeness.
//*
//* This library also includes a simple implementation of a group enumeration
//* call that factors collision of units in a given area of effect. This is
//* particularly useful because GroupEnumUnitsInRange doesn't factor collision.
//*
//* In your map, you can just replace all instances of GroupEnumUnitsInRange
//* with GroupEnumUnitsInArea with identical arguments and your spells will
//* consider all units colliding with the area of effect. After calling this
//* function as you would normally call GroupEnumUnitsInRange, you are free to
//* do anything with the group that you would normally do.
//*
//* If you don't use xebasic in your map, you may edit the MAX_COLLISION_SIZE
//* variable below and the library will use that as the added radius to check.
//* If you use xebasic, however, the script will automatically use xe's
//* collision size variable.
//*
//* You are also able to use GroupUnitsInArea. This function returns all units
//* within the area, no matter what they are, which can be convenient for those
//* instances where you actually want that.
//*
//* Example usage:
//* local group MyGroup = NewGroup()
//* call GroupRefresh(MyGroup)
//* call ReleaseGroup(MyGroup)
//* call GroupEnumUnitsInArea(ENUM_GROUP, x, y, 350., BOOLEXPR_TRUE)
//* call GroupUnitsInArea(ENUM_GROUP, x, y, 350.)
//*
globals
//If you don't have xebasic in your map, this value will be used instead.
//This value corresponds to the max collision size of a unit in your map.
private constant real MAX_COLLISION_SIZE = 197.
//If you are insane and don't care about any of the protection involved in
//this library, but want this script to be really fast, set this to true.
private constant boolean LESS_SAFETY = false
endglobals
globals
//* Constants that are available to the user
group ENUM_GROUP = CreateGroup()
boolexpr BOOLEXPR_TRUE = null
boolexpr BOOLEXPR_FALSE = null
endglobals
globals
//* Hashtable for debug purposes
private hashtable ht = InitHashtable()
//* Temporary references for GroupRefresh
private boolean Flag = false
private group Refr = null
//* Arrays and counter for the group stack
private group array Groups
private integer Count = 0
//* Variables for use with the GroupUnitsInArea function
private real X = 0.
private real Y = 0.
private real R = 0.
private hashtable H = InitHashtable()
endglobals
private function HookDestroyGroup takes group g returns nothing
if g == ENUM_GROUP then
call BJDebugMsg(SCOPE_PREFIX+"Warning: ENUM_GROUP destroyed")
endif
endfunction
debug hook DestroyGroup HookDestroyGroup
private function AddEx takes nothing returns nothing
if Flag then
call GroupClear(Refr)
set Flag = false
endif
call GroupAddUnit(Refr, GetEnumUnit())
endfunction
function GroupRefresh takes group g returns nothing
set Flag = true
set Refr = g
call ForGroup(Refr, function AddEx)
if Flag then
call GroupClear(g)
endif
endfunction
function NewGroup takes nothing returns group
if Count == 0 then
set Groups[0] = CreateGroup()
else
set Count = Count - 1
endif
static if not LESS_SAFETY then
call SaveInteger(ht, 0, GetHandleId(Groups[Count]), 1)
endif
return Groups[Count]
endfunction
function ReleaseGroup takes group g returns boolean
local integer id = GetHandleId(g)
static if LESS_SAFETY then
if g == null then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Null groups cannot be released")
return false
elseif Count == 8191 then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Max groups achieved, destroying group")
call DestroyGroup(g)
return false
endif
else
if g == null then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Null groups cannot be released")
return false
elseif not HaveSavedInteger(ht, 0, id) then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Group not part of stack")
return false
elseif LoadInteger(ht, 0, id) == 2 then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Groups cannot be multiply released")
return false
elseif Count == 8191 then
debug call BJDebugMsg(SCOPE_PREFIX+"Error: Max groups achieved, destroying group")
call DestroyGroup(g)
return false
endif
call SaveInteger(ht, 0, id, 2)
endif
call GroupClear(g)
set Groups[Count] = g
set Count = Count + 1
return true
endfunction
private function Filter takes nothing returns boolean
return IsUnitInRangeXY(GetFilterUnit(), X, Y, R)
endfunction
private function HookDestroyBoolExpr takes boolexpr b returns nothing
local integer bid = GetHandleId(b)
if HaveSavedHandle(H, 0, bid) then
//Clear the saved boolexpr
call DestroyBoolExpr(LoadBooleanExprHandle(H, 0, bid))
call RemoveSavedHandle(H, 0, bid)
endif
endfunction
hook DestroyBoolExpr HookDestroyBoolExpr
private constant function GetRadius takes real radius returns real
static if LIBRARY_xebasic then
return radius+XE_MAX_COLLISION_SIZE
else
return radius+MAX_COLLISION_SIZE
endif
endfunction
function GroupEnumUnitsInArea takes group whichGroup, real x, real y, real radius, boolexpr filter returns nothing
local real prevX = X
local real prevY = Y
local real prevR = R
local integer bid = 0
//Set variables to new values
set X = x
set Y = y
set R = radius
if filter == null then
//Adjusts for null boolexprs passed to the function
set filter = Condition(function Filter)
else
//Check for a saved boolexpr
set bid = GetHandleId(filter)
if HaveSavedHandle(H, 0, bid) then
//Set the filter to use to the saved one
set filter = LoadBooleanExprHandle(H, 0, bid)
else
//Create a new And() boolexpr for this filter
set filter = And(Condition(function Filter), filter)
call SaveBooleanExprHandle(H, 0, bid, filter)
endif
endif
//Enumerate, if they want to use the boolexpr, this lets them
call GroupEnumUnitsInRange(whichGroup, x, y, GetRadius(radius), filter)
//Give back original settings so nested enumerations work
set X = prevX
set Y = prevY
set R = prevR
endfunction
function GroupUnitsInArea takes group whichGroup, real x, real y, real radius returns nothing
local real prevX = X
local real prevY = Y
local real prevR = R
//Set variables to new values
set X = x
set Y = y
set R = radius
//Enumerate
call GroupEnumUnitsInRange(whichGroup, x, y, GetRadius(radius), Condition(function Filter))
//Give back original settings so nested enumerations work
set X = prevX
set Y = prevY
set R = prevR
endfunction
private function True takes nothing returns boolean
return true
endfunction
private function False takes nothing returns boolean
return false
endfunction
private function Init takes nothing returns nothing
set BOOLEXPR_TRUE = Condition(function True)
set BOOLEXPR_FALSE = Condition(function False)
endfunction
endlibrary
//TESH.scrollpos=89
//TESH.alwaysfold=0
library WrathOfZeus initializer init requires optional GroupUtils
globals
private constant integer ABILITY_ID = 'A000' //Raw code of the triggering ability
private constant integer DUMMY_ID = 'e001' //The dummy unit, please import dummy.mdl and make a proper dummy unit
private constant integer STATIC_LINKS = 32 //The links that are created when the orb crashes
private constant integer CHARGED_BOLTS_AMOUNT = 3 //The amount of orbiting missiles that are created around the caster when the ability is learned
private constant real CHARGED_BOLTS_SIZE = .88 //The scale value of the orbiting missiles
private constant real PRIMARY_BASE_DAMAGE = 130 //The base damage when the orb crashes
private constant real PRIMARY_INC_DAMAGE = 75 // The increment damage of the orb
private constant real SECONDARY_BASE_DAMAGE = 50 //The damage each static link deals
private constant real SECONDARY_INC_DAMAGE = 25 // The increment damage of each static link
private constant real BOLT_SCALE = 2.75 //The scale of the lightning bolt
private constant real NORMAL_OFFSET = 145 //The default rotating offset of the orbiting bolts
private constant real MAX_OFFSET = 425 //The maximum rotating offset the bolts can reach when overloading
private constant real ENUM_OFFSET = 75 //the range that units are checked from each static link. You should decrease this if you use a LOT of static links!
private constant string BALL_ART = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl" //The missiles that rotate around the cast
private constant string TAIL_LIGHTNING = "CLPB" //The lightning tail of the bolt
private constant string CHARGED_LIGHTNING = "CLSB" //The lightning tail of the secondary static links
private constant string ORBITAL_LIGHTNING = "DRAB" //The lightning that links all the orbital missiles
private constant string BOLT_LIGHTNING = "Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl" //The lightning bolt art
private constant string PRIMARY_EFFECT = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl" //The effect that is created upon impact
private constant string SECONDARY_EFFECT = "Abilities\\Spells\\Orc\\LightningShield\\LightningShieldBuff.mdl" //The effect that is created on damaged units of secondary effect
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MAGIC
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_MAGIC
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
///
private constant boolean USE_GROUPUTILS = true //Whether to use Group utils library, if the library isn't found, it will CreateGroup() instead
///
endglobals
////===============
globals
private location loc = Location(0, 0)
private location loc2 = Location(0, 0)
private integer instance = 0
private boolexpr BE
private constant group Group = CreateGroup()
private constant integer Cbolts = CHARGED_BOLTS_AMOUNT - 1
private real MINX
private real MINY
private real MAXX
private real MAXY
endglobals
/////=================
//Extra functions
//
private function SafeX takes real x returns real
local real rx=MINX+50
if(x<rx)then
return rx
endif
set rx=MAXX-50
if(x>rx)then
return rx
endif
return x
endfunction
private function SafeY takes real y returns real
local real ry=MINY+50
if(y<ry)then
return ry
endif
set ry=MAXY-50
if(y>ry)then
return ry
endif
return y
endfunction
/////////=======================================
private struct spark
unit u
lightning l
real ang
real sx
real sy
real x
real y
real time = 1.5
real time2 = 2
real dmg
group damaged
static integer tot = 0
static spark array ar
static timer stim = CreateTimer()
static method SecondaryEffects takes unit u, unit t, real x, real y returns nothing
local integer i = 1
local spark data
loop
exitwhen i > STATIC_LINKS
set data = spark.create()
set data.u = u
set data.sx = x
set data.sy = y
set data.x = x
set data.y = y
set data.ang = (360 / STATIC_LINKS) * i
static if USE_GROUPUTILS then
static if LIBRARY_GroupUtils then
set data.damaged = NewGroup()
else
set data.damaged = CreateGroup()
debug call BJDebugMsg(LIBRARY_PREFIX+": Could not find GroupUtils")
endif
else
set data.damaged = CreateGroup()
endif
if t != null then
call GroupAddUnit(data.damaged, t)
endif
set data.dmg = SECONDARY_BASE_DAMAGE + (SECONDARY_INC_DAMAGE * (GetUnitAbilityLevel(data.u, ABILITY_ID) - 1))
set data.l = AddLightning(CHARGED_LIGHTNING, true, x, y, x+5, y+5)
call SetLightningColor(data.l, .7, .7, 1, .7)
if spark.tot == 0 then
call TimerStart(spark.stim, .042, true, function spark.Loop)
endif
set spark.ar[spark.tot] = data
set spark.tot = spark.tot + 1
set i = i + 1
endloop
endmethod
static method Enum takes nothing returns boolean
local spark data = instance
local unit e = GetFilterUnit()
if IsUnitInGroup(e, data.damaged) then
set e = null
return false
else
if (not(IsUnitType(e, UNIT_TYPE_STRUCTURE))) and (GetWidgetLife(e)>.405) and (IsUnitEnemy(e, GetOwningPlayer(data.u))) then
call DestroyEffect(AddSpecialEffectTarget(SECONDARY_EFFECT, e, "origin"))
call UnitDamageTarget(data.u, e, data.dmg, false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call GroupAddUnit(data.damaged, e)
endif
endif
set e = null
return false
endmethod
static method Loop takes nothing returns nothing
local spark data
local integer i = 0
local real p
loop
exitwhen i >= spark.tot
set data = spark.ar[i]
if data.time > 0 then
set data.time = data.time - .042
set data.x = SafeX(data.x + 30 * Cos(data.ang * bj_DEGTORAD))
set data.y = SafeX(data.y + 30 * Sin(data.ang * bj_DEGTORAD))
set p = SquareRoot((data.x - data.sx) * (data.x - data.sx) + (data.y - data.sy) * (data.y - data.sy))
if p > 450 then
set data.sx = data.sx + 30 * Cos(data.ang * bj_DEGTORAD)
set data.sy = data.sy + 30 * Sin(data.ang * bj_DEGTORAD)
endif
set instance = data
call GroupEnumUnitsInRange(Group, data.x, data.y, ENUM_OFFSET, BE)
call MoveLocation(loc, data.sx, data.sy)
call MoveLocation(loc2, data.x, data.y)
call MoveLightningEx(data.l, true, data.sx, data.sy, GetLocationZ(loc), data.x, data.y, GetLocationZ(loc2))
else
if (SquareRoot((data.x - data.sx) * (data.x - data.sx) + (data.y - data.sy) * (data.y - data.sy)) > 50) and data.time2 > 0 then
set data.sx = data.sx + 30 * Cos(data.ang * bj_DEGTORAD)
set data.sy = data.sy + 30 * Sin(data.ang * bj_DEGTORAD)
call MoveLocation(loc, data.sx, data.sy)
call MoveLocation(loc2, data.x, data.y)
call MoveLightningEx(data.l, true, data.sx, data.sy, GetLocationZ(loc), data.x, data.y, GetLocationZ(loc2))
set instance = data
call GroupEnumUnitsInRange(Group, data.sx, data.sy, 125, BE)
set data.time2 = data.time2 - .04
else
call data.destroy()
set spark.tot = spark.tot - 1
set spark.ar[i] = spark.ar[spark.tot]
endif
endif
set i = i + 1
endloop
if spark.tot == 0 then
call PauseTimer(spark.stim)
endif
endmethod
method onDestroy takes nothing returns nothing
call DestroyLightning(.l)
static if USE_GROUPUTILS then
static if LIBRARY_GroupUtils then
call ReleaseGroup(.damaged)
else
call DestroyGroup(.damaged)
debug call BJDebugMsg(LIBRARY_PREFIX+": Could not find GroupUtils")
endif
else
call DestroyGroup(.damaged)
endif
endmethod
endstruct
private struct bolt
unit u
unit t
unit d
real damage
lightning l
effect art
static integer total = 0
static bolt array arr
static timer tim = CreateTimer()
static method create takes unit u, unit t returns bolt
local bolt data = bolt.allocate()
local real x
local real y
local real x2
local real y2
local sound snd
local string array s
local integer r = GetRandomInt(0, 1)
set s[0] = "Abilities\\Spells\\Orc\\LightningShield\\LightningShieldTarget.wav"
set s[1] = "Abilities\\Spells\\Orc\\LightningBolt\\LightningBolt.wav"
set data.u = u
set snd = CreateSound(s[r], false, false, true, 12700, 12700, "")
set x = GetUnitX(data.u) + 100 * Cos(GetUnitFacing(data.u) * bj_DEGTORAD)
set y = GetUnitY(data.u) + 100 * Sin(GetUnitFacing(data.u) * bj_DEGTORAD)
set data.d = CreateUnit(GetOwningPlayer(data.u), DUMMY_ID, x, y, 0)
call AttachSoundToUnit(snd, data.d)
set x2 = GetUnitX(data.d) + 200 * Cos((GetUnitFacing(data.u)-180) * bj_DEGTORAD)
set y2 = GetUnitY(data.d) + 200 * Sin((GetUnitFacing(data.u)-180) * bj_DEGTORAD)
set data.t = t
call UnitAddAbility(data.d, 'Amrf')
call UnitRemoveAbility(data.d, 'Amrf')
call SetUnitFlyHeight(data.d, 90, 550)
call SetUnitTimeScale(data.d, 0)
call SetUnitScale(data.d, BOLT_SCALE, BOLT_SCALE, BOLT_SCALE)
set data.l = AddLightning(TAIL_LIGHTNING, true, x2, y2, x, y)
call StartSound(snd)
call KillSoundWhenDone(snd)
set snd = null
set data.damage = PRIMARY_BASE_DAMAGE + (PRIMARY_INC_DAMAGE * (GetUnitAbilityLevel(data.u, ABILITY_ID)-1))
set data.art = AddSpecialEffectTarget(BOLT_LIGHTNING, data.d, "origin")
if bolt.total == 0 then
call TimerStart(bolt.tim, .0303, true, function bolt.Loop)
endif
set bolt.arr[bolt.total] = data
set bolt.total = bolt.total + 1
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\StormBolt\\StormBoltMissile.mdl", data.u, "weapon,right"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl", data.d, "origin"))
return data
endmethod
static method Loop takes nothing returns nothing
local bolt data
local integer i = 0
local real p = 0
local real a=0
local real x=0
local real y=0
local real x2=0
local real y2=0
local real z=0
local real d=0
local real dx=0
local real dy=0
loop
exitwhen i >= bolt.total
set data = bolt.arr[i]
set x = GetUnitX(data.d)
set y = GetUnitY(data.d)
set x2 = GetUnitX(data.t)
set y2 = GetUnitY(data.t)
set a = bj_RADTODEG * Atan2(y2 - y, x2 - x)
call SetUnitFacing(data.d, a)
if IsUnitInRange(data.d, data.t, 50) then
call DestroyEffect(data.art)
call KillUnit(data.d)
call DestroyEffect(AddSpecialEffectTarget(PRIMARY_EFFECT, data.t, "origin"))
call UnitDamageTarget(data.u, data.t, data.damage, false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call spark.SecondaryEffects(data.u, data.t, x2, y2)
call DestroyLightning(data.l)
set data.d = CreateUnit(Player(12), DUMMY_ID, x2, y2, 0)
call SetUnitScale(data.d, 3.5, 3.5, 3.5)
call SetUnitVertexColor(data.d, 170, 170, 255, 255)
call DestroyEffect(AddSpecialEffectTarget(PRIMARY_EFFECT, data.d, "origin"))
call KillUnit(data.d)
call data.destroy()
set bolt.total = bolt.total - 1
set bolt.arr[i] = bolt.arr[bolt.total]
else
set p = SquareRoot((x - x2) * (x - x2) + (y - y2) * (y - y2))
set d = 17 + (p * .012)
///------------------------------------
set dx = SafeX(x + d * Cos(a * bj_DEGTORAD))
set dy = SafeY(y + d * Sin(a * bj_DEGTORAD))
call SetUnitX(data.d, dx)
call SetUnitY(data.d, dy)
////-----------------------------------
set x = GetUnitX(data.d)
set y = GetUnitY(data.d)
set a = (a-180)
set dx = x + 200 * Cos(a * bj_DEGTORAD)
set dy = y + 200 * Sin(a * bj_DEGTORAD)
call MoveLocation(loc, dx, dy)
call MoveLocation(loc2, x, y)
call MoveLightningEx(data.l, true, dx, dy, (GetLocationZ(loc)+90), x, y, (GetLocationZ(loc2)+GetUnitFlyHeight(data.d)))
endif
set i = i + 1
endloop
if bolt.total == 0 then
call PauseTimer(bolt.tim)
endif
endmethod
endstruct
// Charged bolts //
private struct Charged
unit u
unit array mis[CHARGED_BOLTS_AMOUNT]
real array fh[CHARGED_BOLTS_AMOUNT]
real array fi[CHARGED_BOLTS_AMOUNT]
real array x[CHARGED_BOLTS_AMOUNT]
lightning array l[CHARGED_BOLTS_AMOUNT]
lightning array l2[CHARGED_BOLTS_AMOUNT]
boolean array fb[CHARGED_BOLTS_AMOUNT]
effect array fx[CHARGED_BOLTS_AMOUNT]
boolean dead = false //If the flag is turned on, the charged bolts dissapear until the hero is alive again
real tick = 0
real xtick = .94 //Defines the duration of the lightning rotation
real rat = SquareRoot(NORMAL_OFFSET) / bj_PI
real limit = NORMAL_OFFSET
boolean charged = false
static thistype array arr
static integer total = 0
static timer tim = CreateTimer()
////
private static string str1 = "Abilities\\Spells\\Orc\\LightningShield\\LightningShieldBuff.mdl"
////
static method create takes unit u returns thistype
local thistype this = thistype.allocate()
local integer i = 0
local trigger t = CreateTrigger()
local real x
local real y
local real cx = GetUnitX(u)
local real cy = GetUnitY(u)
set this.u = u
loop
exitwhen i > Cbolts
set this.mis[i] = CreateUnit(GetOwningPlayer(u), 'e001', GetUnitX(u), GetUnitY(u), 0)
set this.fx[i] = AddSpecialEffectTarget(BALL_ART , this.mis[i], "origin")
set x = cx + 60 * Cos(( (360 / (Cbolts+1)) * (i+1) ) * bj_DEGTORAD)
set y = cy + 60 * Sin(( (360 / (Cbolts+1)) * (i+1) ) * bj_DEGTORAD)
call SetUnitX(this.mis[i], x)
call SetUnitY(this.mis[i], y)
call UnitAddAbility(this.mis[i], 'Amrf')
call SetUnitTimeScale(this.mis[i], 0)
call UnitRemoveAbility(this.mis[i], 'Amrf')
set this.fh[i] = 30 * i
call SetUnitFlyHeight(this.mis[i], this.fh[i], 0)
call SetUnitScale(this.mis[i], CHARGED_BOLTS_SIZE, CHARGED_BOLTS_SIZE, CHARGED_BOLTS_SIZE)
set this.fb[i] = true
set this.x[i] = bj_RADTODEG * Atan2(y - cy, x - cx)
set i = i + 1
endloop
call TriggerAddCondition(t, Condition(function Charged.ready))
call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_SPELL_CAST)
if thistype.total == 0 then
call TimerStart(thistype.tim, .047, true, function Charged.fly)
endif
set thistype.total = thistype.total + 1
set thistype.arr[thistype.total - 1] = this
return this
endmethod
static method ready takes nothing returns boolean
local thistype this
local integer i = 0
local integer k = 0
local sound snd
if GetSpellAbilityId()!= ABILITY_ID then
return false
else
set this = thistype.GetInstance(GetTriggerUnit())
if this.charged then
return false
endif
set snd = CreateSound("Units\\Orc\\StasisTotem\\StasisTotem.wav", false, false, true, 12700, 12700, "")
call AttachSoundToUnit(snd, GetTriggerUnit())
set this.charged = true
set this.xtick = .8
set this.rat = this.rat + SquareRoot(MAX_OFFSET)
set this.limit = MAX_OFFSET
call StartSound(snd)
call KillSoundWhenDone(snd)
set snd = null
loop
exitwhen i>Cbolts
set k = i + 1
if k > Cbolts then
set k = 0
endif
set this.l[i] = AddLightning(CHARGED_LIGHTNING, true, GetUnitX(this.mis[i]), GetUnitY(this.mis[i]), GetUnitX(this.u), GetUnitY(this.u))
call SetLightningColor(this.l[i], 1, 1, 1, .6)
set this.l2[i] = AddLightning(ORBITAL_LIGHTNING, true, GetUnitX(this.mis[i]), GetUnitY(this.mis[i]), GetUnitX(this.mis[k]), GetUnitY(this.mis[k]))
call SetLightningColor(this.l2[i], .3, .1, 1, 1)
set i = i + 1
endloop
endif
return false
endmethod
static method GetInstance takes unit u returns integer
local thistype this
local integer i = 0
loop
exitwhen i >= thistype.total
set this = thistype.arr[i]
if IsUnit(u, this.u) then
return this
endif
set i = i + 1
endloop
return 0
endmethod
static method fly takes nothing returns nothing
local thistype this
local integer i = 0
local integer k = 0
local real x =0
local real y =0
local real cx
local real cy
local integer j = 0
loop
exitwhen i >= thistype.total
set this = thistype.arr[i]
set k = 0
set j = 0
set cx = GetUnitX(this.u)
set cy = GetUnitY(this.u)
loop
exitwhen k > Cbolts
set j = k + 1
if j > Cbolts then
set j = 0
endif
if (not(this.dead)) and this.mis[k] != null then
if this.fb[k] then
set this.fh[k] = this.fh[k] + 3
else
set this.fh[k] = this.fh[k] - 3
endif
if GetUnitFlyHeight(this.mis[k])<50 then
set this.fb[k] = true
elseif GetUnitFlyHeight(this.mis[k]) > 275 then
set this.fb[k] = false
endif
set this.tick = this.tick + .047
call SetUnitFlyHeight(this.mis[k], this.fh[k], 530)
set this.x[k] = this.x[k] + 4
if this.rat < this.limit then
set this.rat = this.rat + 2
elseif this.rat > this.limit then
set this.rat = this.rat - .5
endif
set x = cx + this.rat * Cos(this.x[k] * bj_DEGTORAD)
set y = cy + this.rat * Sin(this.x[k] * bj_DEGTORAD)
call SetUnitX(this.mis[k], x)
call SetUnitY(this.mis[k], y)
if this.charged then
if this.xtick > 0 then
set this.x[k] = this.x[k] + 6
call MoveLocation(loc, x, y)
call MoveLocation(loc2, GetUnitX(this.u), GetUnitY(this.u))
call MoveLightningEx(this.l[k], true, x, y, (GetLocationZ(loc)+GetUnitFlyHeight(this.mis[k])), cx, cy, (GetLocationZ(loc2)+GetUnitFlyHeight(this.u)+20))
call MoveLocation(loc2, GetUnitX(this.mis[j]), GetUnitY(this.mis[j]))
call MoveLightningEx(this.l2[k], true, x, y, (GetLocationZ(loc)+GetUnitFlyHeight(this.mis[k])), GetUnitX(this.mis[j]), GetUnitY(this.mis[j]), (GetLocationZ(loc2)+GetUnitFlyHeight(this.mis[j])))
else
call DestroyLightning(this.l[k])
call DestroyLightning(this.l2[k])
endif
endif
if this.tick > 1.75 then
set this.tick = 0
call DestroyEffect(AddSpecialEffectTarget(thistype.str1 , this.mis[k], "origin"))
endif
endif
set k = k + 1
endloop
if this.charged then
if this.xtick > 0 then
set this.xtick = this.xtick - .05
else
set this.charged = false
set this.limit = NORMAL_OFFSET
endif
endif
if GetWidgetLife(this.u)<.405 then
call this.hide()
set this.dead = true
elseif GetWidgetLife(this.u)>=.405 and this.dead then
set this.dead = false
call this.show()
endif
set i = i + 1
endloop
endmethod
method hide takes nothing returns nothing
local integer i = 0
loop
exitwhen i > Cbolts
if .mis[i] != null then
//call UnitRemoveAbility(.mis[i], 'Aloc')
call ShowUnit(.mis[i], false)
endif
set i = i + 1
endloop
endmethod
method show takes nothing returns nothing
local integer i = 0
loop
exitwhen i > Cbolts
if .mis[i] != null then
call ShowUnit(.mis[i], true)
call UnitAddAbility(.mis[i], 'Aloc')
endif
set i = i + 1
endloop
endmethod
endstruct
///////===================\\\\\\\
private function BoltStart takes nothing returns nothing
call bolt.create(GetTriggerUnit(), GetSpellTargetUnit())
endfunction
private function IsBolt takes nothing returns boolean
return GetSpellAbilityId() == ABILITY_ID
endfunction
private function BoltCharge takes nothing returns boolean
if GetLearnedSkill() == ABILITY_ID then
if GetUnitAbilityLevel(GetTriggerUnit(), ABILITY_ID)<2 then
call Charged.create(GetTriggerUnit())
endif
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger ( )
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function IsBolt))
call TriggerAddAction(t, function BoltStart)
set t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_SKILL)
call TriggerAddCondition(t, Condition(function BoltCharge))
set t = null
set BE = Condition(function spark.Enum)
set MINX = GetRectMinX(bj_mapInitialPlayableArea)
set MINY = GetRectMinY(bj_mapInitialPlayableArea)
set MAXX = GetRectMaxX(bj_mapInitialPlayableArea)
set MAXY = GetRectMaxY(bj_mapInitialPlayableArea)
endfunction
endlibrary