// ᶝ===================================== //
// Start Omnislash System //
// ====================================== //
function Omni_Alloc takes nothing returns integer
set udg_Omni_NewThis = udg_Omni_Alloc[0]
if (udg_Omni_Alloc[udg_Omni_NewThis] == -1) or (udg_Omni_NewThis == 0) then
set udg_Omni_NewThis = ( udg_Omni_NewThis + 1 )
set udg_Omni_Alloc[0] = udg_Omni_NewThis
else
set udg_Omni_Alloc[0] = udg_Omni_Alloc[udg_Omni_NewThis]
endif
set udg_Omni_Instance_Count = udg_Omni_Instance_Count + 1
set udg_Omni_Alloc[udg_Omni_NewThis] = -1
return udg_Omni_NewThis
endfunction
function Omni_Dealloc takes integer index returns nothing
if ( udg_Omni_Alloc[index] != -1 ) then
return
endif
set udg_Omni_Alloc[index] = udg_Omni_Alloc[0]
set udg_Omni_Alloc[0] = udg_Omni_Current
set udg_Omni_Instance_Count = ( udg_Omni_Instance_Count - 1 )
endfunction
// member to class
function Omni_Adopt takes nothing returns nothing
local boolean lastWrite = udg_Omni_DoPersistibleWrite
set udg_Omni_DoPersistibleWrite = true
set udg_Omni_AffectAir = udg_Omni_AffectAir_Flag[udg_Omni_Index]
set udg_Omni_AffectMagicImmune = udg_Omni_AffectMagicImmune_Flag[udg_Omni_Index]
set udg_Omni_ContinueWhenDead = udg_Omni_ContinueWhenDead_Flag[udg_Omni_Index]
set udg_Omni_CheckAllies = udg_Omni_CheckAllies__Flag[udg_Omni_Index]
set udg_Omni_CheckEnemies = udg_Omni_CheckEnemies__Flag[udg_Omni_Index]
set udg_Omni_CheckRange = udg_Omni_CheckRange__Flag[udg_Omni_Index]
set udg_Omni_StopWhenRooted = udg_Omni_StopWhenRooted_Flag[udg_Omni_Index]
set udg_Omni_TargetDead = udg_Omni_TargetDead__Flag[udg_Omni_Index]
set udg_Omni_TargetHidden = udg_Omni_TargetHidden_Flag[udg_Omni_Index]
set udg_Omni_TargetInvul = udg_Omni_TargetInvul_Flag[udg_Omni_Index]
set udg_Omni_TargetStructure = udg_Omni_TargetStructure_Flag[udg_Omni_Index]
// --------
set udg_Omni_Caster = udg_Omni_Caster__Array[udg_Omni_Index]
set udg_Omni_Target = udg_Omni_Target__Array[udg_Omni_Index]
set udg_Omni_Group = udg_Omni_Group__Array[udg_Omni_Index]
set udg_Omni_Interval = udg_Omni_Interval__Array[udg_Omni_Index]
set udg_Omni_Duration = udg_Omni_Duration__Array[udg_Omni_Index]
set udg_Omni_Damage = udg_Omni_Damage__Array[udg_Omni_Index]
set udg_Omni_Count = udg_Omni_Count__Array[udg_Omni_Index]
set udg_Omni_Range = udg_Omni_Range__Array[udg_Omni_Index]
// --------
set udg_Omni_OnSlashStart = udg_Omni_OnSlashStart__Array[udg_Omni_Index]
set udg_Omni_OnSlashEvent = udg_Omni_OnSlashEvent__Array[udg_Omni_Index]
set udg_Omni_OnSlashEnd = udg_Omni_OnSlashEnd__Array[udg_Omni_Index]
set udg_Omni_DoPersistibleWrite = lastWrite
endfunction
// class to member
function Omni_Inverse_Adopt takes integer index returns nothing
set udg_Omni_AffectAir_Flag[index] = udg_Omni_AffectAir
set udg_Omni_AffectMagicImmune_Flag[index] = udg_Omni_AffectMagicImmune
set udg_Omni_ContinueWhenDead_Flag[index] = udg_Omni_ContinueWhenDead
set udg_Omni_CheckAllies__Flag[index] = udg_Omni_CheckAllies
set udg_Omni_CheckEnemies__Flag[index] = udg_Omni_CheckEnemies
set udg_Omni_CheckRange__Flag[index] = udg_Omni_CheckRange
set udg_Omni_StopWhenRooted_Flag[index] = udg_Omni_StopWhenRooted
set udg_Omni_TargetDead__Flag[index] = udg_Omni_TargetDead
set udg_Omni_TargetHidden_Flag[index] = udg_Omni_TargetHidden
set udg_Omni_TargetInvul_Flag[index] = udg_Omni_TargetInvul
set udg_Omni_TargetStructure_Flag[index] = udg_Omni_TargetStructure
// --------
set udg_Omni_Caster__Array[index] = udg_Omni_Caster
set udg_Omni_Target__Array[index] = udg_Omni_Target
set udg_Omni_Group__Array[index] = udg_Omni_Group
set udg_Omni_Interval__Array[index] = udg_Omni_Interval
set udg_Omni_Duration__Array[index] = udg_Omni_Duration
set udg_Omni_Damage__Array[index] = udg_Omni_Damage
set udg_Omni_Count__Array[index] = udg_Omni_Count
set udg_Omni_Range__Array[udg_Omni_Current] = udg_Omni_Range
// --------
set udg_Omni_OnSlashStart__Array[index] = udg_Omni_OnSlashStart
set udg_Omni_OnSlashEvent__Array[index] = udg_Omni_OnSlashEvent
set udg_Omni_OnSlashEnd__Array[index] = udg_Omni_OnSlashEnd
endfunction
function Omni_Reset takes integer index returns nothing
set udg_Omni_Index = index
call Omni_Adopt()
endfunction
function Omni_Timer_Reset takes nothing returns nothing
local integer lastCount = udg_Omni_Count
local boolean lastWrite = udg_Omni_DoPersistibleWrite
local real lastDur = udg_Omni_Duration
local real elapsed = TimerGetElapsed(udg_Omni_Timer)
local real timeout = TimerGetTimeout(udg_Omni_Timer)
set udg_Omni_DoPersistibleWrite = true
set udg_Omni_Duration = 1000000000.00
set udg_Omni_Count = udg_Omni_Next[0]
loop
exitwhen udg_Omni_Count == 0
if not udg_Omni_Timer_Expired then
set udg_Omni_Duration__Array[udg_Omni_Count] = RMaxBJ(udg_Omni_Duration__Array[udg_Omni_Count] - elapsed, 0.)
endif
set udg_Omni_Duration = RMinBJ(udg_Omni_Duration, udg_Omni_Duration__Array[udg_Omni_Count])
set udg_Omni_Count = udg_Omni_Next[udg_Omni_Count]
endloop
if ( not udg_Omni_Timer_Expired ) then
set udg_Omni_Duration = RMinBJ(udg_Omni_Duration, TimerGetRemaining(udg_Omni_Timer))
endif
call PauseTimer( udg_Omni_Timer )
call TimerStart( udg_Omni_Timer, udg_Omni_Duration, false, null )
set udg_Omni_Duration = lastDur
set udg_Omni_Count = lastCount
set udg_Omni_DoPersistibleWrite = lastWrite
endfunction
function Omni_Destroy takes integer h returns nothing
if h <= 0 then
return
endif
if (not udg_OMNI_MULTI_UNIT_INSTANCEABLE) then
call RemoveSavedInteger(udg_Omni_HASH, 1, GetHandleId(udg_Omni_Caster))
endif
// --------
call Omni_Reset(0)
// --------
call Omni_Inverse_Adopt(h)
// --------
set udg_Omni_Next[udg_Omni_Prev[h]] = udg_Omni_Next[h]
set udg_Omni_Prev[udg_Omni_Next[h]] = udg_Omni_Prev[h]
call Omni_Dealloc(h)
endfunction
function Omni_Create takes nothing returns integer
local boolean lastWrite = udg_Omni_DoPersistibleWrite
if not udg_Omni_Initialized then
call TriggerExecute( gg_trg_Omni_Initialisation )
endif
if (not udg_OMNI_MULTI_UNIT_INSTANCEABLE) and (LoadInteger(udg_Omni_HASH, 1, GetHandleId(udg_Omni_Caster)) != 0) then
return 0
endif
set udg_Omni_Current = Omni_Alloc()
if (not udg_OMNI_MULTI_UNIT_INSTANCEABLE) then
call SaveInteger(udg_Omni_HASH, 1, GetHandleId(udg_Omni_Caster), udg_Omni_Current)
endif
set udg_Omni_DoPersistibleWrite = true
set udg_Omni_Interval = RMaxBJ(udg_Omni_Interval, 0.00)
set udg_Omni_Duration = 0.
set udg_Omni_Count = IMaxBJ(udg_Omni_Count, 1)
set udg_Omni_Range = RMaxBJ(udg_Omni_Range, 0.00)
set udg_Omni_DoPersistibleWrite = lastWrite
// Inlined Omni-Push
set udg_Omni_Next[udg_Omni_Current] = 0
set udg_Omni_Prev[udg_Omni_Current] = udg_Omni_Prev[0]
set udg_Omni_Next[udg_Omni_Prev[udg_Omni_Current]] = udg_Omni_Current
set udg_Omni_Prev[udg_Omni_Next[udg_Omni_Current]] = udg_Omni_Current
call Omni_Inverse_Adopt(udg_Omni_Current)
call TriggerExecute(udg_Omni_OnSlashStart )
if ( udg_Omni_Instance_Count > 1 ) then
call PauseTimer(udg_Omni_Timer)
call Omni_Timer_Reset()
endif
if not udg_Omni_Timer_Expired then
call TimerStart(udg_Omni_Timer, 0.0, false, null)
endif
call Omni_Reset(0)
return udg_Omni_Current
endfunction
// ====================================== //
// End Omnislash System //
// ====================================== //
Name | Type | is_array | initial_value |
Omni_AffectAir | boolean | No | |
Omni_AffectAir_Flag | boolean | Yes | |
Omni_AffectMagicImmune | boolean | No | |
Omni_AffectMagicImmune_Flag | boolean | Yes | |
Omni_Alloc | integer | Yes | |
Omni_Caster | unit | No | |
Omni_Caster__Array | unit | Yes | |
Omni_CheckAllies | boolean | No | |
Omni_CheckAllies__Flag | boolean | Yes | |
Omni_CheckEnemies | boolean | No | true |
Omni_CheckEnemies__Flag | boolean | Yes | |
Omni_CheckRange | boolean | No | |
Omni_CheckRange__Flag | boolean | Yes | |
Omni_ContinueWhenDead | boolean | No | |
Omni_ContinueWhenDead_Flag | boolean | Yes | |
Omni_Count | integer | No | |
Omni_Count__Array | integer | Yes | |
Omni_Current | integer | No | |
Omni_Damage | real | No | |
Omni_Damage__Array | real | Yes | |
Omni_DoPersistibleWrite | boolean | No | |
Omni_Duration | real | No | |
Omni_Duration__Array | real | Yes | |
Omni_Group | group | No | |
Omni_Group__Array | group | Yes | |
Omni_HASH | hashtable | No | |
Omni_Index | integer | No | |
Omni_Initialized | boolean | No | |
Omni_Instance_Count | integer | No | |
Omni_Interval | real | No | |
Omni_Interval__Array | real | Yes | |
Omni_InvulCount | integer | No | |
OMNI_INVULNERABLE_FLAG | boolean | No | |
Omni_Jug_Fx | effect | Yes | |
OMNI_MULTI_UNIT_INSTANCEABLE | boolean | No | |
Omni_NewThis | integer | No | |
Omni_Next | integer | Yes | |
Omni_OnSlashEnd | trigger | No | |
Omni_OnSlashEnd__Array | trigger | Yes | |
Omni_OnSlashEvent | trigger | No | |
Omni_OnSlashEvent__Array | trigger | Yes | |
Omni_OnSlashStart | trigger | No | |
Omni_OnSlashStart__Array | trigger | Yes | |
Omni_Prev | integer | Yes | |
Omni_Range | real | No | |
Omni_Range__Array | real | Yes | |
Omni_StopWhenRooted | boolean | No | |
Omni_StopWhenRooted_Flag | boolean | Yes | |
Omni_Target | unit | No | |
Omni_Target__Array | unit | Yes | |
Omni_Target_WasDefined__Array | boolean | Yes | |
Omni_TargetDead | boolean | No | |
Omni_TargetDead__Flag | boolean | Yes | |
Omni_TargetHidden | boolean | No | |
Omni_TargetHidden_Flag | boolean | Yes | |
Omni_TargetInvul | boolean | No | |
Omni_TargetInvul_Flag | boolean | Yes | |
Omni_TargetStructure | boolean | No | |
Omni_TargetStructure_Flag | boolean | Yes | |
Omni_TempLoc | location | No | |
Omni_Timer | timer | No | |
Omni_Timer_Expired | boolean | No | |
Omni_UnitToHandle | handle | No | |
Respawn_Unit | unit | No | |
Respawn_UnitType | unitcode | No |
//! novjass
Note: All triggers included within the Omnislash System are reserved to the System, excluding the
following:
- Omni Create
The system does not assume many things, which eases on the performance, a necessary trade-off
for the JASS System doing all the work. That being said, you, as a user, are obliged to supply
the necessary information when using this system, which are enumerated as follows:
udg_Omni_Caster - The slasher unit.
udg_Omni_Range - The range of enumeration
udg_Omni_Interval - The interval between each slash
udg_Omni_Count - The number of slashes the slasher can do.
udg_Omni_Damage - The damage dealt by the slasher.
Additional variables may be optionally defined within your scope of usage, such as the following:
(Variables with a given definition are those whose purpose is somewhat vague/unclear).
udg_Omni_Target - The currently slashed target.
udg_Omni_AffectAir - If true, targets air units
udg_Omni_AffectMagicImmune - If true, targets magic immune units
udg_Omni_ContinueWhenDead - If true, forces the slasher to keep on slashing even when he/she is dead.
udg_Omni_CheckAllies - If true, checks allies when enumerating
udg_Omni_CheckEnemies - If true, checks enemies when enumerating
udg_Omni_StopWhenRooted - If true, forces the slasher to stop slashing when captured.
udg_Omni_TargetInvul - If true, targets invulnerable units
udg_Omni_TargetHidden - If true. targets both hidden and invisible units
udg_Omni_TargetDead - If true, targets dead units
udg_Omni_TargetStructure - If true, targets structures
These variables can optionally be declared when making an omnislash instance, since you can easily
define the next target of your choice. The system will automatically detect units when you don't
specify the next target.
In addition, the following variables may not be overwritten (for a given omnislash instance
or globally) once defined. (to ensure that the system runs smoothly and logically).
udg_Omni_Caster - Can be used instead as a read-only variable
udg_Omni_Group - Same as udg_Omni_Caster
udg_Omni_DoPersistibleWrite - If set to true, the assignment of udg_Omni_Duration will
be interpreted as that being done by the system.
This could result into unintended behavior from the user's
end.
udg_OMNI_INVULNERABLE_FLAG - This is to be treated as a constant boolean variable.
What it does is ensure that inflicting omnislash damage to
invulnerable units will work.
Since the function returns different values for versions
1.29 and 1.30+, this was intended as a way to easily resolve
potentially game-breaking bugs.
For versions 1.29+, the value is false.
For versions 1.30+, the value is true.
udg_MULTI_UNIT_INSTANCEABLE - This allows the system to introduce more omnislash instances
to ANY unit as slashers. This is an optional feature, meaning
that if you desire to have it so, you can set it to true.
By default, this is true.
If you feel like there is something missing in the documentation, do leave some comments
as the author considers the input of the users of this system, of which the author is also
a user as well.
Enjoy!
//! endnovjass
// ᶝ===================================== //
// Start Omnislash System //
// ====================================== //
function Omni_Alloc takes nothing returns integer
set udg_Omni_NewThis = udg_Omni_Alloc[0]
if (udg_Omni_Alloc[udg_Omni_NewThis] == -1) or (udg_Omni_NewThis == 0) then
set udg_Omni_NewThis = ( udg_Omni_NewThis + 1 )
set udg_Omni_Alloc[0] = udg_Omni_NewThis
else
set udg_Omni_Alloc[0] = udg_Omni_Alloc[udg_Omni_NewThis]
endif
set udg_Omni_Instance_Count = udg_Omni_Instance_Count + 1
set udg_Omni_Alloc[udg_Omni_NewThis] = -1
return udg_Omni_NewThis
endfunction
function Omni_Dealloc takes integer index returns nothing
if ( udg_Omni_Alloc[index] != -1 ) then
return
endif
set udg_Omni_Alloc[index] = udg_Omni_Alloc[0]
set udg_Omni_Alloc[0] = udg_Omni_Current
set udg_Omni_Instance_Count = ( udg_Omni_Instance_Count - 1 )
endfunction
// member to class
function Omni_Adopt takes nothing returns nothing
local boolean lastWrite = udg_Omni_DoPersistibleWrite
set udg_Omni_DoPersistibleWrite = true
set udg_Omni_AffectAir = udg_Omni_AffectAir_Flag[udg_Omni_Index]
set udg_Omni_AffectMagicImmune = udg_Omni_AffectMagicImmune_Flag[udg_Omni_Index]
set udg_Omni_ContinueWhenDead = udg_Omni_ContinueWhenDead_Flag[udg_Omni_Index]
set udg_Omni_CheckAllies = udg_Omni_CheckAllies__Flag[udg_Omni_Index]
set udg_Omni_CheckEnemies = udg_Omni_CheckEnemies__Flag[udg_Omni_Index]
set udg_Omni_CheckRange = udg_Omni_CheckRange__Flag[udg_Omni_Index]
set udg_Omni_StopWhenRooted = udg_Omni_StopWhenRooted_Flag[udg_Omni_Index]
set udg_Omni_TargetDead = udg_Omni_TargetDead__Flag[udg_Omni_Index]
set udg_Omni_TargetHidden = udg_Omni_TargetHidden_Flag[udg_Omni_Index]
set udg_Omni_TargetInvul = udg_Omni_TargetInvul_Flag[udg_Omni_Index]
set udg_Omni_TargetStructure = udg_Omni_TargetStructure_Flag[udg_Omni_Index]
// --------
set udg_Omni_Caster = udg_Omni_Caster__Array[udg_Omni_Index]
set udg_Omni_Target = udg_Omni_Target__Array[udg_Omni_Index]
set udg_Omni_Group = udg_Omni_Group__Array[udg_Omni_Index]
set udg_Omni_Interval = udg_Omni_Interval__Array[udg_Omni_Index]
set udg_Omni_Duration = udg_Omni_Duration__Array[udg_Omni_Index]
set udg_Omni_Damage = udg_Omni_Damage__Array[udg_Omni_Index]
set udg_Omni_Count = udg_Omni_Count__Array[udg_Omni_Index]
set udg_Omni_Range = udg_Omni_Range__Array[udg_Omni_Index]
// --------
set udg_Omni_OnSlashStart = udg_Omni_OnSlashStart__Array[udg_Omni_Index]
set udg_Omni_OnSlashEvent = udg_Omni_OnSlashEvent__Array[udg_Omni_Index]
set udg_Omni_OnSlashEnd = udg_Omni_OnSlashEnd__Array[udg_Omni_Index]
set udg_Omni_DoPersistibleWrite = lastWrite
endfunction
// class to member
function Omni_Inverse_Adopt takes integer index returns nothing
set udg_Omni_AffectAir_Flag[index] = udg_Omni_AffectAir
set udg_Omni_AffectMagicImmune_Flag[index] = udg_Omni_AffectMagicImmune
set udg_Omni_ContinueWhenDead_Flag[index] = udg_Omni_ContinueWhenDead
set udg_Omni_CheckAllies__Flag[index] = udg_Omni_CheckAllies
set udg_Omni_CheckEnemies__Flag[index] = udg_Omni_CheckEnemies
set udg_Omni_CheckRange__Flag[index] = udg_Omni_CheckRange
set udg_Omni_StopWhenRooted_Flag[index] = udg_Omni_StopWhenRooted
set udg_Omni_TargetDead__Flag[index] = udg_Omni_TargetDead
set udg_Omni_TargetHidden_Flag[index] = udg_Omni_TargetHidden
set udg_Omni_TargetInvul_Flag[index] = udg_Omni_TargetInvul
set udg_Omni_TargetStructure_Flag[index] = udg_Omni_TargetStructure
// --------
set udg_Omni_Caster__Array[index] = udg_Omni_Caster
set udg_Omni_Target__Array[index] = udg_Omni_Target
set udg_Omni_Group__Array[index] = udg_Omni_Group
set udg_Omni_Interval__Array[index] = udg_Omni_Interval
set udg_Omni_Duration__Array[index] = udg_Omni_Duration
set udg_Omni_Damage__Array[index] = udg_Omni_Damage
set udg_Omni_Count__Array[index] = udg_Omni_Count
set udg_Omni_Range__Array[udg_Omni_Current] = udg_Omni_Range
// --------
set udg_Omni_OnSlashStart__Array[index] = udg_Omni_OnSlashStart
set udg_Omni_OnSlashEvent__Array[index] = udg_Omni_OnSlashEvent
set udg_Omni_OnSlashEnd__Array[index] = udg_Omni_OnSlashEnd
endfunction
function Omni_Reset takes integer index returns nothing
set udg_Omni_Index = index
call Omni_Adopt()
endfunction
function Omni_Timer_Reset takes nothing returns nothing
local integer lastCount = udg_Omni_Count
local boolean lastWrite = udg_Omni_DoPersistibleWrite
local real lastDur = udg_Omni_Duration
local real elapsed = TimerGetElapsed(udg_Omni_Timer)
local real timeout = TimerGetTimeout(udg_Omni_Timer)
set udg_Omni_DoPersistibleWrite = true
set udg_Omni_Duration = 1000000000.00
set udg_Omni_Count = udg_Omni_Next[0]
loop
exitwhen udg_Omni_Count == 0
if not udg_Omni_Timer_Expired then
set udg_Omni_Duration__Array[udg_Omni_Count] = RMaxBJ(udg_Omni_Duration__Array[udg_Omni_Count] - elapsed, 0.)
endif
set udg_Omni_Duration = RMinBJ(udg_Omni_Duration, udg_Omni_Duration__Array[udg_Omni_Count])
set udg_Omni_Count = udg_Omni_Next[udg_Omni_Count]
endloop
if ( not udg_Omni_Timer_Expired ) then
set udg_Omni_Duration = RMinBJ(udg_Omni_Duration, TimerGetRemaining(udg_Omni_Timer))
endif
call PauseTimer( udg_Omni_Timer )
call TimerStart( udg_Omni_Timer, udg_Omni_Duration, false, null )
set udg_Omni_Duration = lastDur
set udg_Omni_Count = lastCount
set udg_Omni_DoPersistibleWrite = lastWrite
endfunction
function Omni_Destroy takes integer h returns nothing
if h <= 0 then
return
endif
if (not udg_OMNI_MULTI_UNIT_INSTANCEABLE) then
call RemoveSavedInteger(udg_Omni_HASH, 1, GetHandleId(udg_Omni_Caster))
endif
// --------
call Omni_Reset(0)
// --------
call Omni_Inverse_Adopt(h)
// --------
set udg_Omni_Next[udg_Omni_Prev[h]] = udg_Omni_Next[h]
set udg_Omni_Prev[udg_Omni_Next[h]] = udg_Omni_Prev[h]
call Omni_Dealloc(h)
endfunction
function Omni_Create takes nothing returns integer
local boolean lastWrite = udg_Omni_DoPersistibleWrite
if not udg_Omni_Initialized then
call TriggerExecute( gg_trg_Omni_Initialisation )
endif
if (not udg_OMNI_MULTI_UNIT_INSTANCEABLE) and (LoadInteger(udg_Omni_HASH, 1, GetHandleId(udg_Omni_Caster)) != 0) then
return 0
endif
set udg_Omni_Current = Omni_Alloc()
if (not udg_OMNI_MULTI_UNIT_INSTANCEABLE) then
call SaveInteger(udg_Omni_HASH, 1, GetHandleId(udg_Omni_Caster), udg_Omni_Current)
endif
set udg_Omni_DoPersistibleWrite = true
set udg_Omni_Interval = RMaxBJ(udg_Omni_Interval, 0.00)
set udg_Omni_Duration = 0.
set udg_Omni_Count = IMaxBJ(udg_Omni_Count, 1)
set udg_Omni_Range = RMaxBJ(udg_Omni_Range, 0.00)
set udg_Omni_DoPersistibleWrite = lastWrite
// Inlined Omni-Push
set udg_Omni_Next[udg_Omni_Current] = 0
set udg_Omni_Prev[udg_Omni_Current] = udg_Omni_Prev[0]
set udg_Omni_Next[udg_Omni_Prev[udg_Omni_Current]] = udg_Omni_Current
set udg_Omni_Prev[udg_Omni_Next[udg_Omni_Current]] = udg_Omni_Current
call Omni_Inverse_Adopt(udg_Omni_Current)
call TriggerExecute(udg_Omni_OnSlashStart )
if ( udg_Omni_Instance_Count > 1 ) then
call PauseTimer(udg_Omni_Timer)
call Omni_Timer_Reset()
endif
if not udg_Omni_Timer_Expired then
call TimerStart(udg_Omni_Timer, 0.0, false, null)
endif
call Omni_Reset(0)
return udg_Omni_Current
endfunction
// ====================================== //
// End Omnislash System //
// ====================================== //
function Omni_Group_Filter_Default takes unit u returns boolean
if (not udg_Omni_AffectAir and IsUnitType(u, UNIT_TYPE_FLYING)) then
return false
endif
if (not udg_Omni_AffectMagicImmune and IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE)) then
return false
endif
if (not udg_Omni_CheckAllies and IsUnitAlly(u, GetOwningPlayer(udg_Omni_Caster__Array[udg_Omni_Current]))) then
return false
endif
if (not udg_Omni_CheckEnemies and IsUnitEnemy(u, GetOwningPlayer(udg_Omni_Caster__Array[udg_Omni_Current]))) then
return false
endif
if (not udg_Omni_TargetDead) and GetWidgetLife(u) < 0.405 then
return false
endif
if (not udg_Omni_TargetHidden) and (IsUnitInvisible(u, GetOwningPlayer(udg_Omni_Caster__Array[udg_Omni_Current])) or IsUnitHidden(u)) then
return false
endif
if (not udg_Omni_TargetInvul) and ( BlzIsUnitInvulnerable(u) == udg_OMNI_INVULNERABLE_FLAG ) then
return false
endif
if (not udg_Omni_TargetStructure) and IsUnitType(u, UNIT_TYPE_STRUCTURE) then
return false
endif
if (udg_Omni_CheckRange and not IsUnitInRange(u, udg_Omni_Caster__Array[udg_Omni_Current], udg_Omni_Range)) then
return false
endif
return true
endfunction
function Omni_Group_Filter takes nothing returns nothing
local unit tempUnit = udg_Omni_Caster
local group g = CreateGroup()
if IsUnitInGroup(udg_Omni_Caster, udg_Omni_Group) then
call GroupRemoveUnit( udg_Omni_Group, udg_Omni_Caster)
endif
loop
set udg_Omni_Caster = FirstOfGroup(udg_Omni_Group)
exitwhen udg_Omni_Caster == null
if Omni_Group_Filter_Default(udg_Omni_Caster) then
call GroupAddUnit(g, udg_Omni_Caster)
endif
call GroupRemoveUnit( udg_Omni_Group, udg_Omni_Caster)
endloop
// --------
call DestroyGroup(udg_Omni_Group)
// --------
set udg_Omni_Caster = tempUnit
set udg_Omni_Group = g
set udg_Omni_Group__Array[udg_Omni_Current] = g
set g = null
set tempUnit = null
endfunction
function Omni_InflictDamage takes unit trueTarget returns nothing
if (udg_Omni_Damage >= 0.00) and (BlzIsUnitInvulnerable(trueTarget) != udg_OMNI_INVULNERABLE_FLAG) then
call UnitDamageTarget( udg_Omni_Caster, trueTarget, udg_Omni_Damage, false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNKNOWN, WEAPON_TYPE_WHOKNOWS )
else
call SetWidgetLife(trueTarget, GetWidgetLife(trueTarget) - udg_Omni_Damage)
endif
endfunction
function Omni_Group_Search takes real leastDur returns real
// --------
// Test the existence of the group
// --------
call GroupAddUnit(udg_Omni_Group, udg_Omni_Caster)
if not IsUnitInGroup(udg_Omni_Caster, udg_Omni_Group) then
// --------
// The group does not exist
// --------
set udg_Omni_Group = CreateGroup()
call MoveLocation(udg_Omni_TempLoc, GetUnitX(udg_Omni_Caster), GetUnitY(udg_Omni_Caster))
call GroupEnumUnitsInRangeOfLoc(udg_Omni_Group, udg_Omni_TempLoc, udg_Omni_Range, null)
call Omni_Group_Filter()
// --------
set udg_Omni_Target = FirstOfGroup(udg_Omni_Group)
call Omni_Inverse_Adopt(udg_Omni_Current)
set leastDur = RMinBJ(leastDur, RMaxBJ(udg_Omni_Duration, 0.))
// --------
else
// --------
// The group exists
// --------
call GroupRemoveUnit(udg_Omni_Group, udg_Omni_Caster)
set udg_Omni_Target = GroupPickRandomUnit(udg_Omni_Group)
// --------
// Test if any valid unit exists
// --------
call MoveLocation(udg_Omni_TempLoc, GetUnitX(udg_Omni_Caster), GetUnitY(udg_Omni_Caster))
if udg_Omni_Target == null then
// --------
// No valid unit exists in the group, enumerate again
// --------
call GroupEnumUnitsInRangeOfLoc(udg_Omni_Group, udg_Omni_TempLoc, udg_Omni_Range, null)
call Omni_Group_Filter()
// --------
set udg_Omni_Target = FirstOfGroup(udg_Omni_Group)
call Omni_Inverse_Adopt(udg_Omni_Current)
set leastDur = RMinBJ(leastDur, RMaxBJ(udg_Omni_Duration, 0.))
// --------
else
// --------
call Omni_Group_Filter()
if (not IsUnitInGroup(udg_Omni_Target, udg_Omni_Group)) and (FirstOfGroup(udg_Omni_Group) != null) then
set udg_Omni_Target = FirstOfGroup(udg_Omni_Group)
endif
call Omni_Inverse_Adopt(udg_Omni_Current)
set leastDur = RMinBJ(leastDur, RMaxBJ(udg_Omni_Duration, 0.))
endif
endif
return leastDur
endfunction
function Trig_Omni_Timer_Expiration_Actions takes nothing returns nothing
local real leastDur = 100000000.
local real lastIntvl = 0.
local real timeout = TimerGetTimeout(udg_Omni_Timer)
local boolean lastWrite = udg_Omni_DoPersistibleWrite
local boolean enumDone = false
local boolean wasStopped = false
local unit tempTarget = null
set udg_Omni_Timer_Expired = true
set udg_Omni_Current = udg_Omni_Next[0]
loop
exitwhen udg_Omni_Current == 0
set udg_Omni_Duration__Array[udg_Omni_Current] = ( udg_Omni_Duration__Array[udg_Omni_Current] - timeout )
// Check if the instance is to be executed
if udg_Omni_Duration__Array[udg_Omni_Current] <= (0.0001) then
set udg_Omni_Count__Array[udg_Omni_Current] = ( udg_Omni_Count__Array[udg_Omni_Current] - 1 )
// Assign the values from the array variables to the static variables
set udg_Omni_Index = udg_Omni_Current
call Omni_Adopt()
if ( udg_Omni_Count < 0 ) or ((not udg_Omni_ContinueWhenDead) and GetWidgetLife(udg_Omni_Caster) < 0.405) or (udg_Omni_StopWhenRooted and IsUnitType(udg_Omni_Caster, UNIT_TYPE_SNARED)) then
// Either the unit is rooted, dead, or slashes are all done. Exit.
set udg_Omni_Target_WasDefined__Array[udg_Omni_Current] = false
call DestroyGroup(udg_Omni_Group)
set udg_Omni_Group = null
call TriggerExecute( udg_Omni_OnSlashEnd )
call Omni_Destroy(udg_Omni_Current)
else
// Remove the target first from the group to ensure unique selection as much as possible. (if automated)
set tempTarget = udg_Omni_Target
set udg_Omni_Target__Array[udg_Omni_Current] = null
call GroupRemoveUnit(udg_Omni_Group, udg_Omni_Target)
// Either the target is not specified or has been removed from the game. Try to scan for a target first.
if not (udg_Omni_Target_WasDefined__Array[udg_Omni_Current]) and (tempTarget == null or (not Omni_Group_Filter_Default(tempTarget))) then
call Omni_Group_Search(leastDur)
set enumDone = true
set tempTarget = udg_Omni_Target
set udg_Omni_Target__Array[udg_Omni_Current] = null
if tempTarget == null then
// No targets left. Exit.
call DestroyGroup(udg_Omni_Group)
set udg_Omni_Group = null
call TriggerExecute( udg_Omni_OnSlashEnd )
call Omni_Destroy(udg_Omni_Current)
set wasStopped = true
endif
endif
set udg_Omni_Target_WasDefined__Array[udg_Omni_Current] = false
if not wasStopped then
// Kept for compatibility purposes
call MoveLocation(udg_Omni_TempLoc, GetUnitX(tempTarget), GetUnitY(tempTarget))
call SetUnitX(udg_Omni_Caster, GetUnitX(tempTarget))
call SetUnitY(udg_Omni_Caster, GetUnitY(tempTarget))
set udg_Omni_DoPersistibleWrite = true
call TriggerExecute( udg_Omni_OnSlashEvent )
// The next target might be damaged instead.
call Omni_InflictDamage(tempTarget)
// If duration is still zero, then it wasn't updated
if udg_Omni_Duration < 0.0001 then
set udg_Omni_Duration = udg_Omni_Interval
else
set udg_Omni_Interval = udg_Omni_Duration
endif
set udg_Omni_DoPersistibleWrite = lastWrite
// --------
// Assume that a target unit was defined in the Omni_SlashEvent trigger
// --------
if (udg_Omni_Target != tempTarget) and (udg_Omni_Target != null) then
// --------
// Ignore the filters set in place for the instance
// --------
set leastDur = RMinBJ(leastDur, RMaxBJ(udg_Omni_Duration, 0.))
// --------
set udg_Omni_Target_WasDefined__Array[udg_Omni_Current] = true
call Omni_Inverse_Adopt(udg_Omni_Current)
else
if not enumDone then
set leastDur = Omni_Group_Search(leastDur)
endif
// No target located during Omni_Group_Search. Exit.
if (udg_Omni_Target == null) or (udg_Omni_Count <= 0) then
call DestroyGroup(udg_Omni_Group)
set udg_Omni_Group = null
call TriggerExecute( udg_Omni_OnSlashEnd )
call Omni_Destroy(udg_Omni_Current)
else
set leastDur = RMinBJ(leastDur, RMaxBJ(udg_Omni_Duration, 0.))
call Omni_Inverse_Adopt(udg_Omni_Current)
endif
endif
endif
set wasStopped = false
endif
else
set leastDur = RMinBJ(leastDur, RMaxBJ(udg_Omni_Duration__Array[udg_Omni_Current], 0.))
endif
set udg_Omni_Current = udg_Omni_Next[udg_Omni_Current]
endloop
if udg_Omni_Instance_Count > 0 then
set lastIntvl = udg_Omni_Interval
set udg_Omni_Interval = leastDur
call TimerStart( udg_Omni_Timer, udg_Omni_Interval, false, null)
set udg_Omni_Interval = lastIntvl
endif
call Omni_Reset(0)
set tempTarget = null
set udg_Omni_Timer_Expired = false
endfunction
//===========================================================================
function InitTrig_Omni_Timer_Expiration takes nothing returns nothing
set gg_trg_Omni_Timer_Expiration = CreateTrigger( )
call TriggerRegisterTimerExpireEvent( gg_trg_Omni_Timer_Expiration, udg_Omni_Timer )
call TriggerAddAction( gg_trg_Omni_Timer_Expiration, function Trig_Omni_Timer_Expiration_Actions )
endfunction
function Trig_Omni_Create_Actions takes nothing returns nothing
call Omni_Create()
endfunction
//===========================================================================
function InitTrig_Omni_Create takes nothing returns nothing
set gg_trg_Omni_Create = CreateTrigger( )
call DisableTrigger( gg_trg_Omni_Create )
call TriggerAddAction( gg_trg_Omni_Create, function Trig_Omni_Create_Actions )
endfunction