Name | Type | is_array | initial_value |
--[[
LineAimer by Tasyen
Requires Warcraft 3 V1.32+
Shows a precast hitzone for registered Line Direction dmg spells and tints units. (Shockwave, Carrion swarm, Breath of Fire/Frost, Impale, Smashing wave).
API
function LineAimerRegister(spellCode, orderString[, hitEnemy, hitAlly])
unmentioned hitEnemy, hitAlly results into -> true, false
Exmple, default Abilities
LineAimerRegister(FourCC("AOsh"), "shockwave")
LineAimerRegister('AOs2', "shockwave")
LineAimerRegister('ACsh', "shockwave")
LineAimerRegister('ACst', "shockwave")
LineAimerRegister('ANsh', "shockwave")
LineAimerRegister('ANbf', "breathoffire")
LineAimerRegister('ANcf', "breathoffire")
LineAimerRegister('ACbc', "breathoffire")
LineAimerRegister('ACbf', "breathoffire")
LineAimerRegister('AUcs', "carrionswarm")
LineAimerRegister('ACca', "carrionswarm")
LineAimerRegister('ACcv', "carrionswarm")
LineAimerRegister('ACc2', "carrionswarm")
LineAimerRegister('ACc3', "carrionswarm")
LineAimerRegister('AUim', "impale")
LineAimerRegister('ACmp', "impale")
--]]
LineAimer = {
Lightning ={
-- 0 to 1.0
Red = 1.0
,Blue = 1
,Green = 1
,Alpha = 1.0
-- splats/lightningdata.slk
-- does not update after creation
,FileCode = "LAIM"
}
,UnitTintingAlly ={
[true] = {
-- 0 to 255
Red = 0
,Blue = 0
,Green = 255
,Alpha = 255
}
,[false] = {
Red = 0
,Blue = 0
,Green = 255
,Alpha = 255
}
}
-- highest coli units can have.
,MaxColi = 200
-- data is only known to the local player, except for the unit reference
,Caster = {}
--,Img = {}
,X = 0
,Y = 0
,SkillCode = 0
,AoeStart = 0
,AoeEnd = 0
,Range = 0
,ToCreate = {}
,SkillFields = {
shockwave = {ABILITY_RLF_FINAL_AREA_OSH4, ABILITY_RLF_DISTANCE_OSH3}
,carrionswarm = {ABILITY_RLF_FINAL_AREA_UCS4, ABILITY_RLF_DISTANCE_UCS3}
,breathoffire = {ABILITY_RLF_FINAL_AREA_UCS4, ABILITY_RLF_DISTANCE_UCS3}
,impale = {ABILITY_RLF_AREA_OF_EFFECT, ABILITY_RLF_WAVE_DISTANCE}
}
}
function isInTargetingMode()
local index = 0
repeat
if BlzFrameIsVisible(BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON, index)) then break end
index = index + 1
until index == 12 --when 12 is reached no button is visible
return index == 11 --when the loop broke in index == 11 its targeting mode
end
do
local data = LineAimer
local function newAimTrigger(spellCode, orderString, hitEnemy, hitAlly)
-- default values for hitEnemy, hitAlly
if hitEnemy == nil and hitAlly == nil then
hitEnemy = true
hitAlly = false
end
-- error display
if data[spellCode] then
print("LineAimer - Register Twice", GetObjectName(spellCode), spellCode)
return
end
local trigger = CreateTrigger()
local player
local triggerUnit
TriggerRegisterCommandEvent(trigger, spellCode, orderString)
TriggerAddAction(trigger, function()
triggerUnit = GetTriggerUnit()
player = GetOwningPlayer(triggerUnit)
data.Caster[player] = triggerUnit
local skill = BlzGetUnitAbility(triggerUnit, spellCode)
-- instance api starts with index 0 for level 1
local level = GetUnitAbilityLevel(triggerUnit, spellCode) - 1
if player == GetLocalPlayer() then
data.AoeStart = BlzGetAbilityRealLevelField(skill, ABILITY_RLF_AREA_OF_EFFECT, level)
data.AoeEnd = BlzGetAbilityRealLevelField(skill, data.SkillFields[orderString][1], level)
data.HitEnemy = hitEnemy
data.HitAlly = hitAlly
-- for reasons imaple's AREA_OF_EFFECT has to be halved
if orderString == "impale" then
data.AoeStart = data.AoeStart/2
data.AoeEnd = data.AoeEnd/2
end
data.Range = BlzGetAbilityRealLevelField(skill, data.SkillFields[orderString][2], level)
data.SkillCode = spellCode
end
--[[ if data.Img[player] then
SetImageRenderAlways(data.Img[player], false)
DestroyImage(data.Img[player])
end
local endSize = data.AoeEnd*2
data.Img[player] = CreateImage("ReplaceableTextures\\Selection\\SpellAreaOfEffect.blp", endSize, endSize, 0, 0, 0, 0, endSize/2, endSize/2, 0, 2)
SetImageRenderAlways(data.Img[player], true)
--]]
skill = nil
end)
data[spellCode] = true
triggerUnit = nil
end
function LineAimerRegister(spellCode, orderString, hitEnemy, hitAlly)
-- support calls without FourCC
if type(spellCode) == "string" then spellCode = FourCC(spellCode) end
-- delay the creation when this is called to early
if data.Started then
newAimTrigger(spellCode, orderString, hitEnemy, hitAlly)
else
table.insert(data.ToCreate, {spellCode, orderString, hitEnemy, hitAlly})
end
end
-- hook into Blizzard's at Map Init
local oldInit = InitBlizzard
function InitBlizzard()
oldInit()
data.Started = true
data.MouseTrigger = CreateTrigger()
for playerIndex = 0, bj_MAX_PLAYER_SLOTS do
TriggerRegisterPlayerEvent(data.MouseTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_MOVE)
end
TriggerAddAction(data.MouseTrigger, function()
if GetTriggerPlayer() == GetLocalPlayer() then
data.X = BlzGetTriggerPlayerMouseX()
data.Y = BlzGetTriggerPlayerMouseY()
end
end)
-- create the to early created ones
for i, v in ipairs(data.ToCreate) do
newAimTrigger(v[1], v[2], v[3], v[4])
end
data.ToCreate = nil
-- preload this frames, make sure they got a handleId for everyone
for i = 0, 11 do BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON, i) end
data.LineA = AddLightning(data.Lightning.FileCode, false, 0, 0, 0, 0)
data.LineB = AddLightning(data.Lightning.FileCode, false, 0, 0, 0, 0)
data.LineC = AddLightning(data.Lightning.FileCode, false, 0, 0, 0, 0)
local localPlayer = GetLocalPlayer()
local unitX, unitY, rad, maxRange
local off = bj_PI/2
local tempGroup = CreateGroup()
local affectedUnits = CreateGroup()
local x, y
local filterUnit
local pickUnitAction = Filter(function()
filterUnit = GetFilterUnit()
local isAlly = IsUnitAlly(filterUnit, localPlayer)
-- disallow oneself, bigger radius is included because PickUnits in Range picks units based on there center. But IsUnitInRangeXY includes colision.
if filterUnit ~= data.Caster[localPlayer] and IsUnitInRangeXY(filterUnit, data.PosX, data.PosY, data.Radius) then
-- filter allies/enemies when wanted
if (data.HitEnemy and not isAlly) or (data.HitAlly and isAlly) then
GroupAddUnit(affectedUnits, filterUnit)
SetUnitVertexColor(filterUnit, data.UnitTintingAlly[isAlly].Red, data.UnitTintingAlly[isAlly].Green, data.UnitTintingAlly[isAlly].Blue, data.UnitTintingAlly[isAlly].Alpha)
end
end
filterUnit = nil
return false
end)
TimerStart(CreateTimer(), 0.05, true, function()
xpcall(function()
-- revert tinting for units picked in the last iteration and remove reference to them
local unit
for i = 0, BlzGroupGetSize(affectedUnits) do
unit = BlzGroupUnitAt(affectedUnits, i)
SetUnitVertexColor(unit, BlzGetUnitIntegerField(unit, UNIT_IF_TINTING_COLOR_RED), BlzGetUnitIntegerField(unit, UNIT_IF_TINTING_COLOR_GREEN), BlzGetUnitIntegerField(unit, UNIT_IF_TINTING_COLOR_BLUE), BlzGetUnitIntegerField(unit, UNIT_IF_TINTING_COLOR_ALPHA))
end
GroupClear(affectedUnits)
if data.SkillCode > 0 and BlzIsLocalClientActive() then
if isInTargetingMode() then
unitX = GetUnitX(data.Caster[localPlayer])
unitY = GetUnitY(data.Caster[localPlayer])
-- when there is an unit under the mouse, use it for the direction
if BlzGetMouseFocusUnit() then
-- is the hovered unit not the caster?
if BlzGetMouseFocusUnit() ~= data.Caster[localPlayer] then
rad = Atan2(GetUnitY(BlzGetMouseFocusUnit()) - unitY, GetUnitX(BlzGetMouseFocusUnit()) - unitX)
else
-- caster himself, use current facing
rad = bj_DEGTORAD*GetUnitFacing(data.Caster[localPlayer])
end
else
rad = Atan2(data.Y - unitY, data.X - unitX)
end
-- the shockwave starts from data.AoeStart offset traveling data.Range then having data.AoeEnd in the final moment
maxRange = (data.Range + data.AoeEnd + data.AoeStart)
maxRangeCos = Cos(rad)*maxRange
maxRangeSin = Sin(rad)*maxRange
SetLightningColor(data.LineA, data.Lightning.Red, data.Lightning.Green, data.Lightning.Blue, data.Lightning.Alpha)
SetLightningColor(data.LineB, data.Lightning.Red, data.Lightning.Green, data.Lightning.Blue, data.Lightning.Alpha)
SetLightningColor(data.LineC, data.Lightning.Red, data.Lightning.Green, data.Lightning.Blue, data.Lightning.Alpha)
--if not true then
--MoveLightning(data.LineA, false, unitX + data.AoeStart*Cos(rad + off), unitY + data.AoeStart*Sin(rad + off), unitX + Cos(rad)*(data.Range + data.AoeStart) + data.AoeEnd*Cos(rad+ off), unitY + Sin(rad)*(data.Range + data.AoeStart) + data.AoeEnd*Sin(rad+ off))
--MoveLightning(data.LineB, false, unitX + data.AoeStart*Cos(rad - off), unitY + data.AoeStart*Sin(rad - off), unitX + Cos(rad)*(data.Range + data.AoeStart) + data.AoeEnd*Cos(rad- off), unitY + Sin(rad)*(data.Range + data.AoeStart) + data.AoeEnd*Sin(rad - off))
--MoveLightning(data.LineC, false, unitX + Cos(rad)*(data.Range + data.AoeStart) + data.AoeEnd*Cos(rad+ off), unitY + Sin(rad)*(data.Range + data.AoeStart) + data.AoeEnd*Sin(rad+ off), unitX + Cos(rad)*(data.Range + data.AoeStart) + data.AoeEnd*Cos(rad- off), unitY + Sin(rad)*(data.Range + data.AoeStart) + data.AoeEnd*Sin(rad - off) )
MoveLightning(data.LineA, false, unitX + data.AoeStart*Cos(rad + off), unitY + data.AoeStart*Sin(rad + off), unitX + maxRangeCos + data.AoeEnd*Cos(rad+ off), unitY + maxRangeSin + data.AoeEnd*Sin(rad+ off))
MoveLightning(data.LineB, false, unitX + data.AoeStart*Cos(rad - off), unitY + data.AoeStart*Sin(rad - off), unitX + maxRangeCos + data.AoeEnd*Cos(rad- off), unitY + maxRangeSin + data.AoeEnd*Sin(rad - off))
MoveLightning(data.LineC, false, unitX + maxRangeCos + data.AoeEnd*Cos(rad+ off), unitY + maxRangeSin + data.AoeEnd*Sin(rad+ off), unitX +maxRangeCos + data.AoeEnd*Cos(rad- off), unitY + maxRangeSin + data.AoeEnd*Sin(rad - off) )
--else
--MoveLightning(data.LineA, false, unitX + maxRangeCos + data.AoeEnd*Cos(rad+ off), unitY + maxRangeSin + data.AoeEnd*Sin(rad+ off), unitX + data.AoeStart*Cos(rad + off), unitY + data.AoeStart*Sin(rad + off))
--MoveLightning(data.LineB, false, unitX + maxRangeCos + data.AoeEnd*Cos(rad- off), unitY + maxRangeSin + data.AoeEnd*Sin(rad - off), unitX + data.AoeStart*Cos(rad - off), unitY + data.AoeStart*Sin(rad - off))
--MoveLightning(data.LineC, false, unitX + maxRangeCos + data.AoeEnd*Cos(rad+ off), unitY + maxRangeSin + data.AoeEnd*Sin(rad+ off), unitX +maxRangeCos + data.AoeEnd*Cos(rad- off), unitY + maxRangeSin + data.AoeEnd*Sin(rad - off) )
--end
--SetImagePosition(data.Img[localPlayer], unitX + (data.AoeStart + data.Range)*Cos(rad), unitY + (data.AoeStart + data.Range)* Sin(rad), 0)
local radiusChange
-- 0.1 is the internal dmg intervale of shockwave
local step = 0.1*data.Range
local radius = data.AoeStart
if data.AoeStart ~= data.AoeEnd then
radiusChange = (data.AoeEnd - data.AoeStart)
radiusChange = radiusChange/ ((data.Range)/step)
else
radiusChange = 0
end
for i = 0, data.Range, step do
--print(radius)
-- + data.MaxColi because GroupEnumUnitsInRange checks for unit centers
data.PosX = unitX + (data.AoeStart + i)*Cos(rad)
data.PosY = unitY + (data.AoeStart + i)*Sin(rad)
data.Radius = radius
GroupEnumUnitsInRange(tempGroup, data.PosX, data.PosY, radius + data.MaxColi, pickUnitAction)
radius = radius + radiusChange
end
else
-- targeting Mode ended stop now
data.SkillCode = 0
-- SetImageRenderAlways(data.Img[localPlayer], false)
end
else
-- hide by 0 alpha
SetLightningColor(data.LineA, 1, 1, 1, 0)
SetLightningColor(data.LineB, 1, 1, 1, 0)
SetLightningColor(data.LineC, 1, 1, 1, 0)
end
end,print)
end)
end
end
LineAimerRegister(FourCC("AOsh"), "shockwave")
LineAimerRegister('AOs2', "shockwave")
LineAimerRegister('ACsh', "shockwave")
LineAimerRegister('ACst', "shockwave")
LineAimerRegister('ANsh', "shockwave")
LineAimerRegister('ANbf', "breathoffire")
LineAimerRegister('ANcf', "breathoffire")
LineAimerRegister('ACbc', "breathoffire")
LineAimerRegister('ACbf', "breathoffire")
LineAimerRegister('AUcs', "carrionswarm")
LineAimerRegister('ACca', "carrionswarm")
LineAimerRegister('ACcv', "carrionswarm")
LineAimerRegister('ACc2', "carrionswarm")
LineAimerRegister('ACc3', "carrionswarm")
LineAimerRegister('AUim', "impale")
LineAimerRegister('ACmp', "impale")
library LineAim initializer init_function
// LineAimer by Tasyen
// Requires Warcraft 3 V1.32+
// Shows a precast hitzone for registered Line Direction dmg spells and tints units. (Shockwave, Carrion swarm, Breath of Fire/Frost, Impale, Smashing wave).
// function LineAimerRegister(spellCode, orderString[, hitEnemy, hitAlly])
// function LineAimerRegisterEx takes integer spellCode, string orderString returns nothing
// wrapper for hitEnemy true, hitAlly false
// Exmple, default Abilities
// scope DefaultLineAimerDemo initializer init_function
// private function init_function takes nothing returns nothing
// call LineAimerRegisterEx('AOsh', "shockwave")
// call LineAimerRegisterEx('AOs2', "shockwave")
// call LineAimerRegisterEx('ACsh', "shockwave")
// call LineAimerRegisterEx('ACst', "shockwave")
// call LineAimerRegisterEx('ANsh', "shockwave")
// call LineAimerRegisterEx('ANbf', "breathoffire")
// call LineAimerRegisterEx('ANcf', "breathoffire")
// call LineAimerRegisterEx('ACbc', "breathoffire")
// call LineAimerRegisterEx('ACbf', "breathoffire")
// call LineAimerRegisterEx('AUcs', "carrionswarm")
// call LineAimerRegisterEx('ACca', "carrionswarm")
// call LineAimerRegisterEx('ACcv', "carrionswarm")
// call LineAimerRegisterEx('ACc2', "carrionswarm")
// call LineAimerRegisterEx('ACc3', "carrionswarm")
// call LineAimerRegisterEx('AUim', "impale")
// call LineAimerRegisterEx('ACmp', "impale")
// endfunction
//endscope
globals
public real LightningRed = 1.0
public real LightningGreen = 1.0
public real LightningBlue = 1.0
public real LightningAlpha = 1.0
// splats/lightningdata.slk
// does not update after creation
public string LightningFileCode = "LAIM"
public integer UnitTintingRed = 0
public integer UnitTintingGreen = 255
public integer UnitTintingBlue = 0
public integer UnitTintingAlpha = 255
// highest coli units can have
public integer MaxColi = 200
// System Data
public boolean HitEnemy
public boolean HitAlly
public lightning LineA
public lightning LineB
public lightning LineC
public filterfunc PickUnitAction
public group AffectedUnits
public group TempGroup
public integer localPlayerIndex
public player localPlayer
public unit array Caster
public real X = 0
public real Y = 0
public integer SkillCode
public real AoeStart = 0
public real AoeEnd = 0
public real Range = 0
public trigger MouseTrigger
public real PosX = 0
public real PosY = 0
public real Radius = 0
public hashtable Hash = InitHashtable()
endglobals
function isInTargetingMode takes nothing returns boolean
local integer index = 0
loop
if BlzFrameIsVisible(BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON, index)) then
exitwhen true
endif
set index = index + 1
exitwhen index == 12 // when 12 is reached no button is visible
endloop
return index == 11 //when the loop broke in index == 11 its targeting mode
endfunction
private function ButtonActionFunc takes nothing returns nothing
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(u)
local integer playerIndex = GetPlayerId(p)
local integer tId = GetHandleId(GetTriggeringTrigger())
local integer spellCode = LoadInteger(Hash, tId, 0)
local ability skill = BlzGetUnitAbility(u, spellCode)
// instance api starts with index 0 for level 1
local integer level = GetUnitAbilityLevel(u, spellCode) - 1
local string orderString = LoadStr(Hash, tId, 0)
set Caster[playerIndex] = u
if p == GetLocalPlayer() then
set AoeStart = BlzGetAbilityRealLevelField(skill, ABILITY_RLF_AREA_OF_EFFECT, level)
if orderString == "impale" then
set AoeEnd = BlzGetAbilityRealLevelField(skill, ABILITY_RLF_AREA_OF_EFFECT, level)
elseif orderString == "carrionswarm" then
set AoeEnd = BlzGetAbilityRealLevelField(skill, ABILITY_RLF_FINAL_AREA_UCS4, level)
elseif orderString == "breathoffire" then
set AoeEnd = BlzGetAbilityRealLevelField(skill, ABILITY_RLF_FINAL_AREA_UCS4, level)
else
set AoeEnd = BlzGetAbilityRealLevelField(skill, ABILITY_RLF_FINAL_AREA_OSH4, level)
endif
set HitEnemy = LoadBoolean(Hash, tId, 0)
set HitAlly = LoadBoolean(Hash, tId, 1)
// for reasons imaple's AREA_OF_EFFECT has to be halved
if orderString == "impale" then
set AoeStart = AoeStart/2
set AoeEnd = AoeEnd/2
endif
if orderString == "impale" then
set Range = BlzGetAbilityRealLevelField(skill, ABILITY_RLF_WAVE_DISTANCE, level)
elseif orderString == "carrionswarm" then
set Range = BlzGetAbilityRealLevelField(skill, ABILITY_RLF_DISTANCE_UCS3, level)
elseif orderString == "breathoffire" then
set Range = BlzGetAbilityRealLevelField(skill, ABILITY_RLF_DISTANCE_UCS3, level)
else
set Range = BlzGetAbilityRealLevelField(skill, ABILITY_RLF_DISTANCE_OSH3, level)
endif
set SkillCode = spellCode
endif
set u = null
set p = null
set skill = null
endfunction
function LineAimerRegister takes integer spellCode, string orderString, boolean hitEnemy, boolean hitAlly returns nothing
local trigger t = CreateTrigger()
local integer tId = GetHandleId(t)
call TriggerRegisterCommandEvent(t, spellCode, orderString)
call TriggerAddAction(t, function ButtonActionFunc)
call SaveInteger(Hash, tId, 0, spellCode)
call SaveStr(Hash, tId, 0, orderString)
call SaveBoolean(Hash, tId, 0, hitEnemy)
call SaveBoolean(Hash, tId, 1, hitAlly)
endfunction
function LineAimerRegisterEx takes integer spellCode, string orderString returns nothing
call LineAimerRegister(spellCode, orderString, true, false)
endfunction
private function MouseActionFunc takes nothing returns nothing
if GetTriggerPlayer() == GetLocalPlayer() then
set X = BlzGetTriggerPlayerMouseX()
set Y = BlzGetTriggerPlayerMouseY()
endif
endfunction
private function UnitActionFunc takes nothing returns boolean
local unit u = GetFilterUnit()
local boolean isAlly = IsUnitAlly(u, localPlayer)
// disallow oneself, bigger radius is included because PickUnits in Range picks units based on there center. But IsUnitInRangeXY includes colision.
if u != Caster[localPlayerIndex] and IsUnitInRangeXY(u, PosX, PosY, Radius) then
// filter allies/enemies when wanted
if (HitEnemy and not isAlly) or (HitAlly and isAlly) then
call GroupAddUnit(AffectedUnits, u)
call SetUnitVertexColor(u, UnitTintingRed, UnitTintingGreen, UnitTintingBlue, UnitTintingAlpha)
endif
endif
set u = null
return false
endfunction
private function TimerFunc takes nothing returns nothing
local real unitX
local real unitY
local real rad
local real maxRange
local real maxRangeCos
local real maxRangeSin
local real off = bj_PI/2
local real x
local real y
local unit u
local real i = 0
local real radiusChange
local real step
loop
set u = FirstOfGroup(AffectedUnits)
exitwhen u == null
call SetUnitVertexColor(u, BlzGetUnitIntegerField(u, UNIT_IF_TINTING_COLOR_RED), BlzGetUnitIntegerField(u, UNIT_IF_TINTING_COLOR_GREEN), BlzGetUnitIntegerField(u, UNIT_IF_TINTING_COLOR_BLUE), BlzGetUnitIntegerField(u, UNIT_IF_TINTING_COLOR_ALPHA))
call GroupRemoveUnit(AffectedUnits, u)
endloop
if SkillCode > 0 and BlzIsLocalClientActive() then
if isInTargetingMode() then
set unitX = GetUnitX(Caster[localPlayerIndex])
set unitY = GetUnitY(Caster[localPlayerIndex])
// when there is an unit under the mouse, use it for the direction
if BlzGetMouseFocusUnit() != null then
// is the hovered unit not the caster?
if BlzGetMouseFocusUnit() != Caster[localPlayerIndex] then
set rad = Atan2(GetUnitY(BlzGetMouseFocusUnit()) - unitY, GetUnitX(BlzGetMouseFocusUnit()) - unitX)
else
// caster himself, use current facing
set rad = bj_DEGTORAD*GetUnitFacing(Caster[localPlayerIndex])
endif
else
set rad = Atan2(Y - unitY, X - unitX)
endif
// the shockwave starts from AoeStart offset traveling Range then having AoeEnd in the final moment
set maxRange = (Range + AoeEnd + AoeStart)
set maxRangeCos = Cos(rad)*maxRange
set maxRangeSin = Sin(rad)*maxRange
call SetLightningColor(LineA, LightningRed, LightningGreen, LightningBlue, LightningAlpha)
call SetLightningColor(LineB, LightningRed, LightningGreen, LightningBlue, LightningAlpha)
call SetLightningColor(LineC, LightningRed, LightningGreen, LightningBlue, LightningAlpha)
call MoveLightning(LineA, false, unitX + AoeStart*Cos(rad + off), unitY + AoeStart*Sin(rad + off), unitX + maxRangeCos + AoeEnd*Cos(rad+ off), unitY + maxRangeSin + AoeEnd*Sin(rad+ off))
call MoveLightning(LineB, false, unitX + AoeStart*Cos(rad - off), unitY + AoeStart*Sin(rad - off), unitX + maxRangeCos + AoeEnd*Cos(rad- off), unitY + maxRangeSin + AoeEnd*Sin(rad - off))
call MoveLightning(LineC, false, unitX + maxRangeCos + AoeEnd*Cos(rad+ off), unitY + maxRangeSin + AoeEnd*Sin(rad+ off), unitX +maxRangeCos + AoeEnd*Cos(rad- off), unitY + maxRangeSin + AoeEnd*Sin(rad - off) )
// 0.1 is the internal dmg intervale of shockwave
set step = 0.1*Range
set Radius = AoeStart
if AoeStart != AoeEnd then
set radiusChange = (AoeEnd - AoeStart)
set radiusChange = radiusChange/ ((Range)/step)
else
set radiusChange = 0
endif
loop
exitwhen i > Range
//print(radius)
// + MaxColi because GroupEnumUnitsInRange checks for unit centers
set PosX = unitX + (AoeStart + i)*Cos(rad)
set PosY = unitY + (AoeStart + i)*Sin(rad)
set Radius = Radius
call GroupEnumUnitsInRange(TempGroup, PosX, PosY, Radius + MaxColi, PickUnitAction)
set Radius = Radius + radiusChange
set i = i + step
endloop
else
// targeting Mode ended stop now
set SkillCode = 0
endif
else
// hide by 0 alpha
call SetLightningColor(LineA, 1, 1, 1, 0)
call SetLightningColor(LineB, 1, 1, 1, 0)
call SetLightningColor(LineC, 1, 1, 1, 0)
endif
endfunction
private function init_function takes nothing returns nothing
local integer loopA
set MouseTrigger = CreateTrigger()
call TriggerAddAction(MouseTrigger, function MouseActionFunc)
set loopA = 0
loop
call TriggerRegisterPlayerEvent(MouseTrigger, Player(loopA), EVENT_PLAYER_MOUSE_MOVE)
set loopA = loopA + 1
exitwhen loopA == bj_MAX_PLAYER_SLOTS
endloop
// preload this frames, make sure they got a handleId for everyone
set loopA = 0
loop
call BlzGetOriginFrame(ORIGIN_FRAME_COMMAND_BUTTON, loopA)
set loopA = loopA + 1
exitwhen loopA == 12
endloop
set LineA = AddLightning(LightningFileCode, false, 0, 0, 0, 0)
set LineB = AddLightning(LightningFileCode, false, 0, 0, 0, 0)
set LineC = AddLightning(LightningFileCode, false, 0, 0, 0, 0)
set PickUnitAction = Filter(function UnitActionFunc)
set AffectedUnits = CreateGroup()
set TempGroup = CreateGroup()
set localPlayer = GetLocalPlayer()
set localPlayerIndex = GetPlayerId(localPlayer)
call TimerStart(CreateTimer(), 0.05, true, function TimerFunc)
endfunction
endlibrary
scope DefaultLineAimerDemo initializer init_function
private function init_function takes nothing returns nothing
call LineAimerRegisterEx('AOsh', "shockwave")
call LineAimerRegisterEx('AOs2', "shockwave")
call LineAimerRegisterEx('ACsh', "shockwave")
call LineAimerRegisterEx('ACst', "shockwave")
call LineAimerRegisterEx('ANsh', "shockwave")
call LineAimerRegisterEx('ANbf', "breathoffire")
call LineAimerRegisterEx('ANcf', "breathoffire")
call LineAimerRegisterEx('ACbc', "breathoffire")
call LineAimerRegisterEx('ACbf', "breathoffire")
call LineAimerRegisterEx('AUcs', "carrionswarm")
call LineAimerRegisterEx('ACca', "carrionswarm")
call LineAimerRegisterEx('ACcv', "carrionswarm")
call LineAimerRegisterEx('ACc2', "carrionswarm")
call LineAimerRegisterEx('ACc3', "carrionswarm")
call LineAimerRegisterEx('AUim', "impale")
call LineAimerRegisterEx('ACmp', "impale")
endfunction
endscope