Name | Type | is_array | initial_value |
Loc | location | No |
library FactoryMode
/*
FactoryMode is a system that allows you to create your own version of PocketFactory but
comes with added functionality like the ability to have multiple exit ports and dynamically
changing spawn time.
*/
//API
/*
/* FactoryMode */
call FactoryMode.create takes unit u, real interval, integer chargeTrigger, integer chargeLimit returns thistype
unit u ---------------- The Factory
real interval --------- The time after which FACTORY_ON_CHARGE_INTERVAL will fire
integer chargeTrigger - the amount of charges needed to fire FACTORY_ON_CHARGE_LIMIT
integer chargeLimit --- this is the maximum number of charges a factory can hold at any
time.
call FactoryMode.remove takes FactoryMode this returns nothing
FactoryMode this ------ this is the instance of a created FactoryMode. Be sure to store
the instance or you will not be able to terminate it. This method
will terimate a FactoryMode.
call FactoryMode.getFactory takes FactoryMode this returns unit
FactoryMode this ------ similar to above, returns the Factory itself.
call FactoryMode.getThreshold takes FactoryMode this returns integer
FactoryMode this ------ similar to above, but returns the number of charges required to trigger the threshold.
call FactoryMode.getCharges takes FactoryMode this returns integer
FactoryMode this ------ similar to above, but returns the number of charges on a Factory.
call FactoryMode.setCharges takes FactoryMode this, integer chargeCount, boolean muteEvent returns nothing
FactoryMode this ------ similar to above.
integer chargeCount --- sets the charges of a Factory. Use FactoryMode.getCharges() to
find what the current number is.
boolean muteEvent ----- Prevents a CAHRGE_UP event from firing. Useful when reducing charge count.
/* ExitPort */
static method ExitPort.getPortX takes thistype port returns real
returns the X coordinate of a port
static method ExitPort.getPortY takes thistype port returns real
returns the Y coordinate of a port
static method ExitPort.getPortZ takes thistype port returns real
returns the Z value of a port
static method ExitPort.getPortFacing takes thistype port returns real
returns the facing angle of a port
static method ExitPort.getPortFactoryId takes thistype port returns FactoryMode
return the FactoryMode instance of a port
static method ExitPort.getSpecific takes FactoryMode f, integer i returns thistype
returns a specific exit port instance of a factory
static method ExitPort.getRandom takes FactoryMode f returns thistype
returns a random exit port instance of a factory
static method ExitPort.createUnit takes thistype port, integer unitid returns unit
special CreateUnit method for FactoryMode. Will create a unit depending on which port is
chosen.
static method ExitPort.create takes FactoryMode f, real X, real Y, real Z, real angle returns thistype
Adds an exit port to a factory.Exit ports come with height and angle settings as well so
you may make a unit exit the factory at a specific height and facing a particular direction.
static method ExitPort.remove takes FactoryMode f, integer portNumber returns nothing
removes an exit port from a factory.
*/
globals
private constant real TIMEOUT = .03125
unit FACTORY = null
FactoryMode FACTORY_ID = 0
constant integer FACTORY_ON_CHARGE_INTERVAL = 1
constant integer FACTORY_ON_CHARGE_LIMIT = 2
constant integer FACTORY_ON_CHARGE_UP = 3
private trigger array EventTrig
private FactoryMode array Factory
private hashtable PortsStorage = null
private integer Factories = 0
private timer tmr = null
private unit Minitank = null
endglobals
private function FireTrigger takes integer ev, unit u, FactoryMode F returns nothing
set FACTORY = u
set FACTORY_ID = F
call TriggerEvaluate(EventTrig[ev])
set FACTORY = null
set FACTORY_ID = 0
endfunction
function RegisterFactoryEvent takes integer ev, code c returns nothing
call TriggerAddCondition(EventTrig[ev], Condition(c))
endfunction
struct FactoryMode
private integer charges
private integer triggerThreshold
private integer limit
private integer slot
private unit factory
private real timeout
private real timeoutReset
integer portsCount
static method getFactory takes FactoryMode this returns unit
return this.factory
endmethod
static method getLimit takes FactoryMode this returns integer
return this.limit
endmethod
static method getThreshold takes FactoryMode this returns integer
return this.triggerThreshold
endmethod
static method getCharges takes FactoryMode this returns integer
return this.charges
endmethod
static method setCharges takes FactoryMode this, integer chargeCount, boolean muteEvent returns nothing
local integer c
set this.charges = chargeCount
if this.charges >= this.limit then
set this.charges = this.limit
endif
if not muteEvent then
call FireTrigger(FACTORY_ON_CHARGE_UP, this.factory, this)
endif
set c = this.charges
if c >= this.triggerThreshold then
call FireTrigger(FACTORY_ON_CHARGE_LIMIT, this.factory, this)
endif
endmethod
private static method factoryInterval takes nothing returns nothing
local integer i = 0
local thistype this
if Factories > 0 then
loop
set i = i + 1
exitwhen i > Factories
set this = Factory[i]
set this.timeout = this.timeout - TIMEOUT
if this.timeout <= 0. then
set this.timeout = this.timeoutReset
call FireTrigger(FACTORY_ON_CHARGE_INTERVAL, this.factory, this)
endif
endloop
else
call DestroyTimer(tmr)
set tmr = null
endif
endmethod
private method destroy takes nothing returns nothing
local integer i = 0
local ExitPort port
loop
set i = i + 1
exitwhen i > this.portsCount
set port = LoadInteger(PortsStorage, this, i)
call port.destroy()
endloop
call FlushChildHashtable(PortsStorage, this)
set this.charges = 0
set this.triggerThreshold = 0
set this.limit = 0
set this.slot = 0
set this.timeout = 0.
set this.timeoutReset = 0.
set this.factory = null
set this.portsCount = 0
call this.deallocate()
endmethod
static method remove takes FactoryMode this returns nothing
local integer i = this.slot
local FactoryMode = nextF
loop
set nextF = Factory[i + 1]
set Factory[i] = nextF
set nextF.slot = i
set i = i + 1
exitwhen i > Factories
endloop
set Factories = Factories - 1
call this.destroy()
endmethod
static method create takes unit u, real interval, integer chargeTrigger, integer chargeLimit returns thistype
local thistype this = allocate()
set this.charges = 0
set this.triggerThreshold = chargeTrigger
set this.limit = chargeLimit
set this.timeout = interval
set this.timeoutReset = interval
set this.factory = u
set this.portsCount = 0
set Factories = Factories + 1
set Factory[Factories] = this
set this.slot = Factories
if tmr == null then
set tmr = CreateTimer()
call TimerStart(tmr, TIMEOUT, true, function thistype.factoryInterval)
endif
return this
endmethod
private static method onInit takes nothing returns nothing
set EventTrig[FACTORY_ON_CHARGE_UP] = CreateTrigger()
set EventTrig[FACTORY_ON_CHARGE_LIMIT] = CreateTrigger()
set EventTrig[FACTORY_ON_CHARGE_INTERVAL] = CreateTrigger()
endmethod
endstruct
struct ExitPort
private real x
private real y
private real z
private real facing
FactoryMode fId
method destroy takes nothing returns nothing
set this.x = 0.
set this.y = 0.
set this.z = 0.
set this.facing = 0.
set this.fId = 0
call this.deallocate()
endmethod
static method remove takes FactoryMode f, integer portNumber returns nothing
local integer i = portNumber
local thistype port = LoadInteger(PortsStorage, f, i)
call port.destroy()
loop
call RemoveSavedInteger(PortsStorage, f, i)
call SaveInteger(PortsStorage, f, i, LoadInteger(PortsStorage, f, i + 1))
set i = i + 1
exitwhen i > f.portsCount
endloop
set f.portsCount = f.portsCount - 1
endmethod
static method getPortX takes thistype port returns real
return port.x
endmethod
static method getPortY takes thistype port returns real
return port.y
endmethod
static method getPortZ takes thistype port returns real
return port.z
endmethod
static method getPortFacing takes thistype port returns real
return port.facing
endmethod
static method getPortFactoryId takes thistype port returns FactoryMode
return port.fId
endmethod
static method getSpecific takes FactoryMode f, integer i returns thistype
local thistype port = LoadInteger(PortsStorage, f, i)
if port == 0 then
set port = LoadInteger(PortsStorage, f, f.portsCount)
endif
return port
endmethod
static method getRandom takes FactoryMode f returns thistype
return LoadInteger(PortsStorage, f, GetRandomInt(1, f.portsCount))
endmethod
static method createUnit takes thistype port, integer unitid returns unit
local unit source = FactoryMode.getFactory(port.fId)
local unit rallyU = GetUnitRallyUnit(source)
local destructable rallyD = GetUnitRallyDestructable(source)
local location loc
set Minitank = CreateUnit(GetOwningPlayer(source), unitid, port.x, port.y, port.facing)
call SetUnitFlyHeight(Minitank, port.z, 0.)
if rallyU != null then
if rallyU != source then
call IssueTargetOrderById(Minitank, 851971, rallyU) //order smart
endif
elseif rallyD != null then
call IssueTargetOrderById(Minitank, 851971, rallyD) //order smart
else
set loc = GetUnitRallyPoint(source)
call IssuePointOrderById(Minitank, 851983, GetLocationX(loc), GetLocationY(loc)) //order attack
call RemoveLocation(loc)
endif
set rallyU = null
set rallyD = null
set source = null
return Minitank
endmethod
static method create takes FactoryMode f, real X, real Y, real Z, real angle returns thistype
local thistype port = allocate()
set port.x = X
set port.y = Y
set port.z = Z
set port.facing = angle
set port.fId = f
set f.portsCount = f.portsCount + 1
if PortsStorage == null then
set PortsStorage = InitHashtable()
endif
call SaveInteger(PortsStorage, f, f.portsCount, port)
return port
endmethod
endstruct
endlibrary
library FactoryModeDemo initializer init requires FactoryMode, SpellEffectEvent optional BlizzardMessage
/*
This demo shows how the Factory Mode library is being used. Each function has a brief
description to help you understand their use.
*/
globals
//CONFIG
private constant integer SPELL_ID = 'A000'
private constant integer RALLY_ID = 'ARal'
private constant integer CREATE_TANK_ID = 'A001'
private constant integer BASE_HERO_ID = 'N000'
private constant string SPAWN_FX_STRING = "Objects\\Spawnmodels\\Other\\ToonBoom\\ToonBoom.mdl"
private constant integer ORDER_UNMORPH = 852657 //order unrobogoblin
private constant integer ORDER_MAKETANK = 852561 //order frenzy
private constant integer ORDER_TANKON = 852562 //order frenzyon
private constant integer ORDER_TANKOFF = 852563 //order frenzyoff
private constant integer TANK_ID = 'tan1'
private constant integer NUMBER_OF_PORTS = 3
private constant real TANK_LIFESPAN = 25.
private constant real PORTS_DISTANCE = 160.
private constant real ANGLE_PER_PORT = 90. * bj_DEGTORAD //Must be in radians
private constant real CHARGE_INTERVAL = 1.
private constant integer CHARGE_THRESHOLD = 7
private constant integer CHARGE_REDUCTION_PER_LEVEL = 1
private constant integer CHARGE_LIMIT = 20
private constant integer CHARGE_RETURNED = 2
private constant boolean SHOW_CHARGE_COUNT = true
private constant boolean SHOW_CHARGE_CHANGE = true
private constant real TEXT_HEIGHT = 240.
private constant string CHARGES_MSG = "Insufficient Charges"
//END CONFIG
private hashtable F_ID_Storage = InitHashtable()
private hashtable Hero_Storage = InitHashtable()
private trigger onDeathTrig = CreateTrigger()
private trigger onTankTrig = CreateTrigger()
private trigger array HeroTrigger
private boolean array IsCreateTankOn
private integer array NextPort
private texttag array ChargeText
endglobals
/* This is the main function that produces the tanks. The next exit port is then picked so that the
next tank will exit from a different point.
*/
private function CreateTank takes FactoryMode F returns nothing
local integer thld = FactoryMode.getThreshold(F)
local integer c = FactoryMode.getCharges(F)
local integer diff = c - thld
local unit u
local ExitPort port
if diff >= 0 then
call FactoryMode.setCharges(F, c - thld, true)
if ChargeText[F] != null then
call SetTextTagText(ChargeText[F], I2S(FactoryMode.getCharges(F)), .023)
endif
set port = ExitPort.getSpecific(F, NextPort[F])
set u = ExitPort.createUnit(port, TANK_ID)
call DestroyEffect(AddSpecialEffect(SPAWN_FX_STRING, GetUnitX(u), GetUnitY(u)))
call UnitApplyTimedLife(u, 'BTLF', TANK_LIFESPAN)
call SaveUnitHandle(Hero_Storage, GetHandleId(u), 0, FACTORY)
set u = null
set NextPort[F] = NextPort[F] + 1
if NextPort[F] > NUMBER_OF_PORTS then
set NextPort[F] = 1
endif
else
static if LIBRARY_BlizzardMessage then
call BlizzardMessage(CHARGES_MSG, "|cffffcc00", 31, GetOwningPlayer(FactoryMode.getFactory(F)))
else
call BJDebugMsg(CHARGES_MSG)
endif
endif
endfunction
/* This function fires when the Create Tank ability is cast.
*/
private function onTank takes nothing returns nothing
call CreateTank(LoadInteger(F_ID_Storage, GetHandleId(GetTriggerUnit()), 0))
endfunction
/* This custom event fires whenever a charge count has changed. It checks for a relevant number
of charges and if it does have it, orders the hero to cast Create Tank.
*/
private function ActionsChargeUp takes nothing returns nothing
local FactoryMode F = FACTORY_ID //Store this because calling FactoryMode.setCharges will null the value of FACTORY_ID otherwise. More info below.
local unit Factory = FACTORY
local texttag ChargeCount
local real x = GetUnitX(Factory)
local real y = GetUnitY(Factory)
local real z = GetUnitFlyHeight(Factory) + TEXT_HEIGHT
local player play = GetOwningPlayer(Factory)
if IsCreateTankOn[F] and FactoryMode.getCharges(F) >= FactoryMode.getThreshold(F) then
call IssueImmediateOrderById(Factory, ORDER_MAKETANK)
endif
if ChargeText[F] != null then
call SetTextTagText(ChargeText[F], I2S(FactoryMode.getCharges(F)), .023)
endif
if SHOW_CHARGE_COUNT and FactoryMode.getCharges(F) < FactoryMode.getLimit(F) then
set ChargeCount = CreateTextTag()
call SetTextTagPos(ChargeCount, x, y, z + 50.)
call SetTextTagPermanent(ChargeCount, false)
call SetTextTagLifespan(ChargeCount, 2.0)
call SetTextTagFadepoint(ChargeCount, 1.0)
call SetTextTagVelocity(ChargeCount, .0355 * Cos(1.5708), .0355 * Sin(1.5708))
call SetTextTagColor(ChargeCount, 255, 255, 255, 255)
call SetTextTagText(ChargeCount, "+1", .023)
call SetTextTagVisibility(ChargeCount, (GetLocalPlayer() == GetOwningPlayer(Factory)))
endif
endfunction
/* This custom event fires whenever an interval for the FactoryMode has been reached. In this
instance, the number of charges is increased by 1.
*/
private function ActionsInterval takes nothing returns nothing
local FactoryMode F = FACTORY_ID //Store this because calling FactoryMode.setCharges will null the value of FACTORY_ID otherwise. More info below.
call FactoryMode.setCharges(F, FactoryMode.getCharges(F) + 1, false)
//Store FACTORY_ID and/or FACTORY inside of a local because calling FactoryMode.setCharges will null these values.
//call BJDebugMsg(I2S(F.charges))
endfunction
/* This functions handles the heros's death and increasing the level of the Factory Mode abiltiy.
If he dies, the same code is call as when he morphs back into a hero from Factory Mode. If he levels
up the ability, he is ordered to morph back into a hero to reset the spell.
*/
private function OnHeroEvent takes nothing returns boolean
local unit hero = GetTriggerUnit()
local FactoryMode F
if GetTriggerEventId() == EVENT_UNIT_HERO_SKILL then
if GetLearnedSkill() == SPELL_ID then
call IssueImmediateOrderById(hero, ORDER_UNMORPH)
endif
elseif GetTriggerEventId() == EVENT_UNIT_ISSUED_ORDER then
if GetIssuedOrderId() == ORDER_TANKON then //frenzyon
set F = LoadInteger(F_ID_Storage, GetHandleId(hero), 0)
set IsCreateTankOn[F] = true
elseif GetIssuedOrderId() == ORDER_TANKOFF then //frenzyoff
set F = LoadInteger(F_ID_Storage, GetHandleId(hero), 0)
set IsCreateTankOn[F] = false
endif
else
set F = LoadInteger(F_ID_Storage, GetHandleId(hero), 0)
call DestroyTrigger(HeroTrigger[F])
if ChargeText[F] != null then
call DestroyTextTag(ChargeText[F])
endif
set IsCreateTankOn[F] = false
set NextPort[F] = 0
call FactoryMode.remove(F)
call UnitRemoveAbility(hero, RALLY_ID)
endif
set hero = null
return false
endfunction
/* This trigger checks for the death of nearby minitanks. If they die in the vicinity of their
spawner, FactoryMode.setCharges() is called to increase the number of charges the main tank has,
effectively reducing spawn time between tanks.
*/
private function OnMachineDeath takes nothing returns boolean
local unit u = GetTriggerUnit()
local unit factory = LoadUnitHandle(Hero_Storage, GetHandleId(u), 0)
local FactoryMode F
if factory != null and IsUnitInRange(u, factory, 750.) then
set F = LoadInteger(F_ID_Storage, GetHandleId(factory), 0)
call FactoryMode.setCharges(F, FactoryMode.getCharges(F) + CHARGE_RETURNED, false)
endif
set factory = null
set u = null
return false
endfunction
/* When the spell is cast, the trigger checks for the ID of the hero - if the ID is that of the
deployed tank, then the ability has been activated. If the ID is that of the base hero, then the
ability has been deactivated. In the former case, FactoryMode.create() is called and the instance
is stored in a hashtable. In the latter case, the instance number is loaded and Factory.remove()
is called.
*/
private function onCast takes nothing returns nothing
local unit caster = GetTriggerUnit()
local FactoryMode F
local real xCaster
local real yCaster
local real x
local real y
local real a
local integer i = 0
local integer spellLevel = GetUnitAbilityLevel(caster, SPELL_ID)
if GetUnitTypeId(caster) == BASE_HERO_ID then //morph has been initiated
set F = FactoryMode.create(caster, CHARGE_INTERVAL, CHARGE_THRESHOLD - CHARGE_REDUCTION_PER_LEVEL * spellLevel, CHARGE_LIMIT)
call SaveInteger(F_ID_Storage, GetHandleId(caster), 0, F)
set xCaster = GetUnitX(caster)
set yCaster = GetUnitY(caster)
set a = (GetUnitFacing(caster) * bj_DEGTORAD) - ANGLE_PER_PORT
loop
set i = i + 1
exitwhen i > NUMBER_OF_PORTS
set x = xCaster + Cos(a) * PORTS_DISTANCE
set y = yCaster + Sin(a) * PORTS_DISTANCE
call ExitPort.create(F, x, y, 0, a * bj_RADTODEG)
set a = a + ANGLE_PER_PORT
endloop
set NextPort[F] = 1
call UnitAddAbility(caster, RALLY_ID)
call UnitAddAbility(caster, CREATE_TANK_ID)
call UnitMakeAbilityPermanent(caster, true, CREATE_TANK_ID)
call SetUnitAbilityLevel(caster, CREATE_TANK_ID, spellLevel)
set HeroTrigger[F] = CreateTrigger()
call TriggerRegisterUnitEvent(HeroTrigger[F], caster, EVENT_UNIT_DEATH)
call TriggerRegisterUnitEvent(HeroTrigger[F], caster, EVENT_UNIT_HERO_SKILL)
call TriggerRegisterUnitEvent(HeroTrigger[F], caster, EVENT_UNIT_ISSUED_ORDER)
call TriggerAddCondition(HeroTrigger[F], Condition(function OnHeroEvent))
if SHOW_CHARGE_COUNT then
set ChargeText[F] = CreateTextTag()
call SetTextTagPos(ChargeText[F], xCaster, yCaster, GetUnitFlyHeight(caster) + TEXT_HEIGHT)
call SetTextTagPermanent(ChargeText[F], true)
call SetTextTagColor(ChargeText[F], 255, 255, 255, 255)
call SetTextTagText(ChargeText[F], I2S(FactoryMode.getCharges(F)), .023)
call SetTextTagVisibility(ChargeText[F], (GetLocalPlayer() == GetOwningPlayer(caster)))
endif
else
set F = LoadInteger(F_ID_Storage, GetHandleId(caster), 0)
call DestroyTrigger(HeroTrigger[F])
if ChargeText[F] != null then
call DestroyTextTag(ChargeText[F])
endif
set IsCreateTankOn[F] = false
set NextPort[F] = 0
call FactoryMode.remove(F)
call UnitRemoveAbility(caster, RALLY_ID)
call UnitMakeAbilityPermanent(caster, false, CREATE_TANK_ID)
call UnitRemoveAbility(caster, CREATE_TANK_ID)
endif
set caster = null
endfunction
private function init takes nothing returns nothing
call RegisterFactoryEvent(FACTORY_ON_CHARGE_UP, function ActionsChargeUp)
call RegisterFactoryEvent(FACTORY_ON_CHARGE_INTERVAL, function ActionsInterval)
call RegisterSpellEffectEvent(SPELL_ID, function onCast)
call RegisterSpellEffectEvent(CREATE_TANK_ID, function onTank)
call TriggerRegisterAnyUnitEventBJ(onDeathTrig, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(onDeathTrig, Condition(function OnMachineDeath))
endfunction
endlibrary
//============================================================================
// SpellEffectEvent
// - Version 1.1.0.0
//
// API
// ---
// RegisterSpellEffectEvent(integer abil, code onCast)
//
// Requires
// --------
// RegisterPlayerUnitEvent: hiveworkshop.com/forums/showthread.php?t=203338
//
// Optional
// --------
// Table: hiveworkshop.com/forums/showthread.php?t=188084
//
library SpellEffectEvent requires RegisterPlayerUnitEvent, optional Table
//============================================================================
private module M
static if LIBRARY_Table then
static Table tb
else
static hashtable ht = InitHashtable()
endif
static method onCast takes nothing returns nothing
static if LIBRARY_Table then
call TriggerEvaluate(.tb.trigger[GetSpellAbilityId()])
else
call TriggerEvaluate(LoadTriggerHandle(.ht, 0, GetSpellAbilityId()))
endif
endmethod
private static method onInit takes nothing returns nothing
static if LIBRARY_Table then
set .tb = Table.create()
endif
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function thistype.onCast)
endmethod
endmodule
//============================================================================
private struct S extends array
implement M
endstruct
//============================================================================
function RegisterSpellEffectEvent takes integer abil, code onCast returns nothing
static if LIBRARY_Table then
if not S.tb.handle.has(abil) then
set S.tb.trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(S.tb.trigger[abil], Filter(onCast))
else
if not HaveSavedHandle(S.ht, 0, abil) then
call SaveTriggerHandle(S.ht, 0, abil, CreateTrigger())
endif
call TriggerAddCondition(LoadTriggerHandle(S.ht, 0, abil), Filter(onCast))
endif
endfunction
endlibrary
/**************************************************************
*
* RegisterPlayerUnitEvent
* v5.1.0.1
* By Magtheridon96
*
* I would like to give a special thanks to Bribe, azlier
* and BBQ for improving this library. For modularity, it only
* supports player unit events.
*
* Functions passed to RegisterPlayerUnitEvent must either
* return a boolean (false) or nothing. (Which is a Pro)
*
* Warning:
* --------
*
* - Don't use TriggerSleepAction inside registered code.
* - Don't destroy a trigger unless you really know what you're doing.
*
* API:
* ----
*
* - function RegisterPlayerUnitEvent takes playerunitevent whichEvent, code whichFunction returns nothing
* - Registers code that will execute when an event fires.
* - function RegisterPlayerUnitEventForPlayer takes playerunitevent whichEvent, code whichFunction, player whichPlayer returns nothing
* - Registers code that will execute when an event fires for a certain player.
* - function GetPlayerUnitEventTrigger takes playerunitevent whichEvent returns trigger
* - Returns the trigger corresponding to ALL functions of a playerunitevent.
*
**************************************************************/
library RegisterPlayerUnitEvent // Special Thanks to Bribe and azlier
globals
private trigger array t
endglobals
function RegisterPlayerUnitEvent takes playerunitevent p, code c returns nothing
local integer i = GetHandleId(p)
local integer k = 15
if t[i] == null then
set t[i] = CreateTrigger()
loop
call TriggerRegisterPlayerUnitEvent(t[i], Player(k), p, null)
exitwhen k == 0
set k = k - 1
endloop
endif
call TriggerAddCondition(t[i], Filter(c))
endfunction
function RegisterPlayerUnitEventForPlayer takes playerunitevent p, code c, player pl returns nothing
local integer i = 16 * GetHandleId(p) + GetPlayerId(pl)
if t[i] == null then
set t[i] = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(t[i], pl, p, null)
endif
call TriggerAddCondition(t[i], Filter(c))
endfunction
function GetPlayerUnitEventTrigger takes playerunitevent p returns trigger
return t[GetHandleId(p)]
endfunction
endlibrary
library BlizzardMessage /* v1.0.0.4
*************************************************************************************
*
* For creating Blizzard-like messages with a variety of sounds.
*
*************************************************************************************
*
* Credits
*
* Vexorian
* -----------------------
*
* The original SimError
*
*
* Maker
* -----------------------
*
* Sound label help
*
************************************************************************************
*
* Function
* -----------------------
*
* function BlizzardMessage takes string msg, string colorCode, integer soundLabel, player forPlayer returns nothing
*
* Description
* -----------------------
*
* This function creates a Blizzard-like message with a sound for a player.
*
* Takes
* -----------------------
*
* string msg
* - The message to be displayed.
*
* string colorCode
* - Adds a color for the message through an ARBG color code. A null value creates a normal white text.
*
* integer soundLabel
* - The sound to be played.
*
* player forPlayer
* - The player that receives the message.
*
* Returns
* -----------------------
*
* nothing
*
*************************************************************************************
*
* Function
* -----------------------
*
* function BlizzardMessageTimed takes string msg, string colorCode, real dur, integer soundLabel, player forPlayer returns nothing
*
* Description
* -----------------------
*
* This function creates a timed Blizzard-like message with a sound for a player.
*
* Takes
* -----------------------
*
* string msg
* - The message to be displayed.
*
* string colorCode
* - Adds a color for the message through an ARBG color code. A null value creates a normal white text.
*
* real dur
* - The duration of the message.
*
* integer soundLabel
* - The sound to be played.
*
* player forPlayer
* - The player that receives the message.
*
* Returns
* -----------------------
*
* nothing
*
*************************************************************************************
*
* SETTINGS
* -----------------------
*
*/
globals
constant real MSG_DURATION = 2.00 //Message Duration
/*************************************************************************************
*
* Sound Labels
*
*************************************************************************************/
constant integer ALLY_HERO_DIES_HUMAN = 0
constant integer ALLY_HERO_DIES_NAGA = 1
constant integer ALLY_HERO_DIES_NIGHTELF = 2
constant integer ALLY_HERO_DIES_ORC = 3
constant integer ALLY_HERO_DIES_UNDEAD = 4
constant integer ALLY_TOWN_UNDER_ATTACK_HUMAN = 5
constant integer ALLY_TOWN_UNDER_ATTACK_NAGA = 6
constant integer ALLY_TOWN_UNDER_ATTACK_NIGHTELF = 7
constant integer ALLY_TOWN_UNDER_ATTACK_ORC = 8
constant integer ALLY_TOWN_UNDER_ATTACK_UNDEAD = 9
constant integer ALLY_UNDER_ATTACK_HUMAN = 10
constant integer ALLY_UNDER_ATTACK_NAGA = 11
constant integer ALLY_UNDER_ATTACK_NIGHTELF = 12
constant integer ALLY_UNDER_ATTACK_ORC = 13
constant integer ALLY_UNDER_ATTACK_UNDEAD = 14
constant integer ARRANGED_TEAM_INVITATION = 15
constant integer AUTO_CAST_BUTTON_CLICK = 16
constant integer CANT_PLACE_HUMAN = 17
constant integer CANT_PLACE_NAGA = 18
constant integer CANT_PLACE_NIGHTELF = 19
constant integer CANT_PLACE_ORC = 20
constant integer CANT_PLACE_UNDEAD = 21
constant integer CANT_ROOT_NIGHTELF = 22
constant integer CHATROOM_TIMER_TICK = 23
constant integer CLAN_INVITATION = 24
constant integer CONSTRUCTING_BUILDING_DEFAULT = 25
constant integer CONSTRUCTING_BUILDING_NAGA = 26
constant integer CONSTRUCTING_BUILDING_NIGHTELF = 27
constant integer CONSTRUCTING_BUILDING_ORC = 28
constant integer CONSTRUCTING_BUILDING_UNDEAD = 29
constant integer CREEP_AGGRO = 30
constant integer ERROR_MESSAGE = 31
constant integer GAME_FOUND = 32
constant integer GLUE_SCREEN_CLICK = 33
constant integer GOLD_MINE_COLLAPSE_HUMAN = 34
constant integer GOLD_MINE_COLLAPSE_NAGA = 35
constant integer GOLD_MINE_COLLAPSE_NIGHTELF = 36
constant integer GOLD_MINE_COLLAPSE_ORC = 37
constant integer GOLD_MINE_COLLAPSE_UNDEAD = 38
constant integer GOLD_MINE_LOW_GENERIC = 39
constant integer GOLD_MINE_LOW_HUMAN = 40
constant integer GOLD_MINE_LOW_NAGA = 41
constant integer GOLD_MINE_LOW_NIGHTELF = 42
constant integer GOLD_MINE_LOW_ORC = 43
constant integer GOLD_MINE_LOW_UNDEAD = 44
constant integer GOOD_JOB = 45
constant integer HERO_DIES_GENERIC = 46
constant integer HERO_DIES_HUMAN = 47
constant integer HERO_DIES_NAGA = 48
constant integer HERO_DIES_NIGHTELF = 49
constant integer HERO_DIES_ORC = 50
constant integer HERO_DIES_UNDEAD = 51
constant integer HINT = 52
constant integer IN_GAME_CHAT_WHAT = 53
constant integer INTERFACE_CLICK = 54
constant integer INTERFACE_ERROR = 55
constant integer INVENTORY_FULL_HUMAN = 56
constant integer INVENTORY_FULL_NAGA = 57
constant integer INVENTORY_FULL_NIGHTELF = 58
constant integer INVENTORY_FULL_ORC = 59
constant integer INVENTORY_FULL_UNDEAD = 60
constant integer ITEM_DROP = 61
constant integer ITEM_GET = 62
constant integer ITEM_REWARD = 63
constant integer JOB_DONE_SOUND_HUMAN = 64
constant integer JOB_DONE_SOUND_NAGA = 65
constant integer JOB_DONE_SOUND_NIGHTELF = 66
constant integer JOB_DONE_SOUND_ORC = 67
constant integer JOB_DONE_SOUND_UNDEAD = 68
constant integer MAP_PING = 69
constant integer MENU_BUTTON_CLICK = 70
constant integer NEW_TOURNAMENT = 71
constant integer NO_FOOD_HUMAN = 72
constant integer NO_FOOD_NAGA = 73
constant integer NO_FOOD_NIGHTELF = 74
constant integer NO_FOOD_ORC = 75
constant integer NO_FOOD_UNDEAD = 76
constant integer NO_GOLD_GENERIC = 77
constant integer NO_GOLD_HUMAN = 78
constant integer NO_GOLD_NAGA = 79
constant integer NO_GOLD_NIGHTELF = 80
constant integer NO_GOLD_ORC = 81
constant integer NO_GOLD_UNDEAD = 82
constant integer NO_LUMBER_HUMAN = 83
constant integer NO_LUMBER_NAGA = 84
constant integer NO_LUMBER_NIGHTELF = 85
constant integer NO_LUMBER_ORC = 86
constant integer NO_LUMBER_UNDEAD = 87
constant integer NO_MANA_GENERIC = 88
constant integer NO_MANA_HUMAN = 89
constant integer NO_MANA_NAGA = 90
constant integer NO_MANA_NIGHTELF = 91
constant integer NO_MANA_ORC = 92
constant integer NO_MANA_UNDEAD = 93
constant integer OFF_BLIGHT_UNDEAD = 94
constant integer PAUSE_GAME = 95
constant integer PLACE_BUILDING_DEFAULT = 96
constant integer QUEST_COMPLETED = 97
constant integer QUEST_FAILED = 98
constant integer QUEST_LOG_MODIFIED = 99
constant integer QUEST_NEW = 100
constant integer QUEST_UPDATE = 101
constant integer RALLY_POINT_PLACE = 102
constant integer RESCUE = 103
constant integer RESEARCH_COMPLETE_GENERIC = 104
constant integer RESEARCH_COMPLETE_HUMAN = 105
constant integer RESEARCH_COMPLETE_NAGA = 106
constant integer RESEARCH_COMPLETE_NIGHTELF = 107
constant integer RESEARCH_COMPLETE_ORC = 108
constant integer RESEARCH_COMPLETE_UNDEAD = 109
constant integer SCORE_SCREEN_TAB_CLICK = 110
constant integer SECRET_FOUND = 111
constant integer SUB_GROUP_SELECTION_CHANGE = 112
constant integer TOWN_ATTACK_GENERIC = 113
constant integer TOWN_ATTACK_HUMAN = 114
constant integer TOWN_ATTACK_NAGA = 115
constant integer TOWN_ATTACK_NIGHTELF = 116
constant integer TOWN_ATTACK_ORC = 117
constant integer TOWN_ATTACK_UNDEAD = 118
constant integer UNDER_ATTACK_HUMAN = 119
constant integer UNDER_ATTACK_NAGA = 120
constant integer UNDER_ATTACK_NIGHTELF = 121
constant integer UNDER_ATTACK_ORC = 122
constant integer UNDER_ATTACK_UNDEAD = 123
constant integer UPGRADE_COMPLETE_GENERIC = 124
constant integer UPGRADE_COMPLETE_HUMAN = 125
constant integer UPGRADE_COMPLETE_NAGA = 126
constant integer UPGRADE_COMPLETE_NIGHTELF = 127
constant integer UPGRADE_COMPLETE_ORC = 128
constant integer UPGRADE_COMPLETE_UNDEAD = 129
constant integer UPKEEP_LEVEL = 130
constant integer WARNING = 131
constant integer WAYPOINT = 132
/* private */ string array SOUND_LABEL
endglobals
/*
************************************************************************************
*/
function BlizzardMessage takes string msg, string colorCode, integer soundLabel, player forPlayer returns nothing
local sound snd
local string s
debug if soundLabel >= 0 and soundLabel <= 132 and forPlayer != null then
set snd = CreateSoundFromLabel (SOUND_LABEL[soundLabel], false, false, false, 10, 10)
if colorCode != null then
set s = "|r"
else
set colorCode = ""
set s = ""
endif
if GetLocalPlayer () == forPlayer then
call ClearTextMessages ()
call DisplayTimedTextToPlayer (forPlayer, 0.52, 0.96, MSG_DURATION, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + colorCode + msg + s)
call StartSound (snd)
endif
if s != null then
set s = ""
endif
set snd = null
debug else
debug if msg == null
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[BlizzardMessage] [BlizzardMessage] Null message")
debug endif
debug if forPlayer == null
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[BlizzardMessage] [BlizzardMessage] Null forPlayer")
debug endif
debug if soundLabel < 0 or soundLabel > 132
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[BlizzardMessage] [BlizzardMessage] Invalid sound label")
debug endif
debug endif
endfunction
function BlizzardMessageTimed takes string msg, string colorCode, real dur, integer soundLabel, player forPlayer returns nothing
local sound snd
local string s
debug if soundLabel >= 0 and soundLabel <= 132 and forPlayer != null then
set snd = CreateSoundFromLabel (SOUND_LABEL[soundLabel], false, false, false, 10, 10)
if colorCode != null then
set s = "|r"
else
set colorCode = ""
set s = ""
endif
if GetLocalPlayer () == forPlayer then
call ClearTextMessages ()
call DisplayTimedTextToPlayer (forPlayer, 0.52, 0.96, dur, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + colorCode + msg + s)
call StartSound (snd)
endif
if s != null then
set s = ""
endif
set snd = null
debug else
debug if msg == null
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[BlizzardMessage] [BlizzardMessage] Null message")
debug endif
debug if forPlayer == null
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[BlizzardMessage] [BlizzardMessage] Null forPlayer")
debug endif
debug if soundLabel < 0 or soundLabel > 132
debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "[BlizzardMessage] [BlizzardMessage] Invalid sound label")
debug endif
debug endif
endfunction
private module BMInit
private static method onInit takes nothing returns nothing
call init()
endmethod
endmodule
private struct InitStruct extends array
private static method init takes nothing returns nothing
set SOUND_LABEL[0] = "AllyHeroDiesHuman"
set SOUND_LABEL[1] = "AllyHeroDiesNaga"
set SOUND_LABEL[2] = "AllyHeroDiesNightElf"
set SOUND_LABEL[3] = "AllyHeroDiesOrc"
set SOUND_LABEL[4] = "AllyHeroDiesUndead"
set SOUND_LABEL[5] = "AllyTownUnderAttackHuman"
set SOUND_LABEL[6] = "AllyTownUnderAttackNaga"
set SOUND_LABEL[7] = "AllyTownUnderAttackNightElf"
set SOUND_LABEL[8] = "AllyTownUnderAttackOrc"
set SOUND_LABEL[9] = "AllyTownUnderAttackUndead"
set SOUND_LABEL[10] = "AllyUnderAttackHuman"
set SOUND_LABEL[11] = "AllyUnderAttackNaga"
set SOUND_LABEL[12] = "AllyUnderAttackNightElf"
set SOUND_LABEL[13] = "AllyUnderAttackOrc"
set SOUND_LABEL[14] = "AllyUnderAttackUndead"
set SOUND_LABEL[15] = "ArrangedTeamInvitation"
set SOUND_LABEL[16] = "AutoCastButtonClick"
set SOUND_LABEL[17] = "CantPlaceHuman"
set SOUND_LABEL[18] = "CantPlaceNaga"
set SOUND_LABEL[19] = "CantPlaceNightElf"
set SOUND_LABEL[20] = "CantPlaceOrc"
set SOUND_LABEL[21] = "CantPlaceUndead"
set SOUND_LABEL[22] = "CantRootNightElf"
set SOUND_LABEL[23] = "ChatroomTimerTick"
set SOUND_LABEL[24] = "ClanInvitation"
set SOUND_LABEL[25] = "ConstructingBuildingDefault"
set SOUND_LABEL[26] = "ConstructingBuildingNaga"
set SOUND_LABEL[27] = "ConstructingBuildingNightElf"
set SOUND_LABEL[28] = "ConstructingBuildingOrc"
set SOUND_LABEL[29] = "ConstructingBuildingUndead"
set SOUND_LABEL[30] = "CreepAggro"
set SOUND_LABEL[31] = "ErrorMessage"
set SOUND_LABEL[32] = "GameFound"
set SOUND_LABEL[33] = "GlueScreenClick"
set SOUND_LABEL[34] = "GoldMineCollapseHuman"
set SOUND_LABEL[35] = "GoldMineCollapseNaga"
set SOUND_LABEL[36] = "GoldMineCollapseNightElf"
set SOUND_LABEL[37] = "GoldMineCollapseOrc"
set SOUND_LABEL[38] = "GoldMineCollapseUndead"
set SOUND_LABEL[39] = "GoldMineLowGeneric"
set SOUND_LABEL[40] = "GoldMineLowHuman"
set SOUND_LABEL[41] = "GoldMineLowNaga"
set SOUND_LABEL[42] = "GoldMineLowNightElf"
set SOUND_LABEL[43] = "GoldMineLowOrc"
set SOUND_LABEL[44] = "GoldMineLowUndead"
set SOUND_LABEL[45] = "GoodJob"
set SOUND_LABEL[46] = "HeroDiesGeneric"
set SOUND_LABEL[47] = "HeroDiesHuman"
set SOUND_LABEL[48] = "HeroDiesNaga"
set SOUND_LABEL[49] = "HeroDiesNightElf"
set SOUND_LABEL[50] = "HeroDiesOrc"
set SOUND_LABEL[51] = "HeroDiesUndead"
set SOUND_LABEL[52] = "Hint"
set SOUND_LABEL[53] = "InGameChatWhat"
set SOUND_LABEL[54] = "InterfaceClick"
set SOUND_LABEL[55] = "InterfaceError"
set SOUND_LABEL[56] = "InventoryFullHuman"
set SOUND_LABEL[57] = "InventoryFullNaga"
set SOUND_LABEL[58] = "InventoryFullNightElf"
set SOUND_LABEL[59] = "InventoryFullOrc"
set SOUND_LABEL[60] = "InventoryFullUndead"
set SOUND_LABEL[61] = "ItemDrop"
set SOUND_LABEL[62] = "ItemGet"
set SOUND_LABEL[63] = "ItemReward"
set SOUND_LABEL[64] = "JobDoneSoundHuman"
set SOUND_LABEL[65] = "JobDoneSoundNaga"
set SOUND_LABEL[66] = "JobDoneSoundNightElf"
set SOUND_LABEL[67] = "JobDoneSoundOrc"
set SOUND_LABEL[68] = "JobDoneSoundUndead"
set SOUND_LABEL[69] = "MapPing"
set SOUND_LABEL[70] = "MenuButtonClick"
set SOUND_LABEL[71] = "NewTournament"
set SOUND_LABEL[72] = "NoFoodHuman"
set SOUND_LABEL[73] = "NoFoodNaga"
set SOUND_LABEL[74] = "NoFoodNightElf"
set SOUND_LABEL[75] = "NoFoodOrc"
set SOUND_LABEL[76] = "NoFoodUndead"
set SOUND_LABEL[77] = "NoGoldGeneric"
set SOUND_LABEL[78] = "NoGoldHuman"
set SOUND_LABEL[79] = "NoGoldNaga"
set SOUND_LABEL[80] = "NoGoldNightElf"
set SOUND_LABEL[81] = "NoGoldOrc"
set SOUND_LABEL[82] = "NoGoldUndead"
set SOUND_LABEL[83] = "NoLumberHuman"
set SOUND_LABEL[84] = "NoLumberNaga"
set SOUND_LABEL[85] = "NoLumberNightElf"
set SOUND_LABEL[86] = "NoLumberOrc"
set SOUND_LABEL[87] = "NoLumberUndead"
set SOUND_LABEL[88] = "NoManaGeneric"
set SOUND_LABEL[89] = "NoManaHuman"
set SOUND_LABEL[90] = "NoManaNaga"
set SOUND_LABEL[91] = "NoManaNightElf"
set SOUND_LABEL[92] = "NoManaOrc"
set SOUND_LABEL[93] = "NoManaUndead"
set SOUND_LABEL[94] = "OffBlightUndead"
set SOUND_LABEL[95] = "PauseGame"
set SOUND_LABEL[96] = "PlaceBuildingDefault"
set SOUND_LABEL[97] = "QuestCompleted"
set SOUND_LABEL[98] = "QuestFailed"
set SOUND_LABEL[99] = "QuestLogModified"
set SOUND_LABEL[100] = "QuestNew"
set SOUND_LABEL[101] = "QuestUpdate"
set SOUND_LABEL[102] = "RallyPointPlace"
set SOUND_LABEL[103] = "Rescue"
set SOUND_LABEL[104] = "ResearchCompleteGeneric"
set SOUND_LABEL[105] = "ResearchCompleteHuman"
set SOUND_LABEL[106] = "ResearchCompleteNaga"
set SOUND_LABEL[107] = "ResearchCompleteNightElf"
set SOUND_LABEL[108] = "ResearchCompleteOrc"
set SOUND_LABEL[109] = "ResearchCompleteUndead"
set SOUND_LABEL[110] = "ScoreScreenTabClick"
set SOUND_LABEL[111] = "SecretFound"
set SOUND_LABEL[112] = "SubGroupSelectionChange"
set SOUND_LABEL[113] = "TownAttackGeneric"
set SOUND_LABEL[114] = "TownAttackHuman"
set SOUND_LABEL[115] = "TownAttackNaga"
set SOUND_LABEL[116] = "TownAttackNightElf"
set SOUND_LABEL[117] = "TownAttackOrc"
set SOUND_LABEL[118] = "TownAttackUndead"
set SOUND_LABEL[119] = "UnderAttackHuman"
set SOUND_LABEL[120] = "UnderAttackNaga"
set SOUND_LABEL[121] = "UnderAttackNightElf"
set SOUND_LABEL[122] = "UnderAttackOrc"
set SOUND_LABEL[123] = "UnderAttackUndead"
set SOUND_LABEL[124] = "UpgradeCompleteGeneric"
set SOUND_LABEL[125] = "UpgradeCompleteHuman"
set SOUND_LABEL[126] = "UpgradeCompleteNaga"
set SOUND_LABEL[127] = "UpgradeCompleteNightElf"
set SOUND_LABEL[128] = "UpgradeCompleteOrc"
set SOUND_LABEL[129] = "UpgradeCompleteUndead"
set SOUND_LABEL[130] = "UpkeepLevel"
set SOUND_LABEL[131] = "Warning"
set SOUND_LABEL[132] = "WayPoint"
endmethod
implement BMInit
endstruct
endlibrary