Name | Type | is_array | initial_value |
Anti_Magic_Dummy | unit | No | |
Anti_Magic_Enum_Unit | unit | No | |
NETHER_VACUUM_ABILITY | abilcode | No | |
Nether_Vacuum_Accel_Z | real | Yes | |
Nether_Vacuum_Alloc | integer | Yes | |
NETHER_VACUUM_CAP_DIST_RATIO | real | Yes | |
Nether_Vacuum_Caster | unit | Yes | |
Nether_Vacuum_Closure_Timer | timer | Yes | |
Nether_Vacuum_Current | integer | No | |
NETHER_VACUUM_DEATH_MODEL | string | No | |
NETHER_VACUUM_DPS | real | Yes | |
Nether_Vacuum_Dummy_Enum_Unit | unit | No | |
Nether_Vacuum_Dummy_Loc | location | Yes | |
Nether_Vacuum_Dummy_Var | integer | No | |
NETHER_VACUUM_DURATION | real | Yes | |
Nether_Vacuum_Hashtable | hashtable | No | |
NETHER_VACUUM_INNER_RADIUS | real | Yes | |
NETHER_VACUUM_INTERVAL | real | No | |
Nether_Vacuum_Level | integer | Yes | |
Nether_Vacuum_List_Mode | integer | Yes | |
NETHER_VACUUM_MAX_SPAWN_COUNT | integer | Yes | |
Nether_Vacuum_Next | integer | Yes | |
NETHER_VACUUM_OUTER_RADIUS | real | Yes | |
Nether_Vacuum_Pitch_Temp | real | No | |
Nether_Vacuum_Portal | integer | Yes | |
NETHER_VACUUM_PORTAL_MODEL | string | No | |
Nether_Vacuum_Portal_Pointer | integer | Yes | |
Nether_Vacuum_Prev | integer | Yes | |
NETHER_VACUUM_PROJ_END_Z | real | Yes | |
NETHER_VACUUM_PROJ_LAUNCH_Z | real | Yes | |
NETHER_VACUUM_PROJ_MAX_HEIGHT | real | Yes | |
NETHER_VACUUM_PROJECTILE_MODEL | string | No | |
Nether_Vacuum_Projectile_SFX | effect | Yes | |
NETHER_VACUUM_PULL_REL_FACTOR | real | Yes | |
NETHER_VACUUM_PULL_VELOCITY | real | Yes | |
NETHER_VACUUM_ROTATE_VELOCITY | real | Yes | |
Nether_Vacuum_SFX_Yaw | real | Yes | |
Nether_Vacuum_Spawn_CurScale | real | Yes | |
Nether_Vacuum_Spawn_DelayTicks | integer | Yes | |
Nether_Vacuum_Spawn_Group | group | Yes | |
NETHER_VACUUM_SPAWN_MAX_SCALE | real | No | |
NETHER_VACUUM_SPAWN_MODEL | string | No | |
Nether_Vacuum_Spawn_TicksMax | integer | Yes | |
NETHER_VACUUM_SPAWN_TIMED_LIFE | real | Yes | |
NETHER_VACUUM_SPAWN_TYPE | unitcode | Yes | |
NETHER_VACUUM_SPAWNS_DELAY | real | Yes | |
NETHER_VACUUM_SPEED | real | Yes | |
Nether_Vacuum_TargetX | real | Yes | |
Nether_Vacuum_TargetY | real | Yes | |
Nether_Vacuum_Temp_Dist | real | Yes | |
Nether_Vacuum_Timer | timer | No | |
NETHER_VACUUM_UPROOT_TREES | boolean | Yes | |
Nether_Vacuum_Veloc_Z | real | Yes | |
Parabola_Func_Id | integer | No | |
Parabola_Initial_Acceleration | real | No | |
Parabola_Initial_Velocity | real | No | |
Parabola_Veloc | real | No | |
ParabolaLoc | location | Yes | |
ParabolaX | real | Yes | |
ParabolaY | integer | Yes | |
ParabolaZ | real | Yes | |
ParabolaZ_Max | real | No | |
Void_Portal_Alloc | integer | Yes | |
Void_Portal_Attack_Type | attacktype | Yes | |
Void_Portal_Capture_Dist_Ratio | real | Yes | |
VOID_PORTAL_CAPTURE_DISTANCE | real | No | |
Void_Portal_Caster | unit | Yes | |
Void_Portal_Create_InnerRad | real | No | |
Void_Portal_Create_Location | location | No | |
Void_Portal_Create_Model | string | No | |
Void_Portal_Create_OuterRad | real | No | |
Void_Portal_Create_Owner | player | No | |
Void_Portal_Current | integer | No | |
Void_Portal_Damage_Type | damagetype | Yes | |
Void_Portal_Death_Group | group | Yes | |
Void_Portal_Death_Model | string | Yes | |
Void_Portal_Destroy_Flag | integer | Yes | |
Void_Portal_Destroy_Instance | integer | No | |
Void_Portal_Do_Remove | boolean | No | |
Void_Portal_Do_Spawn | boolean | No | |
Void_Portal_DPS | real | Yes | |
Void_Portal_Enum_Unit | unit | No | |
Void_Portal_Exclude_Group | group | Yes | |
Void_Portal_Inner_Radius | real | Yes | |
VOID_PORTAL_INNER_RADIUS | real | No | |
VOID_PORTAL_INTERVAL | real | No | |
VOID_PORTAL_MODEL | string | No | |
Void_Portal_Model | string | Yes | |
Void_Portal_Model_Scale | real | Yes | |
Void_Portal_Next | integer | Yes | |
Void_Portal_On_Death_Flag | trigger | Yes | |
Void_Portal_On_Filter | trigger | Yes | |
Void_Portal_On_Spawn | trigger | Yes | |
Void_Portal_Outer_Radius | real | Yes | |
VOID_PORTAL_OUTER_RADIUS | real | No | |
Void_Portal_Pass_Filter | boolean | No | |
Void_Portal_Prev | integer | Yes | |
Void_Portal_Pull_Rel_Veloc | real | Yes | |
VOID_PORTAL_PULL_VEL | real | No | |
Void_Portal_Pull_Velocity | real | Yes | |
Void_Portal_Recursion_Count | integer | No | |
Void_Portal_Recursion_Damage | real | No | |
VOID_PORTAL_ROTATE_VEL | real | No | |
Void_Portal_Rotate_Velocity | real | Yes | |
Void_Portal_SFX | effect | Yes | |
Void_Portal_Spawn_Count | integer | Yes | |
Void_Portal_Spawn_Model | string | Yes | |
Void_Portal_Spawn_Owner | player | Yes | |
Void_Portal_Spawn_Type | unitcode | Yes | |
Void_Portal_System_Damage_Flag | boolean | No | |
Void_Portal_System_Running | boolean | Yes | |
Void_Portal_Timer | timer | No |
function GetParabolicInitialVelocity takes real x1, real y1, real z1, real x2, real y2, real z2, real k, real vel returns real
local real dist = SquareRoot((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
local real b = 0.
local real h = 0.
local real a = 0.
// Always assume maximum height in case of in-between parameters.
if ((k > z1) and (z2 > k)) then
set k = z2
elseif ((k > z2) and (z1 > k)) then
set k = z1
endif
set b = (z1-k)*dist // -(z2-k)*0
if (z1 == z2) then
set h = dist/2.
elseif (k <= z1) or (k <= z2) then
set h = (b - SquareRoot(b*b - (z1-z2)*(b*dist/*-(z2-k)*0*0*/)))/(z1-z2)
else
set h = (b + SquareRoot(b*b - (z1-z2)*(b*dist/*-(z2-k)*0*0*/)))/(z1-z2)
endif
if h == 0 then
set a = (z2-k)/((dist-h)*(dist-h))
else
set a = (z1-k)/(h*h)
endif
set udg_Parabola_Initial_Acceleration = a*vel
set udg_Parabola_Initial_Velocity = -2*a*h*vel
return udg_Parabola_Initial_Velocity
endfunction
function GetParabolicInitialVelocityEx takes location loc1, location loc2, real z1, real z2, real k, real vel returns real
local real lowZ = RMinBJ(GetLocationZ(loc1) + z1, GetLocationZ(loc2) + z2)
return GetParabolicInitialVelocity(GetLocationX(loc1), GetLocationY(loc1), z1, GetLocationX(loc2), GetLocationY(loc2), z2, lowZ + k, vel)
endfunction
function GetParabolicInitialVelocity2 takes real x1, real z1, real x2, real z2, real k, real time returns real
return GetParabolicInitialVelocity(x1, 0, z1, x2, 0, z2, k, time)
endfunction
library VoidPortal
globals
private trigger damageTrigger = null
endglobals
native UnitAlive takes unit id returns boolean
// -- Private function
private function CreateVoidCreatures takes integer i returns nothing
local real x = BlzGetLocalSpecialEffectX(udg_Void_Portal_SFX[i])
local real y = BlzGetLocalSpecialEffectY(udg_Void_Portal_SFX[i])
local string modelPath = udg_Void_Portal_Spawn_Model[i]
local integer count = udg_Void_Portal_Spawn_Count[i]
local integer spawnType = udg_Void_Portal_Spawn_Type[i]
local integer prevCur = udg_Void_Portal_Current
local group lastGrp = bj_lastCreatedGroup
local unit lastUnit = bj_lastCreatedUnit
set bj_lastCreatedGroup = CreateGroup()
loop
exitwhen count <= 0
set bj_lastCreatedUnit = CreateUnit(udg_Void_Portal_Spawn_Owner[i], spawnType, x, y, GetRandomReal(0, 360))
call DestroyEffect(AddSpecialEffect(modelPath, GetUnitX(bj_lastCreatedUnit), GetUnitY(bj_lastCreatedUnit)))
call GroupAddUnit(bj_lastCreatedGroup, bj_lastCreatedUnit)
set count = count - 1
endloop
set udg_Void_Portal_Current = i
call TriggerExecute(udg_Void_Portal_On_Spawn[i])
set udg_Void_Portal_Current = prevCur
set bj_lastCreatedGroup = lastGrp
set bj_lastCreatedUnit = lastUnit
set lastGrp = null
set lastUnit = null
endfunction
function OnVoidPortalDestroy takes integer i returns nothing
// -- Spawn the creatures
call CreateVoidCreatures(i)
// -- Destroy object
call DestroyEffect(udg_Void_Portal_SFX[i])
call DestroyGroup(udg_Void_Portal_Death_Group[i])
call DestroyGroup(udg_Void_Portal_Exclude_Group[i])
set udg_Void_Portal_Caster[i] = null
set udg_Void_Portal_Death_Group[i] = null
set udg_Void_Portal_Exclude_Group[i] = null
set udg_Void_Portal_SFX[i] = null
set udg_Void_Portal_Model[i] = null
set udg_Void_Portal_Death_Model[i] = null
set udg_Void_Portal_Spawn_Model[i] = null
set udg_Void_Portal_Spawn_Owner[i] = null
set udg_Void_Portal_Spawn_Type[i] = 0
set udg_Void_Portal_Spawn_Count[i] = 0
set udg_Void_Portal_Destroy_Flag[i] = 0
set udg_Void_Portal_DPS[i] = 0.
set udg_Void_Portal_Inner_Radius[i] = 0.
set udg_Void_Portal_Outer_Radius[i] = 0.
set udg_Void_Portal_Pull_Rel_Veloc[i] = 0.
// -- Assume callback trigger was defined
set udg_Void_Portal_On_Death_Flag[i] = null
set udg_Void_Portal_Attack_Type[i] = ATTACK_TYPE_NORMAL
set udg_Void_Portal_Damage_Type[i] = DAMAGE_TYPE_UNIVERSAL
set udg_Void_Portal_Capture_Dist_Ratio[i] = udg_VOID_PORTAL_CAPTURE_DISTANCE
set udg_Void_Portal_On_Filter[i] = gg_trg_Void_Portal_Filter
set udg_Void_Portal_On_Spawn[i] = gg_trg_Void_Portal_On_Spawn
set udg_Void_Portal_Pull_Velocity[i] = udg_VOID_PORTAL_PULL_VEL
set udg_Void_Portal_Rotate_Velocity[i] = udg_VOID_PORTAL_ROTATE_VEL
endfunction
// -- Destroys a void portal instance.
function DestroyVoidPortal takes integer i returns boolean
// -- Cannot destroy an un-allocated or an already-deallocated instance
if udg_Void_Portal_Alloc[i] != -1 then
return false
endif
if udg_Void_Portal_System_Running[0] or udg_Void_Portal_System_Running[1] then
if udg_Void_Portal_System_Running[0] then
set udg_Void_Portal_Destroy_Flag[i] = 1
elseif udg_Void_Portal_System_Running[1] then
set udg_Void_Portal_Destroy_Flag[i] = 2
endif
return false
endif
// -- Unlink instance
set udg_Void_Portal_Next[udg_Void_Portal_Prev[i]] = udg_Void_Portal_Next[i]
set udg_Void_Portal_Prev[udg_Void_Portal_Next[i]] = udg_Void_Portal_Prev[i]
// -- Deallocate instance
set udg_Void_Portal_Alloc[i] = udg_Void_Portal_Alloc[0]
set udg_Void_Portal_Alloc[0] = i
call OnVoidPortalDestroy(i)
// -- Successful
return true
endfunction
// -- Updates a void portal instance with the changes made.
function UpdateVoidPortal takes integer i returns nothing
local effect oldFX = udg_Void_Portal_SFX[i]
set udg_Void_Portal_SFX[i] = AddSpecialEffect(udg_Void_Portal_Model[i], BlzGetLocalSpecialEffectX(oldFX), BlzGetLocalSpecialEffectY(oldFX))
call BlzSetSpecialEffectScale(udg_Void_Portal_SFX[i], udg_Void_Portal_Model_Scale[i])
call BlzSetSpecialEffectAlpha(oldFX, 0)
call DestroyEffect(oldFX)
set oldFX = null
endfunction
// -- Callback function that handles everything from the gravitational pull simulation, to the filter.
// -- Will pause whenever there are no more instances.
function OnVoidPortalUpdate takes nothing returns nothing
local integer i = udg_Void_Portal_Next[0]
local group g = CreateGroup()
local effect fx = null
local real at = 0.
local real rt = 0.
local real pl = 0.
local real cx = 0.
local real cy = 0.
local real ux = 0.
local real uy = 0.
local real hp = 0.
local real dist1 = 0.
local real dist2 = 0.
local real dist3 = 0.
local real dist4 = 0.
local real dist5 = 0.
loop
exitwhen (i == 0)
set cx = BlzGetLocalSpecialEffectX(udg_Void_Portal_SFX[i])
set cy = BlzGetLocalSpecialEffectY(udg_Void_Portal_SFX[i])
set dist1 = udg_Void_Portal_Inner_Radius[i]*udg_Void_Portal_Inner_Radius[i]
set dist2 = udg_Void_Portal_Capture_Dist_Ratio[i]*udg_Void_Portal_Capture_Dist_Ratio[i]
call GroupEnumUnitsInRange(g, cx, cy, udg_Void_Portal_Outer_Radius[i], null)
loop
set udg_Void_Portal_Enum_Unit = FirstOfGroup(g)
call GroupRemoveUnit(g, udg_Void_Portal_Enum_Unit)
// -- Exit when reaching the end of the group loop, or when the instance is destroyed.
exitwhen udg_Void_Portal_Enum_Unit == null or (udg_Void_Portal_Alloc[i] != -1)
// -- Check if the unit was filtered beforehand
if not IsUnitInGroup(udg_Void_Portal_Enum_Unit, udg_Void_Portal_Exclude_Group[i]) then
// -- Apply filter
set udg_Void_Portal_Pass_Filter = true
set udg_Void_Portal_Current = i
set udg_Void_Portal_System_Running[0] = true
call TriggerExecute(udg_Void_Portal_On_Filter[i])
set udg_Void_Portal_System_Running[0] = false
if udg_Void_Portal_Pass_Filter and not IsUnitInGroup(udg_Void_Portal_Enum_Unit, udg_Void_Portal_Death_Group[i]) and BlzBitAnd(udg_Void_Portal_Destroy_Flag[i], 1) != 1 then
// -- Pull the unit inward
// Get angle in radian, then add it by the angular acceleration of the object.
set ux = GetUnitX(udg_Void_Portal_Enum_Unit)
set uy = GetUnitY(udg_Void_Portal_Enum_Unit)
set at = Atan2(uy-cy, ux-cx)
set dist3 = (cx-ux)*(cx-ux) + (cy-uy)*(cy-uy)
set dist5 = SquareRoot(dist3)
set rt = (udg_Void_Portal_Rotate_Velocity[i]/dist5)*udg_VOID_PORTAL_INTERVAL
set dist4 = dist3/dist1
// -- Using the formula f(x) = (ex)**e/(e**(ex))
set at = at + rt
if dist3 > dist1 then
set pl = (Pow(bj_E, -bj_E*dist4)*Pow(bj_E*dist4, bj_E))
else
set pl = -120*(1/5.*Pow(dist4, 2.5) - 1/2.*(dist4*dist4) + 5/12.*Pow(dist4, 1.5) - 1/8.*dist4)
call SetUnitFlyHeight(udg_Void_Portal_Enum_Unit, GetUnitDefaultFlyHeight(udg_Void_Portal_Enum_Unit)*pl, 0.)
call SetUnitFlyHeight(udg_Void_Portal_Enum_Unit, GetUnitDefaultFlyHeight(udg_Void_Portal_Enum_Unit), 1.)
endif
set pl = dist5 - (udg_Void_Portal_Pull_Velocity[i] + GetUnitMoveSpeed(udg_Void_Portal_Enum_Unit)*udg_Void_Portal_Pull_Rel_Veloc[i])*udg_VOID_PORTAL_INTERVAL*pl
call SetUnitX(udg_Void_Portal_Enum_Unit, cx + pl*Cos(at))
call SetUnitY(udg_Void_Portal_Enum_Unit, cy + pl*Sin(at))
// -- Damage the target
set hp = udg_Void_Portal_DPS[i]*udg_VOID_PORTAL_INTERVAL
if hp != 0 then
// -- If damage is 0, why bother with a damage event?
// -- Flag this damage instance as damage dealt by the system, and apply damage modification whenever
// -- needed
set udg_Void_Portal_System_Damage_Flag = true
set udg_Void_Portal_System_Running[3] = true
call EnableTrigger(damageTrigger)
if not UnitDamageTarget(udg_Void_Portal_Caster[i], udg_Void_Portal_Enum_Unit, hp, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null) then
set udg_Void_Portal_System_Damage_Flag = true
set udg_Void_Portal_System_Running[3] = true
if not UnitDamageTarget(udg_Void_Portal_Enum_Unit, udg_Void_Portal_Enum_Unit, hp, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null) then
call SetWidgetLife(udg_Void_Portal_Enum_Unit, GetWidgetLife(udg_Void_Portal_Enum_Unit)-hp)
endif
set udg_Void_Portal_System_Running[3] = false
set udg_Void_Portal_System_Damage_Flag = false
endif
call DisableTrigger(damageTrigger)
set udg_Void_Portal_System_Running[3] = false
set udg_Void_Portal_System_Damage_Flag = false
endif
// -- If the unit is within capture distance, kill the unit.
if (dist4 <= dist2) then
if UnitAlive(udg_Void_Portal_Enum_Unit) then
set hp = GetWidgetLife(udg_Void_Portal_Enum_Unit)
// -- Ensure that the unit is killed by a caster when provided.
set udg_Void_Portal_System_Damage_Flag = true
set udg_Void_Portal_System_Running[3] = true
call EnableTrigger(damageTrigger)
if not UnitDamageTarget(udg_Void_Portal_Caster[i], udg_Void_Portal_Enum_Unit, hp, true, false, udg_Void_Portal_Attack_Type[i], udg_Void_Portal_Damage_Type[i], null) then
set udg_Void_Portal_System_Damage_Flag = true
set udg_Void_Portal_System_Running[3] = true
if not UnitDamageTarget(udg_Void_Portal_Enum_Unit, udg_Void_Portal_Enum_Unit, hp, true, false, udg_Void_Portal_Attack_Type[i], udg_Void_Portal_Damage_Type[i], null) then
call SetWidgetLife(udg_Void_Portal_Enum_Unit, GetWidgetLife(udg_Void_Portal_Enum_Unit)-hp)
endif
set udg_Void_Portal_System_Running[3] = false
set udg_Void_Portal_System_Damage_Flag = false
endif
call DisableTrigger(damageTrigger)
set udg_Void_Portal_System_Running[3] = false
set udg_Void_Portal_System_Damage_Flag = false
// -- If the unit's still alive, kill the unit (source confirmed).
if not IsUnitType(udg_Void_Portal_Enum_Unit, UNIT_TYPE_DEAD) then
call KillUnit(udg_Void_Portal_Enum_Unit)
endif
endif
// -- Passing true will increase the spawn count.
// -- Passing false will not increase the spawn count
set udg_Void_Portal_Do_Spawn = true
set udg_Void_Portal_Do_Remove = true
set udg_Void_Portal_Current = i
set udg_Void_Portal_Spawn_Count[i] = udg_Void_Portal_Spawn_Count[i] + 1
set udg_Void_Portal_System_Running[1] = true
call TriggerExecute(udg_Void_Portal_On_Death_Flag[i])
set udg_Void_Portal_System_Running[1] = false
if not udg_Void_Portal_Do_Spawn then
set udg_Void_Portal_Spawn_Count[i] = udg_Void_Portal_Spawn_Count[i] - 1
endif
// -- The system should never remove Hero units.
if not IsUnitType(udg_Void_Portal_Enum_Unit, UNIT_TYPE_HERO) and udg_Void_Portal_Do_Remove then
call DestroyEffect(AddSpecialEffect(udg_Void_Portal_Death_Model[i], GetUnitX(udg_Void_Portal_Enum_Unit), GetUnitY(udg_Void_Portal_Enum_Unit)))
call RemoveUnit(udg_Void_Portal_Enum_Unit)
else
if not IsUnitType(udg_Void_Portal_Enum_Unit, UNIT_TYPE_HERO) then
call ShowUnit(udg_Void_Portal_Enum_Unit, false)
endif
call DestroyEffect(AddSpecialEffect(udg_Void_Portal_Death_Model[i], GetUnitX(udg_Void_Portal_Enum_Unit), GetUnitY(udg_Void_Portal_Enum_Unit)))
call GroupAddUnit(udg_Void_Portal_Death_Group[i], udg_Void_Portal_Enum_Unit)
endif
// -- Check if the instance was destroyed here?
if BlzBitAnd(udg_Void_Portal_Destroy_Flag[i], 2) == 2 then
call DestroyVoidPortal(i)
endif
endif
elseif not udg_Void_Portal_Pass_Filter then
// -- Exclude the unit in future searches.
call GroupAddUnit(udg_Void_Portal_Exclude_Group[i], udg_Void_Portal_Enum_Unit)
elseif BlzBitAnd(udg_Void_Portal_Destroy_Flag[i], 1) == 1 then
// -- Destroy the instance
call DestroyVoidPortal(i)
endif
endif
endloop
set i = udg_Void_Portal_Next[i]
endloop
call DestroyGroup(g)
set udg_Void_Portal_Current = 0
// -- List is empty, pause timer
if udg_Void_Portal_Next[0] == 0 then
call PauseTimer(udg_Void_Portal_Timer)
endif
endfunction
function CreateVoidPortal takes player owner, real x, real y, real innerR, real outerR, string modelPath returns integer
// -- Allocation
local integer i = udg_Void_Portal_Alloc[0]
if udg_Void_Portal_Alloc[i] == -1 or (i == 0) then
if i + 1 >= JASS_MAX_ARRAY_SIZE then
return 0
endif
set i = i + 1
set udg_Void_Portal_Alloc[0] = i
else
set udg_Void_Portal_Alloc[0] = udg_Void_Portal_Alloc[i]
endif
set udg_Void_Portal_Alloc[i] = -1
// -- Linked list
set udg_Void_Portal_Next[i] = 0
set udg_Void_Portal_Prev[i] = udg_Void_Portal_Prev[0]
set udg_Void_Portal_Next[udg_Void_Portal_Prev[i]] = i
set udg_Void_Portal_Prev[udg_Void_Portal_Next[i]] = i
// -- Object creation
set udg_Void_Portal_Current = i
set udg_Void_Portal_Pull_Rel_Veloc[i] = 0.
set udg_Void_Portal_Inner_Radius[i] = innerR
set udg_Void_Portal_Outer_Radius[i] = outerR
set udg_Void_Portal_Model[i] = modelPath
set udg_Void_Portal_Spawn_Owner[i] = owner
set udg_Void_Portal_Death_Group[i] = CreateGroup()
set udg_Void_Portal_Exclude_Group[i] = CreateGroup()
set udg_Void_Portal_SFX[i] = AddSpecialEffect(modelPath, x, y)
set udg_Void_Portal_On_Filter[i] = gg_trg_Void_Portal_Filter
set udg_Void_Portal_On_Spawn[i] = gg_trg_Void_Portal_On_Spawn
set udg_Void_Portal_Capture_Dist_Ratio[i] = udg_VOID_PORTAL_CAPTURE_DISTANCE
set udg_Void_Portal_Pull_Velocity[i] = udg_VOID_PORTAL_PULL_VEL
set udg_Void_Portal_Rotate_Velocity[i] = udg_VOID_PORTAL_ROTATE_VEL
set udg_Void_Portal_Attack_Type[i] = ATTACK_TYPE_NORMAL
set udg_Void_Portal_Damage_Type[i] = DAMAGE_TYPE_UNIVERSAL
// -- Start Void Portal Timer
if udg_Void_Portal_Prev[i] == 0 then
call TimerStart(udg_Void_Portal_Timer, udg_VOID_PORTAL_INTERVAL, true, function OnVoidPortalUpdate)
endif
// -- Return instance
return i
endfunction
// -- Private
function OnVoidPortalDamage takes nothing returns nothing
if udg_Void_Portal_System_Damage_Flag and not udg_Void_Portal_System_Running[2] then
// The system has detected the damage.
static if LIBRARY_DamageEngine then
// -- Damage Engine should handle possible recursions on its' own.
if (udg_DamageEventDamageT == udg_DAMAGE_TYPE_UNIVERSAL) or (udg_DamageEventDamageT == udg_DAMAGE_TYPE_UNKNOWN) then
set udg_DamageEventType = udg_DamageTypePure
endif
else
// -- Immediately set this to false to prevent false positives of system damage from recursive damage instances.
set udg_Void_Portal_System_Damage_Flag = false
set udg_Void_Portal_System_Running[2] = true
// -- Tell the system to handle incoming recursions...
if GetTriggerEventId() == EVENT_PLAYER_UNIT_DAMAGING then
// -- Store the pure damage dealt here.
set udg_Void_Portal_Recursion_Damage = GetEventDamage()
else
// -- Change the damage dealt to the previous value
if BlzGetEventDamageType() == DAMAGE_TYPE_UNIVERSAL or BlzGetEventDamageType() == DAMAGE_TYPE_UNKNOWN then
call BlzSetEventDamage(udg_Void_Portal_Recursion_Damage)
endif
set udg_Void_Portal_Recursion_Damage = 0.
set udg_Void_Portal_System_Running[2] = false
endif
endif
elseif udg_Void_Portal_System_Running[2] then
// Either a recursion has occurred or something else happened.
static if not LIBRARY_DamageEngine then
// Damage Engine already handles this kind of behavior, so we only concern ourselves with the possibility of it
// not being present.
if GetTriggerEventId() == EVENT_PLAYER_UNIT_DAMAGING then
set udg_Void_Portal_Recursion_Count = udg_Void_Portal_Recursion_Count + 1
else
if udg_Void_Portal_Recursion_Count > 0 then
set udg_Void_Portal_Recursion_Count = udg_Void_Portal_Recursion_Count - 1
set udg_Void_Portal_System_Damage_Flag = udg_Void_Portal_Recursion_Count <= 0
set udg_Void_Portal_System_Running[2] = not udg_Void_Portal_System_Damage_Flag
endif
endif
endif
endif
endfunction
// -- Private
private function InitVoidPortal takes nothing returns nothing
set damageTrigger = CreateTrigger()
static if LIBRARY_DamageEngine then
call TriggerRegisterVariableEvent(damageTrigger, "udg_DamageModifierEvent", EQUAL, 1.00)
else
call TriggerRegisterAnyUnitEventBJ(damageTrigger, EVENT_PLAYER_UNIT_DAMAGING)
call TriggerRegisterAnyUnitEventBJ(damageTrigger, EVENT_PLAYER_UNIT_DAMAGED)
endif
call TriggerAddCondition(damageTrigger, Filter(function OnVoidPortalDamage))
call DisableTrigger(damageTrigger)
endfunction
private module M
private static method onInit takes nothing returns nothing
call InitVoidPortal()
endmethod
endmodule
private struct S extends array
implement M
endstruct
endlibrary
library IsDestructableTree uses optional UnitIndexer /* v1.3.1
*************************************************************************************
*
* Detect whether a destructable is a tree or not.
*
***************************************************************************
*
* Credits
*
* To PitzerMike
* -----------------------
*
* for IsDestructableTree
*
*************************************************************************************
*
* Functions
*
* function IsDestructableTree takes destructable d returns boolean
*
* function IsDestructableAlive takes destructable d returns boolean
*
* function IsDestructableDead takes destructable d returns boolean
*
* function IsTreeAlive takes destructable tree returns boolean
* - May only return true for trees.
*
* function KillTree takes destructable tree returns boolean
* - May only kill trees.
*
*/
globals
private constant integer HARVESTER_UNIT_ID = 'hpea'//* human peasant
private constant integer HARVEST_ABILITY = 'Ahrl'//* ghoul harvest
private constant integer HARVEST_ORDER_ID = 0xD0032//* harvest order ( 852018 )
private constant player NEUTRAL_PLAYER = Player(PLAYER_NEUTRAL_PASSIVE)
private unit harvester = null
endglobals
function IsDestructableTree takes destructable d returns boolean
//* 851973 is the order id for stunned, it will interrupt the preceding harvest order.
return (IssueTargetOrderById(harvester, HARVEST_ORDER_ID, d)) and (IssueImmediateOrderById(harvester, 851973))
endfunction
function IsDestructableDead takes destructable d returns boolean
return (GetWidgetLife(d) <= 0.405)
endfunction
function IsDestructableAlive takes destructable d returns boolean
return (GetWidgetLife(d) > .405)
endfunction
function IsTreeAlive takes destructable tree returns boolean
return IsDestructableAlive(tree) and IsDestructableTree(tree)
endfunction
function KillTree takes destructable tree returns boolean
if (IsTreeAlive(tree)) then
call KillDestructable(tree)
return true
endif
return false
endfunction
private function Init takes nothing returns nothing
static if LIBRARY_UnitIndexer then//* You may adapt this to your own indexer.
set UnitIndexer.enabled = false
endif
set harvester = CreateUnit(NEUTRAL_PLAYER, HARVESTER_UNIT_ID, 0, 0, 0)
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = true
endif
call UnitAddAbility(harvester, HARVEST_ABILITY)
call UnitAddAbility(harvester, 'Aloc')
call ShowUnit(harvester, false)
endfunction
//* Seriously?
private module Inits
private static method onInit takes nothing returns nothing
call Init()
endmethod
endmodule
private struct I extends array
implement Inits
endstruct
endlibrary
function NetherVacuumOnDestroy takes integer i returns nothing
// Do not allow the Nether Vacuum to be destroyed (again) when the List Mode has been flagged
// for destruction.
if (udg_Nether_Vacuum_List_Mode[i] != 0) or (udg_Nether_Vacuum_Alloc[i] != -1) then
return
endif
// -- Remove the reference from the timer first
call RemoveSavedInteger(udg_Nether_Vacuum_Hashtable, 0, GetHandleId(udg_Nether_Vacuum_Closure_Timer[i]))
// -- Destroy the timer
call PauseTimer(udg_Nether_Vacuum_Closure_Timer[i])
call DestroyTimer(udg_Nether_Vacuum_Closure_Timer[i])
// -- Destroy the portal here.
call DestroyVoidPortal(udg_Nether_Vacuum_Portal[i])
set udg_Nether_Vacuum_Portal[i] = 0
// -- Add the instance back to the list.
set udg_Nether_Vacuum_Next[i] = 0
set udg_Nether_Vacuum_Prev[i] = udg_Nether_Vacuum_Prev[0]
set udg_Nether_Vacuum_Next[udg_Nether_Vacuum_Prev[i]] = i
set udg_Nether_Vacuum_Prev[udg_Nether_Vacuum_Next[i]] = i
set udg_Nether_Vacuum_List_Mode[i] = 2
// -- Restart the timer if the timer was paused
if udg_Nether_Vacuum_Prev[i] == 0 then
// A direct call to TimerStart would be appreciated here
call TimerStart(udg_Nether_Vacuum_Timer, udg_NETHER_VACUUM_INTERVAL, true, null)
endif
endfunction
// -- Callback function for the Closure Timer
function NetherVacuumOnClose takes nothing returns nothing
local integer i = LoadInteger(udg_Nether_Vacuum_Hashtable, 0, GetHandleId(GetExpiredTimer()))
call NetherVacuumOnDestroy(i)
endfunction
function Trig_Recursive_Damage_Unit_Actions takes nothing returns nothing
call BJDebugMsg("Damage Reported: Recursive Damage Unit")
if GetTriggerEventId() == EVENT_PLAYER_UNIT_DAMAGED then
call BJDebugMsg("Damage Event Type: On Damaged")
else
call BJDebugMsg("Damage Event Type: On Damaging")
endif
call BJDebugMsg("=========================\n")
call DisableTrigger(GetTriggeringTrigger())
call UnitDamageTarget(GetEventDamageSource(), GetTriggerUnit(), 0., true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, null)
call EnableTrigger(GetTriggeringTrigger())
call BJDebugMsg("Recursive Damage Unit \n=====================\n")
endfunction
//===========================================================================
function InitTrig_Recursive_Damage_Unit takes nothing returns nothing
set gg_trg_Recursive_Damage_Unit = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ(gg_trg_Recursive_Damage_Unit, EVENT_PLAYER_UNIT_DAMAGING)
call TriggerRegisterAnyUnitEventBJ(gg_trg_Recursive_Damage_Unit, EVENT_PLAYER_UNIT_DAMAGED)
call TriggerAddAction( gg_trg_Recursive_Damage_Unit, function Trig_Recursive_Damage_Unit_Actions )
endfunction