NeuroToxin
New Member
- Reaction score
- 46
Okay, so first off, heres my code
And basically, what I'm asking, is there a more efficient way to count the number of units "Attached" to another unit? For this purpose, I'm using Custom Value, but if someone can explain AIDS and how it would be more efficient I'd happily use that instead.
JASS:
scope SoulsCreate initializer Init
//==========================================================================================
//=======================================SETUP=============================================
//==========================================================================================
globals
//The ability Code for the Spell
private constant integer ABILITY_CODE = 039;A003039;
//The Dummy ID For the spell
private constant integer DUMMY_CODE = 039;n000039;
//The speed of the circling (Note that 4 is actually a pretty average speed)
private constant real SPEED = 8
//The effect to be played on the corpses that are getting they're souls taken.
private constant string EFFECT_ON_CORPSE = "Objects\\Spawnmodels\\Undead\\UndeadDissipate\\UndeadDissipate.mdx"
endglobals
//==========================================================================================
//=====================================ENDSETUP===========================================
//==========================================================================================
private function CIRCLE_RADIUS takes integer lvl returns real
return 150 + (lvl * 0.)
endfunction
//==========================================================================================
//Just an FYI, RADIUS, is the radius at which a soul can be acquired, CIRCLE_RADIUS, is the radius
//at which the souls will circle the caster.
//==========================================================================================
private function RADIUS takes integer lvl returns real
return 500 + (lvl * 100.)
endfunction
//==========================================================================================
private function MAXSOULS takes integer lvl returns real
return 15 + (lvl * 5.)
endfunction
//==========================================================================================
globals
private group array CirclingUnits[30]
private integer CustomValue = 0
private group Casters = CreateGroup()
endglobals
//==========================================================================================
private function DeadUnits takes nothing returns boolean
if IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD) then
call DestroyEffect( AddSpecialEffect( EFFECT_ON_CORPSE, GetUnitX(GetFilterUnit()), GetUnitY(GetFilterUnit())))
return true
endif
return false
endfunction
//==========================================================================================
private function GroupEnum takes group g, unit u, real x, real y, real radius returns group
call GroupEnumUnitsInRange(g, x, y, radius, Condition(function DeadUnits))
return g
endfunction
//==========================================================================================
private function AddtoCircle takes unit u, unit c returns nothing
if IsUnitInGroup(u, CirclingUnits[GetUnitUserData(c)]) == false then
call GroupAddUnit(CirclingUnits[GetUnitUserData(c)], u)
endif
endfunction
//==========================================================================================
struct Souls
unit Caster
unit Dummy
real angle
integer Unittype
endstruct
//==========================================================================================
private function MovingSouls takes nothing returns boolean
local Souls s = KT_GetData()
local real dummyx = GetUnitX(s.Dummy)
local real dummyy = GetUnitY(s.Dummy)
local real casterx = GetUnitX(s.Caster)
local real castery = GetUnitY(s.Caster)
local real offsetx
local real offsety
local real dx = dummyx - casterx
local real dy = dummyy - castery
local real distance = SquareRoot(dx * dx + dy * dy)
local integer level = GetUnitAbilityLevel(s.Caster, ABILITY_CODE)
local real maxsouls = MAXSOULS(level)
local real circleradius = CIRCLE_RADIUS(level)
local boolean outsidecircle = (distance > circleradius)
local real angle
if outsidecircle and IsUnitInGroup(s.Dummy, CirclingUnits[GetUnitUserData(s.Caster)]) == false then
set angle = Atan2(castery - dummyy, casterx - dummyx)
set offsetx = dummyx + 20 * Cos(angle)
set offsety = dummyy + 20 * Sin(angle)
call SetUnitX(s.Dummy, offsetx)
call SetUnitY(s.Dummy, offsety)
call SetUnitFacing(s.Dummy, angle)
elseif not outsidecircle or IsUnitInGroup(s.Dummy, CirclingUnits[GetUnitUserData(s.Caster)]) == true then
set s.angle = s.angle + (SPEED * bj_DEGTORAD)
set offsetx = casterx + circleradius * Cos(s.angle)
set offsety = castery + circleradius * Sin(s.angle)
call SetUnitX(s.Dummy, offsetx)
call SetUnitY(s.Dummy, offsety)
call SetUnitFacing(s.Dummy, s.angle + 10)
call AddtoCircle(s.Dummy, s.Caster)
endif
if CountUnitsInGroup(CirclingUnits[GetUnitUserData(s.Caster)]) > maxsouls then
call RemoveUnit(s.Dummy)
call s.destroy()
return true
endif
return false
endfunction
//==========================================================================================
private function UnitInGroup takes unit u returns nothing
if IsUnitInGroup(u, Casters) == false then
call GroupAddUnit(Casters, u)
endif
endfunction
//==========================================================================================
private function CreateStructs takes nothing returns nothing
local Souls s
local unit TUnit = GetTriggerUnit()
local unit DUnit = GetEnumUnit()
local real x1 = GetUnitX(TUnit)
local real x2 = GetUnitX(DUnit)
local real y1 = GetUnitY(TUnit)
local real y2 = GetUnitY(DUnit)
local real maxsouls = MAXSOULS(GetUnitAbilityLevel(TUnit, ABILITY_CODE))
if CountUnitsInGroup(CirclingUnits[GetUnitUserData(GetTriggerUnit())]) < maxsouls then
set s = Souls.create()
set s.Caster = TUnit
set s.Unittype = GetUnitTypeId(DUnit)
set s.angle = bj_RADTODEG * Atan2(y2 - y1, x2 - x1)
set s.Dummy = CreateUnit(GetTriggerPlayer(), DUMMY_CODE, GetUnitX(DUnit), GetUnitY(DUnit), s.angle)
call SetUnitFacing(s.Dummy, s.angle)
call SetUnitFlyHeight(s.Dummy, GetRandomReal(50, 300), 50)
call RemoveUnit(DUnit)
set DUnit = null
set TUnit = null
call KT_Add(function MovingSouls, s, .035)
endif
endfunction
//==========================================================================================
private function SetCustomValue takes unit u returns nothing
if IsUnitInGroup(GetTriggerUnit(), Casters) == false then
call SetUnitUserData(u, CustomValue)
set CustomValue = CustomValue + 1
endif
endfunction
//==========================================================================================
private function OnCast takes nothing returns boolean
local group tempgroup
local integer level
local unit caster
local real maxsouls = MAXSOULS(GetUnitAbilityLevel(GetTriggerUnit(), ABILITY_CODE))
if GetSpellAbilityId() == ABILITY_CODE and CountUnitsInGroup(CirclingUnits[GetUnitUserData(GetTriggerUnit())]) < maxsouls then
set caster = GetTriggerUnit()
set tempgroup = CreateGroup()
set level = GetUnitAbilityLevel(caster, ABILITY_CODE)
call SetCustomValue(caster)
call UnitInGroup(caster)
set tempgroup = GroupEnum(tempgroup, caster, GetUnitX(caster), GetUnitY(caster), RADIUS(level))
call ForGroup(tempgroup, function CreateStructs)
call DestroyGroup(tempgroup)
endif
set tempgroup = null
set caster = null
return false
endfunction
//==========================================================================================
private function Init takes nothing returns nothing
local integer index = 0
local trigger t = CreateTrigger( )
call TriggerAddCondition( t, Condition( function OnCast ) )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
loop
exitwhen index == 30
set CirclingUnits[index] = CreateGroup()
set index = index + 1
endloop
endfunction
endscope
And basically, what I'm asking, is there a more efficient way to count the number of units "Attached" to another unit? For this purpose, I'm using Custom Value, but if someone can explain AIDS and how it would be more efficient I'd happily use that instead.