Name | Type | is_array | initial_value |
//TESH.scrollpos=0
//TESH.alwaysfold=0
scope UnitDies initializer Init
function Actions takes nothing returns nothing
local location TEMPPOINT = PolarProjectionBJ(GetUnitLoc(GetTriggerUnit()), GetRandomReal(100, 300), GetRandomReal(0, 360))
if (GetUnitTypeId(GetTriggerUnit()) != 'Hpal') then
call CreateUnitAtLoc(GetOwningPlayer(GetTriggerUnit()), GetUnitTypeId(GetTriggerUnit()), TEMPPOINT, 0)
else
call ReviveHeroLoc(GetTriggerUnit(), TEMPPOINT, true)
endif
call RemoveLocation(TEMPPOINT)
endfunction
//===========================================================================
function Init takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_DEATH )
call TriggerAddAction( t, function Actions )
set t = null
endfunction
endscope
//TESH.scrollpos=209
//TESH.alwaysfold=0
library HolyCross initializer Init requires GCU
//Configurables
globals
//Following Ability-IDs have to be set:
private constant integer SpellID = 'A000' //Triggering spell, should be targeting nothing
//Following Dummie-IDs have to be set:
private constant integer DummyCrossID = 'h002' // The Cross Dummy
private constant integer DummyCasterID = 'h001' // The Sheep Dummy
//This is the effect that is created on the hero, when casted:
private constant string EffectModel = "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl"
private constant string LightningHeal1 = "HWPB" // Healing Wave Effect
private constant string LightningHeal2 = "HWSB" // Healing Wave Effect Variation 2
private constant string LightningDamage1 = "CLPB" // Chain Lightning Effect
private constant string LightningDamage2 = "CLSB" // Chain Lightning Effect Variation 2
private constant string DamagingSoundPath = "Abilities\\Spells\\Orc\\LightningBolt\\LightningBolt.wav" // The Damaging Sound sound-path
private constant string HealingSoundPath = "Abilities\\Spells\\Orc\\HealingWave\\HealingWave.wav" // The Healing Sound sound-path
private constant real BaseHeight = 900 // This is the initial height from where the cross floats down and floats up after the spell is done
private constant real HeightToGo = 175 // This is the heigh in which the cross will be floating while the spell is active
private constant real Length = 20 // This is the spell length; DownRisingTime and UpRisingTime will be included
private constant real DownRisingTime = 1.5 // This is the time that the cross will take to float down
private constant real UpRisingTime = 1.5 // This is the time that the cross will take to float up, when it's finished
private constant real DummyCasterDistanceToCross = 200 // This is the distance in which the sheep will fly around the cross
private constant real CrossRotatingSpeed = 2 // This is the speed of the cross rotating around the hero
private constant real DummyCasterRotatingSpeed = 1.25 // This is the speed of the sheep rotating around the cross
private constant real DummyCasterNukeCooldown = 2.25 // This is the cooldown of the damaging-/healing- lightnings
private constant real DummyCasterNukeRange = 300 // This is the range of the sheep to be to trigger the damaging-/healing- lightnings
private constant real DummyCasterAttackLength = 2. // This is the length of the lightning-attack/healing, the damage will be splited on it
private constant boolean HealsCasterToo = false // true = heals spell casting unit
private constant attacktype AttackType = ATTACK_TYPE_MAGIC // This is the attack type of the lightning-attack
private constant damagetype DamageType = DAMAGE_TYPE_MAGIC // This is the damage type of the lightning-attack
endglobals
private function GetSheepNumb takes integer level returns integer
return level // Returns the number of sheep in the given level. In this case it's the amount of levels
endfunction
private function GetHealing takes integer level returns real
return 100. + (I2R(level)*50) // The formula of healing that is granted to a unit when healed by a sheep
endfunction
private function GetDamage takes integer level returns real
return 100. + (I2R(level)*50) // The formula of damage that is granted to a unit when healed by a sheep
endfunction
// This is the unit filter. Don't change this is if you don't want any special units to be not attacked/healed by the sheep
private function IsUnitViableTarget takes nothing returns boolean
if not HealsCasterToo and GetFilterUnit() == bj_lastCreatedUnit then
return false
endif
return true
endfunction
//Endconfigurables
globals
private integer Index = 0
private boolean array IsActive
private unit array Caster
private unit array Cross
private real array TimeLeft
private real array FloatingDirection
private boolean array FloatedUp
private unit array DummyCasters
private integer array DummyCastersSpellNumb
private real array DummyCasterFloatingDirection
private integer DummyCastersIndex = 0
private real array DummyCasterLeftCooldown
private lightning array DummyCasterLightningAttack
private real array DummyCasterLightningRemainingDur
private boolean array DummyCasterDoesLightningAttack
private unit array DummyCasterTargetedUnit
private boolean array DummyCasterIsHealing
private boolean array DummyCasterLightningIsDestroyed
endglobals
private function Actions takes nothing returns boolean
local real TempLocX
local real TempLocY
local real TempLoc2X
local real TempLoc2Y
local effect TempEffect
local integer i = 1
local real CasterDummyFacing
if (GetSpellAbilityId() == SpellID) then
set Index = Index + 1
set IsActive[Index] = true
set TimeLeft[Index] = Length
set FloatingDirection[Index] = GetRandomInt(0, 360)
set FloatedUp[Index] = false
set Caster[Index] = GetTriggerUnit()
set TempEffect = AddSpecialEffectTarget(EffectModel, Caster[Index], "origin")
set TempLocX = GetUnitX(Caster[Index])
set TempLocY = GetUnitY(Caster[Index])
set Cross[Index] = CreateUnit(GetOwningPlayer(Caster[Index]), DummyCrossID, TempLocX, TempLocY, GetUnitFacing(Caster[Index]))
call SetUnitFlyHeight(Cross[Index], BaseHeight, 0)
call SetUnitFlyHeight(Cross[Index], HeightToGo, (BaseHeight - HeightToGo) / DownRisingTime)
call DestroyEffect(TempEffect)
loop
set DummyCastersIndex = DummyCastersIndex + 1
set DummyCasterLightningIsDestroyed[DummyCastersIndex] = false
set DummyCasterLightningRemainingDur[DummyCastersIndex] = 0
set DummyCasterDoesLightningAttack[DummyCastersIndex] = false
set DummyCasterIsHealing[DummyCastersIndex] = false
set DummyCasterLeftCooldown[DummyCastersIndex] = DummyCasterNukeCooldown
set DummyCastersSpellNumb[DummyCastersIndex] = Index
set DummyCasterFloatingDirection[DummyCastersIndex] = (360 / GetSheepNumb(GetUnitAbilityLevel(Caster[Index], SpellID))) * i
set TempLoc2X = PolarProjectionX(TempLocX, DummyCasterDistanceToCross, DummyCasterFloatingDirection[DummyCastersIndex])
set TempLoc2Y = PolarProjectionY(TempLocY, DummyCasterDistanceToCross, DummyCasterFloatingDirection[DummyCastersIndex])
set CasterDummyFacing = AngleBetweenPointsXY(TempLoc2X, TempLoc2Y, TempLocX, TempLocY)
set DummyCasters[DummyCastersIndex] = CreateUnit(GetOwningPlayer(Caster[Index]), DummyCasterID, TempLoc2X, TempLoc2Y, CasterDummyFacing)
call SetUnitFlyHeight(DummyCasters[DummyCastersIndex], BaseHeight, 0)
call SetUnitFlyHeight(DummyCasters[DummyCastersIndex], HeightToGo, (BaseHeight - HeightToGo) / DownRisingTime)
set i = i + 1
exitwhen i > GetSheepNumb(GetUnitAbilityLevel(Caster[Index], SpellID))
endloop
endif
return false
endfunction
private function Loop takes nothing returns boolean
local integer i = 1
local integer j = 1
local location TempLoc
local location TempLoc2
local real TempLocX
local real TempLocY
local real TempLoc2X
local real TempLoc2Y
local unit UnitTarget
if (Index > 0) then
loop
if (IsActive[i]) then
set TimeLeft[i] = TimeLeft[i] - 0.03
// Set the position of cross
if (FloatingDirection[i] < 360) then
set FloatingDirection[i] = FloatingDirection[i] + CrossRotatingSpeed
else
set FloatingDirection[i] = FloatingDirection[i] - 360
endif
set TempLocX = PolarProjectionX(GetUnitX(Caster[i]), 200, FloatingDirection[i])
set TempLocY = PolarProjectionY(GetUnitY(Caster[i]), 200, FloatingDirection[i])
call SetUnitX(Cross[i], TempLocX)
call SetUnitY(Cross[i], TempLocY)
set j = 1
loop
if (DummyCastersSpellNumb[j] == i) then
if (DummyCasterFloatingDirection[j] > 0) then
set DummyCasterFloatingDirection[j] = DummyCasterFloatingDirection[j] - DummyCasterRotatingSpeed
else
set DummyCasterFloatingDirection[j] = DummyCasterFloatingDirection[j] + 360
endif
set TempLoc2X = PolarProjectionX(TempLocX, DummyCasterDistanceToCross, DummyCasterFloatingDirection[j])
set TempLoc2Y = PolarProjectionY(TempLocY, DummyCasterDistanceToCross, DummyCasterFloatingDirection[j])
call SetUnitX(DummyCasters[j], TempLoc2X)
call SetUnitY(DummyCasters[j], TempLoc2Y)
call SetUnitFacing(DummyCasters[j], AngleBetweenPointsXY(TempLoc2X, TempLoc2Y, TempLocX, TempLocY))
endif
set j = j + 1
exitwhen j > DummyCastersIndex
endloop
if (TimeLeft[i] < (Length - DownRisingTime)) and (TimeLeft[i] > UpRisingTime) then // if cross is rised down
set j = 1
loop
if (DummyCastersSpellNumb[j] == i) then
set DummyCasterLeftCooldown[j] = DummyCasterLeftCooldown[j] - 0.03
if (DummyCasterLeftCooldown[j] <= 0) then
set bj_lastCreatedUnit = Caster[i]
set UnitTarget = GetClosestUnitInRange(GetUnitX(DummyCasters[j]), GetUnitY(DummyCasters[j]), DummyCasterNukeRange, Filter(function IsUnitViableTarget))
if (UnitTarget != null) then
set DummyCasterLeftCooldown[j] = DummyCasterNukeCooldown
if (IsUnitEnemy(UnitTarget, GetOwningPlayer(Caster[i]))) then
if (GetRandomInt(0, 1) == 1) then
set DummyCasterLightningAttack[j] = AddLightningEx(LightningDamage1, true, GetUnitX(DummyCasters[j]), GetUnitY(DummyCasters[j]), GetUnitFlyHeight(DummyCasters[j]), GetUnitX(UnitTarget), GetUnitY(UnitTarget), GetUnitFlyHeight(UnitTarget))
else
set DummyCasterLightningAttack[j] = AddLightningEx(LightningDamage2, true, GetUnitX(DummyCasters[j]), GetUnitY(DummyCasters[j]), GetUnitFlyHeight(DummyCasters[j]), GetUnitX(UnitTarget), GetUnitY(UnitTarget), GetUnitFlyHeight(UnitTarget))
endif
set DummyCasterLightningIsDestroyed[j] = false
set DummyCasterLightningRemainingDur[j] = DummyCasterAttackLength
set DummyCasterDoesLightningAttack[j] = true
set DummyCasterTargetedUnit[j] = UnitTarget
set DummyCasterIsHealing[j] = false
call PlaySoundAtPoint(DamagingSoundPath, GetUnitX(UnitTarget), GetUnitY(UnitTarget))
else
if not IsUnitOwnedByPlayer(UnitTarget, Player(15)) then
if (GetRandomInt(0, 1) == 1) then
set DummyCasterLightningAttack[j] = AddLightningEx(LightningHeal1, true, GetUnitX(DummyCasters[j]), GetUnitY(DummyCasters[j]), GetUnitFlyHeight(DummyCasters[j]), GetUnitX(UnitTarget), GetUnitY(UnitTarget), GetUnitFlyHeight(UnitTarget))
else
set DummyCasterLightningAttack[j] = AddLightningEx(LightningHeal2, true, GetUnitX(DummyCasters[j]), GetUnitY(DummyCasters[j]), GetUnitFlyHeight(DummyCasters[j]), GetUnitX(UnitTarget), GetUnitY(UnitTarget), GetUnitFlyHeight(UnitTarget))
endif
set DummyCasterLightningIsDestroyed[j] = false
set DummyCasterLightningRemainingDur[j] = DummyCasterAttackLength
set DummyCasterDoesLightningAttack[j] = true
set DummyCasterTargetedUnit[j] = UnitTarget
set DummyCasterIsHealing[j] = true
call PlaySoundAtPoint(HealingSoundPath, GetUnitX(UnitTarget), GetUnitY(UnitTarget))
endif
endif
set UnitTarget = null
endif
endif
if (DummyCasterDoesLightningAttack[j]) then
if (IsUnitAlive(DummyCasterTargetedUnit[j])) then
set DummyCasterLightningRemainingDur[j] = DummyCasterLightningRemainingDur[j] - 0.03
if (DummyCasterLightningRemainingDur[j] <= 0) then
set DummyCasterDoesLightningAttack[j] = false
if not DummyCasterLightningIsDestroyed[j] then
set DummyCasterLightningIsDestroyed[j] = true
call DestroyLightning(DummyCasterLightningAttack[j])
endif
set DummyCasterTargetedUnit[j] = null
else
if not DummyCasterLightningIsDestroyed[j] then
set TempLoc = GetUnitLoc(DummyCasters[j])
set TempLoc2 = GetUnitLoc(DummyCasterTargetedUnit[j])
call MoveLightningEx(DummyCasterLightningAttack[j], false, GetUnitX(DummyCasters[j]), GetUnitY(DummyCasters[j]), GetUnitFlyHeight(DummyCasters[j]) + GetLocationZ(TempLoc), GetUnitX(DummyCasterTargetedUnit[j]), GetUnitY(DummyCasterTargetedUnit[j]), GetUnitFlyHeight(DummyCasterTargetedUnit[j]) + GetLocationZ(TempLoc2))
call RemoveLocation(TempLoc)
call RemoveLocation(TempLoc2)
endif
endif
if (DummyCasterIsHealing[j]) then
if (GetWidgetLife(DummyCasterTargetedUnit[j]) / GetUnitState(DummyCasterTargetedUnit[j], UNIT_STATE_MAX_LIFE) * 100) != 100 then
call SetWidgetLife(DummyCasterTargetedUnit[j], GetWidgetLife(DummyCasterTargetedUnit[j]) + ((GetHealing(GetUnitAbilityLevel(Caster[i], SpellID)) / DummyCasterAttackLength) * 0.03))
endif
else
call UnitDamageTarget(Caster[i], DummyCasterTargetedUnit[j], (GetDamage(GetUnitAbilityLevel(Caster[i], SpellID)) / DummyCasterAttackLength) * 0.03, true, false, AttackType, DamageType, WEAPON_TYPE_WHOKNOWS)
endif
else
if not DummyCasterLightningIsDestroyed[j] then
set DummyCasterLightningIsDestroyed[j] = true
call DestroyLightning(DummyCasterLightningAttack[j])
endif
set DummyCasterLightningRemainingDur[j] = 0
set DummyCasterTargetedUnit[j] = null
set DummyCasterDoesLightningAttack[j] = false
endif
endif
endif
set j = j + 1
exitwhen j > DummyCastersIndex
endloop
endif
if (TimeLeft[i] < UpRisingTime and TimeLeft[i] > 0) then // if cross is rising up
if not FloatedUp[i] then
set FloatedUp[i] = true
call SetUnitFlyHeight(Cross[i], BaseHeight, (BaseHeight - HeightToGo) / UpRisingTime)
set j = 1
loop
if (DummyCastersSpellNumb[j] == i) then
if not DummyCasterLightningIsDestroyed[j] then
set DummyCasterLightningIsDestroyed[j] = true
call DestroyLightning(DummyCasterLightningAttack[j])
endif
set DummyCasterTargetedUnit[j] = null
call SetUnitFlyHeight(DummyCasters[j], BaseHeight, (BaseHeight - HeightToGo) / UpRisingTime)
endif
set j = j + 1
exitwhen j > DummyCastersIndex
endloop
endif
endif
if (TimeLeft[i] <= 0) then //Finish
set IsActive[i] = IsActive[Index]
set IsActive[Index] = false
call RemoveUnit(Cross[i])
set Cross[i] = Cross[Index]
set Cross[Index] = null
set Caster[i] = Caster[Index]
set Caster[Index] = null
set TimeLeft[i] = TimeLeft[Index]
set TimeLeft[Index] = 0
set FloatingDirection[i] = FloatingDirection[Index]
set FloatingDirection[Index] = 0
set FloatedUp[i] = FloatedUp[Index]
set FloatedUp[Index] = false
set j = 1
loop
if (DummyCastersSpellNumb[j] == Index) then
set DummyCastersSpellNumb[j] = i
set DummyCastersSpellNumb[DummyCastersIndex] = 0
if not DummyCasterLightningIsDestroyed[j] then
set DummyCasterLightningIsDestroyed[j] = true
call DestroyLightning(DummyCasterLightningAttack[j])
endif
call RemoveUnit(DummyCasters[j])
set DummyCasters[j] = DummyCasters[DummyCastersIndex]
set DummyCasters[DummyCastersIndex] = null
set DummyCasterTargetedUnit[j] = DummyCasterTargetedUnit[DummyCastersIndex]
set DummyCasterTargetedUnit[DummyCastersIndex] = null
set DummyCasterFloatingDirection[j] = DummyCasterFloatingDirection[DummyCastersIndex]
set DummyCasterFloatingDirection[DummyCastersIndex] = 0
set DummyCasterLeftCooldown[j] = DummyCasterLeftCooldown[DummyCastersIndex]
set DummyCasterLeftCooldown[DummyCastersIndex] = 0
set DummyCasterLightningAttack[j] = DummyCasterLightningAttack[DummyCastersIndex]
set DummyCasterLightningAttack[DummyCastersIndex] = null
set DummyCasterLightningRemainingDur[j] = DummyCasterLightningRemainingDur[DummyCastersIndex]
set DummyCasterLightningRemainingDur[DummyCastersIndex] = 0
set DummyCasterDoesLightningAttack[j] = DummyCasterDoesLightningAttack[DummyCastersIndex]
set DummyCasterDoesLightningAttack[DummyCastersIndex] = false
set DummyCasterTargetedUnit[j] = DummyCasterTargetedUnit[DummyCastersIndex]
set DummyCasterTargetedUnit[DummyCastersIndex] = null
set DummyCasterIsHealing[j] = DummyCasterIsHealing[DummyCastersIndex]
set DummyCasterIsHealing[DummyCastersIndex] = false
set DummyCasterLightningIsDestroyed[j] = DummyCasterLightningIsDestroyed[DummyCastersIndex]
set DummyCasterLightningIsDestroyed[DummyCastersIndex] = true
set DummyCastersIndex = DummyCastersIndex - 1
set j = j - 1
endif
set j = j + 1
exitwhen j > DummyCastersIndex
endloop
set Index = Index - 1
set i = i - 1
endif
endif
set i = i + 1
exitwhen i > Index
endloop
endif
return false
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
local trigger t2 = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function Actions))
call TriggerRegisterTimerEvent( t2, 0.03, true)
call TriggerAddCondition( t2, Condition(function Loop))
set t = null
set t2 = null
endfunction
endlibrary // PaladinHolyCross
//TESH.scrollpos=0
//TESH.alwaysfold=0
library HolyCrossFunctions
function AngleBetweenPointsXY takes real xA, real yA, real xB, real yB returns real
return bj_RADTODEG * Atan2(yB - yA, xB - xA)
endfunction
function IsUnitAlive takes unit u returns boolean
return (GetWidgetLife(u) > .405 and not IsUnitType( u, UNIT_TYPE_DEAD) and GetUnitTypeId(u) != 0)
endfunction
function PolarProjectionX takes real x, real dist, real angle returns real
return x + dist * Cos(angle * bj_DEGTORAD)
endfunction
function PolarProjectionY takes real y, real dist, real angle returns real
return y + dist * Sin(angle * bj_DEGTORAD)
endfunction
function PlaySoundAtPoint takes string f, real x, real y returns nothing
local sound s = CreateSound(f, false, true, true, 10, 10, "")
call SetSoundDuration(s, GetSoundFileDuration(f))
call SetSoundChannel(s, 0)
call SetSoundVolume(s, 127)
call SetSoundPitch(s, 1.0)
call SetSoundPosition(s, x, y, 0)
call StartSound(s)
call KillSoundWhenDone(s)
set s = null
endfunction
endlibrary // HolyCrossFunctions
//TESH.scrollpos=18
//TESH.alwaysfold=0
//==============================================================================
//---DiscipleOfLife's-----------------------------------------------------------
// GCU // GetClosestUnit(s) v1.3.1
//------------------------------------------------------------------------------
//
// This library contains the following functions, each of which return the
// unit that is closest to given coordinates and passes a specified filter:
//
// - GetClosestUnit(x, y, filter)
// - GetClosestUnitAlt(x, y, filter)
// - GetClosestUnitInRange(x, y, radius, filter)
// - GetClosestUnitInGroup(x, y, g)
//
// Included are also the following functions, each of which return a
// group consisting of the units closest to given coordinates that
// pass a specified filter:
//
// - GetClosestUnits(x, y, n, filter)
// - GetClosestUnitsInRange(x, y, radius, n, filter)
// - GetClosestUnitsInGroup(x, y, g, n)
//
// Important:
//
// - flying heights and the height of the ground aren't taken into account,
// only the distance in 2D
//
// - these functions can't be used in the boolexpr's passed to them
//
// - all of the functions in this library go through many units to find the
// closest one, meaning that the functions' performance is highly dependant
// on the amount of units they have to go through
//
//------------------------------------------------------------------------------
library GCU
globals
private unit CurrentPick
private real CenterX
private real CenterY
private real CurrentDistance
private group AnyGroup = CreateGroup()
endglobals
private function Enum takes nothing returns nothing
local unit u = GetEnumUnit()
local real dx = GetUnitX(u) - CenterX
local real dy = GetUnitY(u) - CenterY
local real d = (dx*dx + dy*dy) / 10000.
if d < CurrentDistance then
set CurrentDistance = d
set CurrentPick = u
endif
set u = null
endfunction
//==========================================================================
// Finds the unit that is closest to (x, y) from all units on the map that
// pass the filter and do not have the locust ability.
//
function GetClosestUnit takes real x, real y, boolexpr filter returns unit
local real r = 800.
loop
call GroupEnumUnitsInRange(AnyGroup, x, y, r, filter)
exitwhen FirstOfGroup(AnyGroup) != null
if r >= 3200. then
call GroupEnumUnitsInRect(AnyGroup, bj_mapInitialPlayableArea, filter)
exitwhen true
endif
set r = 2.00 * r
endloop
set CurrentPick = null
set CenterX = x
set CenterY = y
set CurrentDistance = 100000
call ForGroup(AnyGroup, function Enum)
return CurrentPick
endfunction
//==========================================================================
// Does the same as above. Faster when there are no units that pass the
// filter in a 3200 radius, but at other times slower, and most likely a
// lot slower. How much faster is somewhat directly proportional to the
// amount of units that do not pass the filter inside that 3200 radius.
//
function GetClosestUnitAlt takes real x, real y, boolexpr filter returns unit
set CurrentPick = null
set CenterX = x
set CenterY = y
set CurrentDistance = 100000
call GroupEnumUnitsInRect(AnyGroup, bj_mapInitialPlayableArea, filter)
call ForGroup(AnyGroup, function Enum)
return CurrentPick
endfunction
//==========================================================================
// Finds the unit that is closest to (x, y) from all units in the specified
// radius, that pass the filter and do not have the locust ability.
//
function GetClosestUnitInRange takes real x, real y, real radius, boolexpr filter returns unit
set CurrentPick = null
set CenterX = x
set CenterY = y
set CurrentDistance = 100000
call GroupEnumUnitsInRange(AnyGroup, x, y, radius, filter)
call ForGroup(AnyGroup, function Enum)
return CurrentPick
endfunction
//==========================================================================
// Finds the unit that is closest to (x, y) from whichGroup. Unlike the
// other versions this one considers locusted units also.
//
function GetClosestUnitInGroup takes real x, real y, group whichGroup returns unit
set CurrentPick = null
set CenterX = x
set CenterY = y
set CurrentDistance = 100000
call ForGroup(whichGroup, function Enum)
return CurrentPick
endfunction
//==========================================================================
// The following three functions do the same as the preceding ones, with //
// the exception that they return groups consisting of the n closest //
// units instead of the closest unit //
//==========================================================================
globals
private group ResultGroup
endglobals
function GetClosestUnits takes real x, real y, integer n, boolexpr filter returns group
call GroupEnumUnitsInRect(AnyGroup, bj_mapInitialPlayableArea, filter)
set ResultGroup = CreateGroup()
set CenterX = x
set CenterY = y
loop
exitwhen n == 0
set CurrentPick = null
set CurrentDistance = 100000
call ForGroup(AnyGroup, function Enum)
exitwhen CurrentPick == null
call GroupRemoveUnit(AnyGroup, CurrentPick)
call GroupAddUnit(ResultGroup, CurrentPick)
set n = n - 1
endloop
return ResultGroup
endfunction
function GetClosestUnitsInRange takes real x, real y, real radius, integer n, boolexpr filter returns group
call GroupEnumUnitsInRange(AnyGroup, x, y, radius, filter)
set ResultGroup = CreateGroup()
set CenterX = x
set CenterY = y
loop
exitwhen n == 0
set CurrentPick = null
set CurrentDistance = 100000
call ForGroup(AnyGroup, function Enum)
exitwhen CurrentPick == null
call GroupRemoveUnit(AnyGroup, CurrentPick)
call GroupAddUnit(ResultGroup, CurrentPick)
set n = n - 1
endloop
return ResultGroup
endfunction
private function AnyGroupAddGroupEnum takes nothing returns nothing
call GroupAddUnit(AnyGroup, GetEnumUnit())
endfunction
function GetClosestUnitsInGroup takes real x, real y, group whichGroup, integer n returns group
call GroupClear(AnyGroup)
call ForGroup(whichGroup, function AnyGroupAddGroupEnum)
set ResultGroup = CreateGroup()
set CenterX = x
set CenterY = y
loop
exitwhen n == 0
set CurrentPick = null
set CurrentDistance = 100000
call ForGroup(AnyGroup, function Enum)
exitwhen CurrentPick == null
call GroupRemoveUnit(AnyGroup, CurrentPick)
call GroupAddUnit(ResultGroup, CurrentPick)
set n = n - 1
endloop
return ResultGroup
endfunction
endlibrary // End of GetClosestUnit
//==============================================================================a