Name | Type | is_array | initial_value |
library CreepRespawn initializer onInit /* v3.0.2
*************************************************************************************
*
* A simple Creep Respawn System tailored for RPG maps. It does not requires
* SetUnitUserData and GetUnitUserData. As a result, it is compatible with any
* existing unit indexer.
*
*************************************************************************************
*
* */ requires /*
*
* */ CTL /* https://github.com/nestharus/JASS/blob/master/jass/Systems/ConstantTimerLoop32/script.j
*
*
* */ optional /*
*
* */ RegisterPlayerUnitEvent /* https://www.hiveworkshop.com/threads/snippet-registerevent-pack.250266/
*
*
*************************************************************************************
*
* NOTE: If you’re using an older version of Warcraft 3, change the values of
* trn.red, trn.green, trn.blue, and trn.alphaMax to 255. The drawback is
* that you can't save and load the RGB color of the creep.
*/
//! textmacro CREEP_RESPAWN_TRANSPARENCY
set trn.red = BlzGetUnitIntegerField(I[creepIndex], UNIT_IF_TINTING_COLOR_RED)
set trn.green = BlzGetUnitIntegerField(I[creepIndex], UNIT_IF_TINTING_COLOR_GREEN)
set trn.blue = BlzGetUnitIntegerField(I[creepIndex], UNIT_IF_TINTING_COLOR_BLUE)
set trn.alphaMax = BlzGetUnitIntegerField(I[creepIndex], UNIT_IF_TINTING_COLOR_ALPHA)
//! endtextmacro
/************************************************************************************
*
* Configurations
*
************************************************************************************/
globals
// Owner
private constant player CREEP_OWNER = Player(PLAYER_NEUTRAL_AGGRESSIVE)
// Revive Special Effect
private constant string REVIVE_EFFECT = "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl"
// Mini Boss and Boss Detector
private constant integer CREEP_BOSS_DETECTOR = 'A000'
private constant integer CREEP_MINI_BOSS_DETECTOR = 'A001'
// Creep Revival Durations
private constant real CREEP_DEFAULT_RESPAWN_DURATION = 10
private constant real CREEP_BOSS_RESPAWN_DURATION = 30
private constant real CREEP_MINI_BOSS_RESPAWN_DURATION = 15
// Fade In
private constant boolean ALLOW_FADE_IN = true
private constant integer ALPHA_INCREMENT = 5
/************************************************************************************
*
* API
* ---------
*
* function AddCreepRespawn takes unit whichCreep returns integer
* - Include a unit to the Creep Respawn System. The function returns the Creep
* Index associated with that unit.
*
* function AddCreepRespawnEx takes unit whichCreep, real duration returns integer
* - Include a unit to the Creep Respawn System with a custom duration. The
* function returns the Creep Index associated with that unit.
*
* function SetCreepRespawn takes unit whichCreep, boolean enable returns boolean
* - Toggleable creep respawning. The function returns whether it succeeded or
* failed.
*
*************************************************************************************
*
* Ignore these below.
*
************************************************************************************/
private integer CREEP_INDEXED_COUNT = 0
private real array X // X Coord
private real array Y // Y Coord
private real array F // Unit Facing
private integer array U // Unit Type Id
private real array D // Duration
private unit array I // Creep
private boolean array B // Enable Revival
endglobals
private function getCreepDuration takes unit whichCreep returns real
if GetUnitAbilityLevel(whichCreep, CREEP_BOSS_DETECTOR) > 0 then
return CREEP_BOSS_RESPAWN_DURATION
elseif GetUnitAbilityLevel(whichCreep, CREEP_MINI_BOSS_DETECTOR) > 0 then
return CREEP_MINI_BOSS_RESPAWN_DURATION
else
return CREEP_DEFAULT_RESPAWN_DURATION
endif
endfunction
private function storeCreepData takes unit whichCreep, real duration returns integer
if GetOwningPlayer(whichCreep) == CREEP_OWNER then
set CREEP_INDEXED_COUNT = CREEP_INDEXED_COUNT + 1
set X[CREEP_INDEXED_COUNT] = GetUnitX(whichCreep)
set Y[CREEP_INDEXED_COUNT] = GetUnitY(whichCreep)
set F[CREEP_INDEXED_COUNT] = GetUnitFacing(whichCreep)
set U[CREEP_INDEXED_COUNT] = GetUnitTypeId(whichCreep)
set D[CREEP_INDEXED_COUNT] = duration
set I[CREEP_INDEXED_COUNT] = whichCreep
set B[CREEP_INDEXED_COUNT] = true
call SetUnitUseFood(whichCreep, false)
static if DEBUG_MODE then
debug call AddSpecialEffect("buildings\\other\\CircleOfPower\\CircleOfPower.mdl", X[CREEP_INDEXED_COUNT], Y[CREEP_INDEXED_COUNT])
endif
return CREEP_INDEXED_COUNT
endif
return 0
endfunction
private function findCreepDataIndex takes unit whichCreep returns integer
local integer count = 0
loop
exitwhen count == CREEP_INDEXED_COUNT
set count = count + 1
if I[count] == whichCreep then
return count
endif
endloop
return 0
endfunction
function AddCreepRespawn takes unit whichCreep returns integer
return storeCreepData(whichCreep, getCreepDuration(whichCreep))
endfunction
function AddCreepRespawnEx takes unit whichCreep, real duration returns integer
return storeCreepData(whichCreep, duration)
endfunction
function SetCreepRespawn takes unit whichCreep, boolean enable returns boolean
local integer creepIndex
if GetOwningPlayer(whichCreep) == CREEP_OWNER then
set creepIndex = findCreepDataIndex(whichCreep)
if creepIndex > 0 then
set B[creepIndex] = enable
return true
endif
endif
return false
endfunction
static if ALLOW_FADE_IN then
private struct transparent extends array
integer red
integer blue
integer green
integer alpha
integer alphaMax
unit unit
implement CTLExpire
if this.alpha >= this.alphaMax then
call SetUnitVertexColor(this.unit, this.red, this.green, this.blue, this.alphaMax)
set this.red = 0
set this.blue = 0
set this.green = 0
set this.alpha = 0
set this.alphaMax = 0
set this.unit = null
call this.destroy()
else
set this.alpha = this.alpha + ALPHA_INCREMENT
call SetUnitVertexColor(this.unit, this.red, this.green, this.blue, this.alpha)
endif
implement CTLEnd
endstruct
endif
private struct creepRevival extends array
real duration
integer creepData
integer uId
implement CTL
local real x
local real y
local real f
local integer creepIndex
static if ALLOW_FADE_IN then
local transparent trn
endif
implement CTLExpire
set creepIndex = this.creepData
if B[creepIndex] then
if this.duration <= 0 then
// Retrieve the X and Y coordinates as well as the unit’s facing direction.
set x = X[creepIndex]
set y = Y[creepIndex]
set f = F[creepIndex]
if IsUnitType(I[creepIndex], UNIT_TYPE_HERO) then
// Revive the Creep Hero
call ReviveHero(I[creepIndex], x, y, false)
call DestroyEffect(AddSpecialEffectTarget(REVIVE_EFFECT, I[creepIndex], "origin"))
else
// Substitute the new unit with the old unit.
set I[creepIndex] = CreateUnit(CREEP_OWNER, this.uId, x, y, f)
call DestroyEffect(AddSpecialEffectTarget(REVIVE_EFFECT, I[creepIndex], "origin"))
endif
static if ALLOW_FADE_IN then
set trn = transparent.create()
set trn.unit = I[creepIndex]
set trn.alpha = 0
//! runtextmacro CREEP_RESPAWN_TRANSPARENCY()
call SetUnitVertexColor(trn.unit, trn.red, trn.green, trn.blue, trn.alpha)
endif
// Data cleanup
set this.duration = 0
set this.creepData = 0
set this.uId = 0
call destroy()
else
set this.duration = this.duration - 0.031250000
endif
else
// Creep is no longer revivable.
set this.duration = 0
set this.creepData = 0
set this.uId = 0
call destroy()
endif
implement CTLEnd
endstruct
static if LIBRARY_RegisterPlayerUnitEvent then
private function onDeath takes nothing returns nothing
else
private function onDeath_ takes nothing returns boolean
endif
local unit Creep = GetTriggerUnit()
local integer creepId
local creepRevival this
if GetOwningPlayer(Creep) == CREEP_OWNER then
set creepId = findCreepDataIndex(Creep)
if creepId > 0 then
set this = creepRevival.create()
set this.duration = D[creepId]
set this.uId = U[creepId]
set this.creepData = creepId
endif
endif
set Creep = null
static if not LIBRARY_RegisterPlayerUnitEvent then
return false
endif
endfunction
private function registerCreepData takes nothing returns nothing
call AddCreepRespawn(GetFilterUnit())
endfunction
private function initRegisterCreepData takes nothing returns nothing
// Register all created creeps
call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, CREEP_OWNER, Filter(function registerCreepData))
endfunction
private function onInit takes nothing returns nothing
static if LIBRARY_RegisterPlayerUnitEvent then
call RegisterPlayerUnitEvent(CREEP_OWNER, EVENT_PLAYER_UNIT_DEATH, function onDeath)
else
local trigger trg = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(trg, CREEP_OWNER, EVENT_PLAYER_UNIT_DEATH, null)
call TriggerAddCondition(trg, Filter(function onDeath_))
endif
call initRegisterCreepData()
endfunction
endlibrary
/*****************************************************************************
*
* RegisterNativeEvent v1.1.1.5
* by Bannar
*
* Storage of trigger handles for native events.
*
******************************************************************************
*
* Optional requirements:
*
* Table by Bribe
* hiveworkshop.com/threads/snippet-new-table.188084/
*
******************************************************************************
*
* Important:
*
* Avoid using TriggerSleepAction within functions registered.
* Destroy native event trigger on your own responsibility.
*
******************************************************************************
*
* Core:
*
* function IsNativeEventRegistered takes integer whichIndex, integer whichEvent returns boolean
* Whether index whichIndex has already been attached to event whichEvent.
*
* function RegisterNativeEventTrigger takes integer whichIndex, integer eventId returns boolean
* Registers whichIndex within whichEvent scope and assigns new trigger handle for it.
*
* function GetIndexNativeEventTrigger takes integer whichIndex, integer whichEvent returns trigger
* Retrieves trigger handle for event whichEvent specific to provided index whichIndex.
*
* function GetNativeEventTrigger takes integer whichEvent returns trigger
* Retrieves trigger handle for event whichEvent.
*
*
* Custom events:
*
* function CreateNativeEvent takes nothing returns integer
* Returns unique id for new event and registers it with RegisterNativeEvent.
*
* function RegisterIndexNativeEvent takes integer whichIndex, integer whichEvent, code func returns triggercondition
* Registers new event handler func for event whichEvent specific to index whichIndex.
*
* function RegisterNativeEvent takes integer whichEvent, code func returns triggercondition
* Registers new event handler func for specified event whichEvent.
*
* function UnregisterNativeEventHandler takes integer whichEvent, triggercondition handler returns nothing
* Unregisters specified event handler for event whichEvent. Requires Warcraft 1.30.4+.
*
*****************************************************************************/
library RegisterNativeEvent uses optional Table
globals
private integer eventIndex = 500 // 0-499 reserved for Blizzard native events
endglobals
private module NativeEventInit
private static method onInit takes nothing returns nothing
static if LIBRARY_Table then
set table = TableArray[0x2000]
endif
endmethod
endmodule
private struct NativeEvent extends array
static if LIBRARY_Table then
static TableArray table
else
static hashtable table = InitHashtable()
endif
implement NativeEventInit
endstruct
function IsNativeEventRegistered takes integer whichIndex, integer whichEvent returns boolean
static if LIBRARY_Table then
return NativeEvent.table[whichEvent].trigger.has(whichIndex)
else
return HaveSavedHandle(NativeEvent.table, whichEvent, whichIndex)
endif
endfunction
function RegisterNativeEventTrigger takes integer whichIndex, integer whichEvent returns boolean
if not IsNativeEventRegistered(whichIndex, whichEvent) then
static if LIBRARY_Table then
set NativeEvent.table[whichEvent].trigger[whichIndex] = CreateTrigger()
else
call SaveTriggerHandle(NativeEvent.table, whichEvent, whichIndex, CreateTrigger())
endif
return true
endif
return false
endfunction
function GetIndexNativeEventTrigger takes integer whichIndex, integer whichEvent returns trigger
static if LIBRARY_Table then
return NativeEvent.table[whichEvent].trigger[whichIndex]
else
return LoadTriggerHandle(NativeEvent.table, whichEvent, whichIndex)
endif
endfunction
function GetNativeEventTrigger takes integer whichEvent returns trigger
return GetIndexNativeEventTrigger(bj_MAX_PLAYER_SLOTS, whichEvent)
endfunction
function CreateNativeEvent takes nothing returns integer
local integer eventId = eventIndex
call RegisterNativeEventTrigger(bj_MAX_PLAYER_SLOTS, eventId)
set eventIndex = eventIndex + 1
return eventId
endfunction
function RegisterIndexNativeEvent takes integer whichIndex, integer whichEvent, code func returns triggercondition
call RegisterNativeEventTrigger(whichIndex, whichEvent)
return TriggerAddCondition(GetIndexNativeEventTrigger(whichIndex, whichEvent), Condition(func))
endfunction
function RegisterNativeEvent takes integer whichEvent, code func returns triggercondition
return RegisterIndexNativeEvent(bj_MAX_PLAYER_SLOTS, whichEvent, func)
endfunction
function UnregisterNativeEventHandler takes integer whichEvent, triggercondition handler returns nothing
call TriggerRemoveCondition(GetNativeEventTrigger(whichEvent), handler)
endfunction
endlibrary
/*****************************************************************************
*
* RegisterPlayerUnitEvent v1.0.3.2
* by Bannar
*
* Register version of TriggerRegisterPlayerUnitEvent.
*
* Special thanks to Magtheridon96, Bribe, azlier and BBQ for the original library version.
*
******************************************************************************
*
* Requirements:
*
* RegisterNativeEvent by Bannar
* hiveworkshop.com/threads/snippet-registerevent-pack.250266/
*
******************************************************************************
*
* Functions:
*
* function GetAnyPlayerUnitEventTrigger takes playerunitevent whichEvent returns trigger
* Retrieves trigger handle for playerunitevent whichEvent.
*
* function GetPlayerUnitEventTrigger takes player whichPlayer, playerunitevent whichEvent returns trigger
* Retrieves trigger handle for playerunitevent whichEvent specific to player whichPlayer.
*
* function RegisterAnyPlayerUnitEvent takes playerunitevent whichEvent, code func returns nothing
* Registers generic playerunitevent whichEvent adding code func as callback.
*
* function RegisterPlayerUnitEvent takes player whichPlayer, playerunitevent whichEvent, code func returns nothing
* Registers playerunitevent whichEvent for player whichPlayer adding code func as callback.
*
*****************************************************************************/
library RegisterPlayerUnitEvent requires RegisterNativeEvent
function GetAnyPlayerUnitEventTrigger takes playerunitevent whichEvent returns trigger
return GetNativeEventTrigger(GetHandleId(whichEvent))
endfunction
function GetPlayerUnitEventTrigger takes player whichPlayer, playerunitevent whichEvent returns trigger
return GetIndexNativeEventTrigger(GetPlayerId(whichPlayer), GetHandleId(whichEvent))
endfunction
function RegisterAnyPlayerUnitEvent takes playerunitevent whichEvent, code func returns nothing
local integer eventId = GetHandleId(whichEvent)
local integer index = 0
local trigger t = null
if RegisterNativeEventTrigger(bj_MAX_PLAYER_SLOTS, eventId) then
set t = GetNativeEventTrigger(eventId)
loop
call TriggerRegisterPlayerUnitEvent(t, Player(index), whichEvent, null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
set t = null
endif
call RegisterNativeEvent(eventId, func)
endfunction
function RegisterPlayerUnitEvent takes player whichPlayer, playerunitevent whichEvent, code func returns nothing
local integer playerId = GetPlayerId(whichPlayer)
local integer eventId = GetHandleId(whichEvent)
if RegisterNativeEventTrigger(playerId, eventId) then
call TriggerRegisterPlayerUnitEvent(GetIndexNativeEventTrigger(playerId, eventId), whichPlayer, whichEvent, null)
endif
call RegisterIndexNativeEvent(playerId, eventId, func)
endfunction
endlibrary
library CTL /* v1.2.0.3
*************************************************************************************
*
* CTL or Constant Timer Loop provides a loop for constant merged timers of timeout .03125
*
* Similar to T32 but pauses timer when no structs have instances and removes structs
* from timer trigger when those structs have no instances.
*
* This can also create new timers after destroying a previous timer and generates less
* code in the module. It also generates no triggers so long as the module is implemented
* at the top of the struct.
*
************************************************************************************
*
* module CTL
*
* Allows creation/destruction of timers in a struct. Provides instancing of those timers.
*
* - static method create takes nothing returns thistype
* - method destroy takes nothing returns nothing
*
* CTL (optional)
* local variables, code before running any timers
* CTLExpire (not optional)
* timer code
* CTLNull (optional)
* null any locals, runs after all timers
* CTLEnd (not optional)
*
* module CT32
*
* Converts struct into a timer group. Allows the timer group to be started and stopped.
* Instancing and looping through active timers is up to the user.
*
* - static method start takes nothing returns nothing
* - static method stop takes nothing returns nothing
*
* CT32 (not optional)
* timer code
* CT32End (not optional)
*
* struct TimerGroup32 extends array
*
* Allows for the creation of timer groups. Timer instancing and looping is entirely up
* to the user.
*
* - static method create takes code func returns thistype
* - method destroy takes nothing returns nothing
* - method start takes nothing returns nothing
* - method stop takes nothing returns nothing
*
************************************************************************************/
globals
private integer tgc = 0 //timer group count
private integer array tgr //timer group recycler
private integer ic=0 //instance count
private integer tc=0 //timer count
private integer array rf //root first
private integer array n //next
private integer array p //previous
private integer array th //timer head
private integer array ns //next stack
private trigger t=CreateTrigger()
private timer m=CreateTimer()
private triggercondition array ct
private conditionfunc array rc
private boolean array e32 //enabled
private integer array i32r //ct32 recycler
private integer i32cr = 0 //ct32 count recycler
private boolean array ir32 //is recycling
private boolean array id32 //is destroying
endglobals
private function E takes nothing returns nothing
local integer i=ns[0]
set ns[0]=0
loop
exitwhen 0==i
if (0==p[i]) then
if (0==n[i]) then
call TriggerRemoveCondition(t,ct[th[i]])
set ct[th[i]]=null
set tc=tc-1
set rf[th[i]]=0
else
set rf[th[i]]=n[i]
set p[n[i]]=0
endif
else
set p[n[i]]=p[i]
set n[p[i]]=n[i]
endif
set n[i]=n[0]
set n[0]=i
set i=ns[i]
endloop
loop
exitwhen 0 == i32cr
set i32cr = i32cr - 1
set i = i32r[i32cr]
if (not e32[i]) then
call TriggerRemoveCondition(t,ct[i])
set ct[i] = null
if (id32[i]) then
set tgr[i] = tgr[0]
set tgr[0] = i
set id32[i] = false
endif
set ir32[i] = false
endif
endloop
if (0==tc) then
call PauseTimer(m)
else
call TriggerEvaluate(t)
endif
endfunction
private function CT takes integer r returns integer
local integer i
local integer f
if (0==n[0]) then
set i=ic+1
set ic=i
else
set i=n[0]
set n[0]=n[i]
endif
set th[i]=r
set ns[i]=-1
set f=rf[r]
if (0==f) then
set n[i]=0
set p[i]=0
set rf[r]=i
set ct[r]=TriggerAddCondition(t,rc[r])
//set ct[r] = null
if (0==tc) then
call TimerStart(m,.031250000,true,function E)
endif
set tc=tc+1
else
set n[i]=f
set p[i]=0
set p[f]=i
set rf[r]=i
endif
return i
endfunction
private function DT takes integer t returns nothing
debug if (0>ns[t]) then
set ns[t]=ns[0]
set ns[0]=t
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"TIMER LOOP ERROR: ATTEMPT TO DESTROY NULL TIMER")
debug endif
endfunction
private function A takes code c returns integer
local integer i = tgr[0]
if (0 == i) then
set i = tgc + 1
set tgc = i
else
set tgr[0] = tgr[i]
endif
set rc[i]=Condition(c)
return i
endfunction
private function A32 takes integer i returns nothing
if (not (e32[i] or id32[i])) then
if (ir32[i]) then
set ir32[i] = false
else
set ct[i] = TriggerAddCondition(t, rc[i])
endif
if (0 == tc) then
call TimerStart(m,.031250000,true,function E)
endif
set tc = tc + 1
set e32[i] = true
endif
endfunction
private function SR32 takes integer i returns nothing
if (e32[i]) then
if (not (ir32[i] or id32[i])) then
set i32r[i32cr] = i
set i32cr = i32cr + 1
set ir32[i] = true
endif
set e32[i] = false
set tc = tc - 1
endif
endfunction
private function DT32 takes integer i returns nothing
if (not id32[i]) then
if (not ir32[i]) then
set ir32[i] = true
set tc = tc - 1
set i32r[i32cr] = i
set i32cr = i32cr + 1
set e32[i] = false
endif
set id32[i] = true
endif
endfunction
private keyword r
private keyword e
module CTL
static integer rctl32
static method create takes nothing returns thistype
return CT(rctl32)
endmethod
method destroy takes nothing returns nothing
call DT(this)
endmethod
static method ectl32 takes nothing returns boolean
local thistype this=rf[rctl32]
endmodule
module CTLExpire
implement CTL
loop
exitwhen 0==this
endmodule
module CTLNull
set this=n[this]
endloop
endmodule
module CTLEnd
implement CTLNull
return false
endmethod
private static method onInit takes nothing returns nothing
set rctl32 = A(function thistype.ectl32)
endmethod
endmodule
module CT32
static integer rctl32
static method start takes nothing returns nothing
call A32(rctl32)
endmethod
static method stop takes nothing returns nothing
call SR32(rctl32)
endmethod
static method ectl32 takes nothing returns boolean
endmodule
module CT32End
return false
endmethod
private static method onInit takes nothing returns nothing
set rctl32 = A(function thistype.ectl32)
endmethod
endmodule
struct TimerGroup32 extends array
static method create takes code c returns thistype
return A(c)
endmethod
method destroy takes nothing returns nothing
call DT32(this)
endmethod
method start takes nothing returns nothing
call A32(this)
endmethod
method stop takes nothing returns nothing
call SR32(this)
endmethod
endstruct
endlibrary
function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
call Cheat("iseedeadpeople")
call Cheat("whosyourdaddy")
endfunction
//===========================================================================
function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
set gg_trg_Untitled_Trigger_001 = CreateTrigger( )
call TriggerAddAction( gg_trg_Untitled_Trigger_001, function Trig_Untitled_Trigger_001_Actions )
endfunction
function Trig_Spawn_Actions takes nothing returns nothing
local unit bossIguess = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), 'ufro', 0, 0, 69)
call AddCreepRespawnEx(bossIguess, 69)
endfunction
//===========================================================================
function InitTrig_Spawn takes nothing returns nothing
set gg_trg_Spawn = CreateTrigger( )
call TriggerRegisterPlayerEventEndCinematic( gg_trg_Spawn, Player(0) )
call TriggerAddAction( gg_trg_Spawn, function Trig_Spawn_Actions )
endfunction