Hi, this is a stun system that I made for my map. I posted it here to hopefully get some feedback from you guys
There are many things to improve for sure.
functions:
StunUnit(unit u, real time, integer type, string animation)
Stun types can be:
- STUN_TYPE_NORMAL // Will apply the "better" stun. That means if the current stun will disappear in 1 second and a new stun would stun for 2 seconds, it will take the 2 seconds
- STUN_TYPE_COVER // Will always overwrite the current stun, no matter which is "better"
- STUN_TYPE_STACK // Will add the stun time to the currently existing stun
- STUN_TYPE_ULTIMATE // Will always overwrite any stun and cannot get overwritten by any stun (except for other stuns by this type), it also cannot be reduced by the stun reduction
RemoveStun(unit u) // removes the stun, does not work for STUN_TYPE_ULTIMATE
IsUnitStunned(unit u) // returns boolean
AddStunReduction(unit u, real value) // Adds a percentage stun reduction, that means that stuns will last for value% shorter/longer. (Does not work on STUN_TYPE_ULTIAMTE)
AddStunReductionTimed(unit u, real value, real time) // Same as before, just timed
I hope you can give me tips on how to improve it
functions:
StunUnit(unit u, real time, integer type, string animation)
Stun types can be:
- STUN_TYPE_NORMAL // Will apply the "better" stun. That means if the current stun will disappear in 1 second and a new stun would stun for 2 seconds, it will take the 2 seconds
- STUN_TYPE_COVER // Will always overwrite the current stun, no matter which is "better"
- STUN_TYPE_STACK // Will add the stun time to the currently existing stun
- STUN_TYPE_ULTIMATE // Will always overwrite any stun and cannot get overwritten by any stun (except for other stuns by this type), it also cannot be reduced by the stun reduction
RemoveStun(unit u) // removes the stun, does not work for STUN_TYPE_ULTIMATE
IsUnitStunned(unit u) // returns boolean
AddStunReduction(unit u, real value) // Adds a percentage stun reduction, that means that stuns will last for value% shorter/longer. (Does not work on STUN_TYPE_ULTIAMTE)
AddStunReductionTimed(unit u, real value, real time) // Same as before, just timed
I hope you can give me tips on how to improve it
JASS:
library StunSystem initializer Init requires TimerUtils, RegisterPlayerUnitEvent
globals
constant integer STUN_TYPE_NORMAL = 0
constant integer STUN_TYPE_COVER = 1
constant integer STUN_TYPE_STACK = 2
constant integer STUN_TYPE_ULTIMATE = 3
constant string STUN_EFFECT = "Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl"
private boolean array IsUnitAffectedByUlt
private unit array StunnedUnit
private real array StunDuration
private effect array StunEffect
private unit array ReductionUnit
private real array ReductionDuration
private real array Reduction
private real array ReductionValue
private integer Index = 0
private unit Dummy
endglobals
private function ClearStun takes unit u returns nothing
local integer id = GetUnitUserData(u)
call UnitRemoveAbility(u, 'Bstn')
set StunDuration[id] = 0
call DestroyEffect(StunEffect[id])
set StunEffect[id] = null
set IsUnitAffectedByUlt[id] = false
endfunction
private function OnDeath takes nothing returns boolean
call ClearStun(GetTriggerUnit())
return false
endfunction
function RemoveStun takes unit u returns nothing
if IsUnitAffectedByUlt[GetUnitUserData(u)] == false then
call ClearStun(u)
endif
endfunction
function IsUnitStunned takes unit u returns boolean
if StunDuration[GetUnitUserData(u)] > 0 then
return true
else
return false
endif
endfunction
function AddStunReduction takes unit u, real r returns nothing
local integer id = GetUnitUserData(u)
set Reduction[id] = Reduction[id] + r
endfunction
private function StunReductionTimed takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer loopIndex = 1
loop
exitwhen loopIndex > Index
set ReductionDuration[loopIndex] = ReductionDuration[loopIndex] - 0.05
if ReductionDuration[loopIndex] <= 0 then
call AddStunReduction(ReductionUnit[loopIndex], ReductionValue[loopIndex])
set ReductionUnit[loopIndex] = ReductionUnit[Index]
set ReductionUnit[Index] = null
set ReductionValue[loopIndex] = ReductionValue[Index]
set ReductionDuration[loopIndex] = ReductionDuration[Index]
set Index = Index - 1
set loopIndex = loopIndex - 1
if Index == 0 then
call ReleaseTimer(t)
endif
endif
set loopIndex = loopIndex + 1
endloop
set t = null
endfunction
function AddStunReductionTimed takes unit u, real r, real t returns nothing
call AddStunReduction(u, r)
set Index = Index + 1
set ReductionUnit[Index] = u
set ReductionValue[Index] = -r
set ReductionDuration[Index] = t
if Index == 1 then
call TimerStart(NewTimer(), 0.05, true, function StunReductionTimed)
endif
endfunction
private function StunTimed takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetTimerData(t)
set StunDuration[id] = StunDuration[id] - 0.05
if StunDuration[id] <= 0 then
call ClearStun(StunnedUnit[id])
call ReleaseTimer(t)
endif
set t = null
endfunction
function StunUnit takes unit u, real r, integer i, string s returns nothing
local integer id = GetUnitUserData(u)
local real time
if i != 3 then
if Reduction[id] < 1.00 and IsUnitAffectedByUlt[id] == false then
call SetUnitPosition(Dummy, GetUnitX(u), GetUnitY(u))
call IssueTargetOrder(Dummy, "thunderbolt", u)
set time = r - (r * Reduction[id])
set StunnedUnit[id] = u
if StunDuration[id] <= 0 then
call TimerStart(NewTimerEx(id), 0.05, true, function StunTimed)
endif
if i == 1 then
call ClearStun(u)
set StunDuration[id] = time
set StunEffect[id] = AddSpecialEffectTarget(s, u, "overhead")
elseif i == 2 then
set StunDuration[id] = StunDuration[id] + time
else
if StunDuration[id] < time then
call ClearStun(u)
set StunDuration[id] = time
set StunEffect[id] = AddSpecialEffectTarget(s, u, "overhead")
endif
endif
endif
else
call ClearStun(u)
set StunEffect[id] = AddSpecialEffectTarget(s, u, "overhead")
call SetUnitPosition(Dummy, GetUnitX(u), GetUnitY(u))
call IssueTargetOrder(Dummy, "thunderbolt", u)
set StunnedUnit[id] = u
set StunDuration[id] = r
set IsUnitAffectedByUlt[id] = true
call TimerStart(NewTimerEx(id), 0.05, true, function StunTimed)
endif
endfunction
private function Init takes nothing returns nothing
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function OnDeath)
set Dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'Ustd', 0, 0, 0.00)
endfunction
endlibrary