Name | Type | is_array | initial_value |
duration | real | No | |
grower | unit | No | |
scale | real | No |
//TESH.scrollpos=195
//TESH.alwaysfold=0
library TimedUnitScale /* v2.0
Information
¯¯¯¯¯¯¯¯¯¯¯
Allows you smoothly to change a unit's scale over time.
It is required you to read the GetUnitScale library,
if you modified default scale values in object editor.
Credits:
¯¯¯¯¯¯¯¯
Resources:
- TriggerHappy
- Nestharus
*/ requires /*
*/ GetUnitScale /* hiveworkshop.com/forums/submissions-414/snippet-getunitscale-262274/
*/ UnitDex /* hiveworkshop.com/threads/system-unitdex-unit-indexer.248209/
*/ List /* attached in map and in thread, because nestharus removed it I can't find original destinaion anymore
struct UnitScale
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
static method operator enableAll= takes boolean flag returns nothing
- when set to "false" it will pause all scale changes for all units
- when set to "true" it will continue again
static method operator [] takes unit who returns thistype
- That's the only interface for the user to get an instance.
- Use this to call methods or to set/read other members:
method apply takes real newScale, real duration returns UnitScaleData
- use this to apply a new scale change
- you also can use GetUnitScale function to mimic add & substract behaviour.
method stopScale takes UnitScaleData sd returns nothing
- you can use the return value from the "apply" method to manualy destroy a scale instance.
- do this at your own risk
method destroy
- "destroy" will destroy all scale instances.
boolean enabled
- set this to "false" if you want to disable, but not destroy a unit's scale changes
- when set to "true" it will continue again
readonly boolean exists
returns the flag if there currently exists any scale instance
readonly integer count
returns amount of current scale instances for our unit
Example:
local UnitScale myInstance = UnitScale[GetTriggerUnit()]
- we get the instance for our unit.
local UnitScaleData data = myInstance.apply(5, 10)
- this will call the apply method for myInstance.
- it will try to set it's scale to "5" over "10" seconds.
call instance.stopScale(data)
- will destroy the applied scale instance
Pay attention for the example. When the user will start multiple scale instances,
it oboviously is not ensured that the unit will have exactly the scale of "5" after "10" seconds.
If you want ensure accurate values you can check for already running instances, or use the .destroy() method before apply().
struct UnitScaleData
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
That's the struct returned by the apply method above.
You have further access from it:
method operator time takes nothing returns real
- returns the remaining time of the instance
method operator time= takes real r returns nothing
- define a new remaining time
- only positives will be allowed
method operator scalePerSecond takes nothing returns real
- return the current scale rate perSecond
method operator scalePerSecond= takes real r returns nothing
- define a new sclare rate perSecond.
- only positives will be allowed.
**************************************************************************/
globals
private constant timer CLOCK = CreateTimer()
private constant real TIMEOUT = .031250000
endglobals
struct UnitScaleData extends array
implement List
real duration // Remaining duration for scaling
real amount // scale-amount per interval
method operator time takes nothing returns real
return .duration
endmethod
method operator time= takes real r returns nothing
set .duration = RAbsBJ(r)
endmethod
method operator scalePerSecond takes nothing returns real
return .amount/TIMEOUT
endmethod
method operator scalePerSecond= takes real r returns nothing
set .amount = RAbsBJ(r)*TIMEOUT
endmethod
endstruct
struct UnitScale extends array
private static boolean systemEnabled = false
boolean enabled
readonly boolean exists // Does a UnitScale currently exist?
readonly integer count // How often a unit is currently regstered.
private unit u
private UnitScaleData head
private thistype prev
private thistype next
private static thistype first = 0
static method operator [] takes unit who returns thistype
return GetUnitId(who)
endmethod
private method destroy takes nothing returns nothing
if not .exists then
return
endif
call .head.destroy()
set .count = 0
if (this == thistype.first) then
set thistype.first = this.next
endif
set this.next.prev = this.prev
set this.prev.next = this.next
if (thistype.first == 0) then
call PauseTimer(CLOCK)
set thistype.systemEnabled = false
endif
set .exists = false
set .u = null
endmethod
method stopScale takes UnitScaleData sd returns nothing
set .count = .count - 1
if .count == 0 then
call.destroy()
else
call sd.remove()
endif
endmethod
private static method callback takes nothing returns nothing
local thistype this = thistype.first
local UnitScaleData element
local UnitScaleData temp
loop
exitwhen (this == 0)
if (GetUnitTypeId(.u) == 0) then
call .destroy()
elseif (.enabled) then
set element = .head.first
loop
exitwhen element == 0
set temp = element.next
call SetUnitScale(.u, (GetUnitScale(.u) + element.amount), 1, 1)
if (element.duration <= TIMEOUT) then
call .stopScale(element)
else
set element.duration = element.duration - TIMEOUT
endif
set element = temp
endloop
endif
set this = this.next
endloop
endmethod
method apply takes real newScale, real duration returns UnitScaleData
local unit u = GetUnitById(this)
local UnitScaleData element
if (newScale == GetUnitScale(u)) then
return 0
endif
if (duration < 0) then
debug call BJDebugMsg("UnitScale: Durations smaller or equal 0 will lead to instant scaling.")
set duration = 0
endif
if (duration == 0) then
call SetUnitScale(u, newScale, 1, 1)
return 0
endif
set this = GetUnitId(u)
if .count == 0 then
set .head = UnitScaleData.create()
set .enabled = true
set .exists = true
set .u = u
if (thistype.first == 0) then
call TimerStart(CLOCK, TIMEOUT, true, function thistype.callback)
set thistype.systemEnabled = true
endif
set this.next = thistype.first
set thistype.first.prev = this
set thistype.first = this
set this.prev = 0
endif
set element = .head.enqueue()
set element.duration = duration
set element.amount = (newScale - GetUnitScale(u)) / (duration/TIMEOUT)
set .count = .count + 1
return element
endmethod
static method operator enableAll= takes boolean flag returns nothing
if flag and not thistype.systemEnabled and thistype.first != 0 then
call TimerStart(CLOCK, TIMEOUT, true, function thistype.callback)
set thistype.systemEnabled = flag
elseif not flag and not thistype.systemEnabled then
call PauseTimer(CLOCK)
set thistype.systemEnabled = flag
endif
endmethod
endstruct
endlibrary
//TESH.scrollpos=6
//TESH.alwaysfold=0
library GetUnitScale /* v1.3
Provides functionality to get a unit's current and default scale.
The system expects the default scale value to be exactly 1.00.
If you modified the value in the object editor for a specific unit,
you have to adapt it to the system. (see module DefaultScale)
*/ requires /*
*/ UnitDex /* hiveworkshop.com/threads/system-unitdex-unit-indexer.248209/
*/ Table /* http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
** API
**
**
** function GetUnitScale (unit) returns real
** Returns the current scale of the unit.
**
** function GetUnitDefaultScale (unit) returns real
** Returns the default scale of the unit.
***************************************************************************
**
** Credits to guys named in brackets.
**
** Requires:
** - Table (Bribe)
** - UnitDex (TriggerHappy)
**
**************************************************************************/
// Here you can define the correct default scale, it the value is not "1" in object editor.
private module DefaultScale
private static method onInit takes nothing returns nothing
// Example: call apply('hfoo', 1.60) // -> Register footman with default scale 1.60.
call RegisterUnitIndexEvent(Condition(function thistype.onIndex), EVENT_UNIT_INDEX)
endmethod
endmodule
private struct UnitScale extends array
private static key k
readonly static Table table = k
readonly real defaultScale
readonly static real array currentScale
private static thistype this = 0
static method apply takes integer uType, real scale returns nothing
if not thistype.table.has(uType) then
set this = this + 1
set thistype.table[uType] = this
endif
set this.defaultScale = scale
endmethod
implement DefaultScale
static method operator [] takes integer uType returns thistype
return thistype.table[uType]
endmethod
// onIndex we initalisize the scale value.
private static method onIndex takes nothing returns boolean
local integer id = GetIndexedUnitId()
local integer uType = GetUnitTypeId(GetIndexedUnit())
// Check if default scale is registered for this unit type.
if not thistype.table.has(uType) then
set thistype.currentScale[id] = 1.
else
set thistype.currentScale[id] = thistype[uType].defaultScale
endif
return false
endmethod
// hook methods
static method DataUpdate takes unit u, real x, real y, real z returns nothing
set thistype.currentScale[GetUnitUserData(u)] = x
endmethod
static method DataUpdatePercent takes unit u, real x, real y, real z returns nothing
set thistype.currentScale[GetUnitUserData(u)] = x*0.01
endmethod
endstruct
hook SetUnitScale UnitScale.DataUpdate
hook SetUnitScalePercent UnitScale.DataUpdatePercent
// API functions
function GetUnitScale takes unit u returns real
return UnitScale.currentScale[GetUnitUserData(u)]
endfunction
function GetUnitDefaultScale takes unit u returns real
if UnitScale.table.has(GetUnitTypeId(u)) then
return UnitScale[GetUnitTypeId(u)].defaultScale
endif
return 1.
endfunction
endlibrary
//TESH.scrollpos=76
//TESH.alwaysfold=0
library UnitDex uses optional WorldBounds, optional GroupUtils
/***************************************************************
*
* v1.2.1, by TriggerHappy
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* UnitDex assigns every unit an unique integer. It attempts to make that number within the
* maximum array limit so you can associate it with one.
* _________________________________________________________________________
* 1. Installation
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Copy the script to your map, save it, then restart the editor and comment out the line below.
*/
//! external ObjectMerger w3a Adef uDex anam "Detect Leave" ansf "(UnitDex)" aart "" acat "" arac 0
/* ________________________________________________________________________
* 2. Configuration
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*/
private module UnitDexConfig
// The raw code of the leave detection ability.
static constant integer DETECT_LEAVE_ABILITY = 'uDex'
// Allow debug messages (debug mode must also be on)
static constant boolean ALLOW_DEBUGGING = true
// Uncomment the lines below to define a filter for units being indexed
/*static method onFilter takes unit u returns boolean
return true
endmethod*/
endmodule
/* _________________________________________________________________________
* 3. Function API
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Every function inlines except for UnitDexRemove
*
* function GetUnitId takes unit whichUnit returns integer
* function GetUnitById takes integer index returns unit
*
* function UnitDexEnable takes boolean flag returns nothing
* function UnitDexRemove takes unit u, boolean runEvents returns boolean
*
* function IsUnitIndexed takes unit u returns boolean
* function IsIndexingEnabled takes nothing returns boolean
*
* function GetIndexedUnit takes nothing returns unit
* function GetIndexedUnitId takes nothing returns integer
*
* function RegisterUnitIndexEvent takes boolexpr func, integer eventtype returns indexevent
* function RemoveUnitIndexEvent takes triggercondition c, integer eventtype returns nothing
* function TriggerRegisterUnitIndexEvent takes trigger t, integer eventtype returns nothing
*
* function OnUnitIndex takes code func returns triggercondition
* function OnUnitDeidex takes code func returns triggercondition
* _________________________________________________________________________
* 4. Struct API
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* UnitDex.Enabled = false // toggle the indexer
* UnitDex.Initialized // returns true if the preload timer has finished
* UnitDex.Count // returns the amount of units indexed
* UnitDex.Unit[0] // access the UnitDex array directly
* UnitDex.Group // a unit group containing every indexed unit (for enumeration)
* UnitDex.LastIndex // returns the last indexed unit's id
* _________________________________________________________________________
* 5. Public Variables
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* These are to be used with the "eventtype" argument of the event API:
*
* constant integer EVENT_UNIT_INDEX = 0
* constant integer EVENT_UNIT_DEINDEX = 1
* _________________________________________________________________________
* 6. Examples
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* 1. Associate a unit with a variable
*
* set UnitFlag[GetUnitId(yourUnit)] = true
*
* 2. Allocate a struct instance using a units assigned ID
*
* local somestruct data = GetUnitId(yourUnit)
*
* 3. Detect when a unit leaves the map
*
* function Exit takes nothing returns nothing
* call BJDebugMsg("The unit " + GetUnitName(GetIndexedUnit()) + " has left the map.")
* endfunction
*
* call OnUnitDeindex(function Exit)
* // or
* call RegisterUnitIndexEvent(Filter(function Exit), EVENT_UNIT_DEINDEX)
*
*
* _________________________________________________________________________
* 7. How it works
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* 1. Enumerate all preplaced units
* 2. TriggerRegisterEnterRegion native to detect when a unit enters the map
* 3. Assign each unit that enters the map a unique integer
* 4. Give every unit an ability based off of defend. There is no native to accurately
* detect when a unit leaves the map but when a unit dies or is removed from the game
* they are issued the "undefend" order
* 5. Catch the "undefend" order and remove unit from the queue
* _________________________________________________________________________
* 8. Notes
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* - This system is compatable with GUI because it utilizes UnitUserData (custom values for units).
* - The object merger line should be commented out after saving and restarting.
* - All public functions are inlined except UnitDexRemove.
*
* -http://www.hiveworkshop.com/forums/submissions-414/unitdex-lightweight-unit-indexer-248209/
*
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*/
globals
// Event types
constant integer EVENT_UNIT_INDEX = 0
constant integer EVENT_UNIT_DEINDEX = 1
// System variables
private trigger array IndexTrig
private integer Index = 0
private real E=-1
private boolexpr FilterEnter
endglobals
function GetUnitId takes unit whichUnit returns integer
return GetUnitUserData(whichUnit)
endfunction
function GetUnitById takes integer index returns unit
return UnitDex.Unit[index]
endfunction
function GetIndexedUnit takes nothing returns unit
return UnitDex.Unit[UnitDex.LastIndex]
endfunction
function GetIndexedUnitId takes nothing returns integer
return UnitDex.LastIndex
endfunction
function IsUnitIndexed takes unit u returns boolean
return (GetUnitById(GetUnitId(u)) != null)
endfunction
function UnitDexEnable takes boolean flag returns nothing
set UnitDex.Enabled = flag
endfunction
function IsIndexingEnabled takes nothing returns boolean
return UnitDex.Enabled
endfunction
function RegisterUnitIndexEvent takes boolexpr func, integer eventtype returns triggercondition
return TriggerAddCondition(IndexTrig[eventtype], func)
endfunction
function RemoveUnitIndexEvent takes triggercondition c, integer eventtype returns nothing
call TriggerRemoveCondition(IndexTrig[eventtype], c)
endfunction
function TriggerRegisterUnitIndexEvent takes trigger t, integer eventtype returns nothing
call TriggerRegisterVariableEvent(t, SCOPE_PRIVATE + "E", EQUAL, eventtype)
endfunction
function OnUnitIndex takes code func returns triggercondition
return TriggerAddCondition(IndexTrig[EVENT_UNIT_INDEX], Filter(func))
endfunction
function OnUnitDeindex takes code func returns triggercondition
return TriggerAddCondition(IndexTrig[EVENT_UNIT_DEINDEX], Filter(func))
endfunction
function UnitDexRemove takes unit u, boolean runEvents returns boolean
return UnitDex.Remove(u, runEvents)
endfunction
/****************************************************************/
private keyword UnitDexCore
struct UnitDex extends array
static boolean Enabled = true
readonly static integer LastIndex
readonly static boolean Initialized=false
readonly static group Group=CreateGroup()
readonly static unit array Unit
readonly static integer Count = 0
readonly static integer array List
implement UnitDexConfig
private static integer Counter = 0
implement UnitDexCore
endstruct
/****************************************************************/
private module UnitDexCore
static method Remove takes unit u, boolean runEvents returns boolean
local integer i
if (IsUnitIndexed(u)) then
set i = GetUnitId(u)
set UnitDex.List[i] = Index
set Index = i
call GroupRemoveUnit(UnitDex.Group, u)
call SetUnitUserData(u, 0)
if (runEvents) then
set UnitDex.LastIndex = i
set E = EVENT_UNIT_DEINDEX
call TriggerEvaluate(IndexTrig[EVENT_UNIT_DEINDEX])
set E = -1
endif
set UnitDex.Unit[i] = null
set UnitDex.Count = UnitDex.Count - 1
return true
endif
return false
endmethod
private static method onGameStart takes nothing returns nothing
local integer i = 0
static if (not LIBRARY_GroupUtils) then // Check if GroupUtils exists so we can use it's enumeration group.
local group ENUM_GROUP = CreateGroup() // If not, create the group.
endif
// Index preplaced units
loop
call GroupEnumUnitsOfPlayer(ENUM_GROUP, Player(i), FilterEnter)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
static if (not LIBRARY_GroupUtils) then
call DestroyGroup(ENUM_GROUP)
set ENUM_GROUP = null
endif
// run init triggers
set i = 1
loop
exitwhen i > Counter
set LastIndex = i
call TriggerEvaluate(IndexTrig[EVENT_UNIT_INDEX])
set E = EVENT_UNIT_INDEX
set E = -1
set i = i + 1
endloop
set LastIndex = Counter
set Initialized = true
set FilterEnter = null
call DestroyTimer(GetExpiredTimer())
endmethod
private static method onEnter takes nothing returns boolean
local unit u = GetFilterUnit()
local integer i = GetUnitId(u)
local integer t = Index
if (i == 0 and thistype.Enabled) then
// If a filter was defined pass the unit through it.
static if (thistype.onFilter.exists) then
if (not thistype.onFilter(u)) then
set u = null
return false // check failed
endif
endif
// Handle debugging
static if (thistype.DEBUG_MODE and thistype.ALLOW_DEBUGGING) then
if (t == 0 and Counter+1 >= JASS_MAX_ARRAY_SIZE) then
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "UnitDex: Maximum number of units reached!")
set u = null
return false
endif
endif
// Add to group of indexed units
call GroupAddUnit(thistype.Group, u)
// Give unit the leave detection ability
call UnitAddAbility(u, thistype.DETECT_LEAVE_ABILITY)
call UnitMakeAbilityPermanent(u, true, thistype.DETECT_LEAVE_ABILITY)
// Allocate index
if (Index != 0) then
set Index = List[t]
else
set Counter = Counter + 1
set t = Counter
endif
set List[t] = -1
set LastIndex = t
set thistype.Unit[t] = u
set Count = Count + 1
// Store the index
call SetUnitUserData(u, t)
if (thistype.Initialized) then
// Execute custom events registered with RegisterUnitIndexEvent
call TriggerEvaluate(IndexTrig[EVENT_UNIT_INDEX])
// Handle TriggerRegisterUnitIndexEvent
set E = EVENT_UNIT_INDEX
// Reset so the event can occur again
set E = -1
endif
endif
set u = null
return false
endmethod
private static method onLeave takes nothing returns boolean
local unit u
local integer i
// Check if order is undefend.
if (thistype.Enabled and GetIssuedOrderId() == 852056) then
set u = GetTriggerUnit()
// If unit was killed (not removed) then don't continue
if (GetUnitAbilityLevel(u, thistype.DETECT_LEAVE_ABILITY) != 0) then
set u = null
return false
endif
set i = GetUnitId(u)
// If unit has been indexed then deindex it
if (i > 0 and i <= Counter and u == GetUnitById(i)) then
// Recycle the index
set List[i] = Index
set Index = i
set LastIndex = i
// Remove to group of indexed units
call GroupRemoveUnit(thistype.Group, u)
// Execute custom events without any associated triggers
call TriggerEvaluate(IndexTrig[EVENT_UNIT_DEINDEX])
// Handle TriggerRegisterUnitIndexEvent
set E = EVENT_UNIT_DEINDEX
// Remove entry
call SetUnitUserData(u, 0)
set thistype.Unit[i] = null
// Decrement unit count
set Count = Count - 1
// Reset so the event can occur again
set E = -1
endif
set u = null
endif
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
local player p
local unit u
static if (not LIBRARY_WorldBounds) then // Check if WorldBounts exists, if not then define the necessary vars
local region reg = CreateRegion() // If WorldBounds wasn't found, create the region manually
local rect world = GetWorldBounds()
endif
set FilterEnter = Filter(function thistype.onEnter)
// Begin to index units when they enter the map
static if (LIBRARY_WorldBounds) then
call TriggerRegisterEnterRegion(CreateTrigger(), WorldBounds.worldRegion, FilterEnter)
else
call RegionAddRect(reg, world)
call TriggerRegisterEnterRegion(CreateTrigger(), reg, FilterEnter)
call RemoveRect(world)
set world = null
endif
call TriggerAddCondition(t, Filter(function thistype.onLeave))
set IndexTrig[EVENT_UNIT_INDEX] = CreateTrigger()
set IndexTrig[EVENT_UNIT_DEINDEX] = CreateTrigger()
loop
set p = Player(i)
// Detect "undefend"
call TriggerRegisterPlayerUnitEvent(t, p, EVENT_PLAYER_UNIT_ISSUED_ORDER, null)
// Hide the detect ability from players
call SetPlayerAbilityAvailable(p, thistype.DETECT_LEAVE_ABILITY, false)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TimerStart(CreateTimer(), 0, false, function thistype.onGameStart)
endmethod
endmodule
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library List /* v1.0.0.3
************************************************************************************
*
* */uses/*
*
* */ ErrorMessage /* hiveworkshop.com/forums/submissions-414/snippet-error-message-239210/
*
************************************************************************************
*
* module List
*
* Description
* -------------------------
*
* NA
*
* Fields
* -------------------------
*
* readonly static integer sentinel
*
* readonly thistype list
*
* readonly thistype first
* readonly thistype last
*
* readonly thistype next
* readonly thistype prev
*
* Methods
* -------------------------
*
* static method create takes nothing returns thistype
* method destroy takes nothing returns nothing
* - May only destroy lists
*
* method push takes nothing returns thistype
* method enqueue takes nothing returns thistype
*
* method pop takes nothing returns nothing
* method dequeue takes nothing returns nothing
*
* method remove takes nothing returns nothing
*
* method clear takes nothing returns nothing
*
* debug static method calculateMemoryUsage takes nothing returns integer
* debug static method getAllocatedMemoryAsString takes nothing returns string
*
************************************************************************************/
module List
private static thistype collectionCount = 0
private static thistype nodeCount = 0
debug private boolean isNode
debug private boolean isCollection
private thistype _list
method operator list takes nothing returns thistype
debug call ThrowError(this == 0, "List", "list", "thistype", this, "Attempted To Read Null Node.")
debug call ThrowError(not isNode, "List", "list", "thistype", this, "Attempted To Read Invalid Node.")
return _list
endmethod
private thistype _next
method operator next takes nothing returns thistype
debug call ThrowError(this == 0, "List", "next", "thistype", this, "Attempted To Go Out Of Bounds.")
debug call ThrowError(not isNode, "List", "next", "thistype", this, "Attempted To Read Invalid Node.")
return _next
endmethod
private thistype _prev
method operator prev takes nothing returns thistype
debug call ThrowError(this == 0, "List", "prev", "thistype", this, "Attempted To Go Out Of Bounds.")
debug call ThrowError(not isNode, "List", "prev", "thistype", this, "Attempted To Read Invalid Node.")
return _prev
endmethod
private thistype _first
method operator first takes nothing returns thistype
debug call ThrowError(this == 0, "List", "first", "thistype", this, "Attempted To Read Null List.")
debug call ThrowError(not isCollection, "List", "first", "thistype", this, "Attempted To Read Invalid List.")
return _first
endmethod
private thistype _last
method operator last takes nothing returns thistype
debug call ThrowError(this == 0, "List", "last", "thistype", this, "Attempted To Read Null List.")
debug call ThrowError(not isCollection, "List", "last", "thistype", this, "Attempted To Read Invalid List.")
return _last
endmethod
static method operator sentinel takes nothing returns integer
return 0
endmethod
private static method allocateCollection takes nothing returns thistype
local thistype this = thistype(0)._first
if (0 == this) then
debug call ThrowError(collectionCount == 8191, "List", "allocateCollection", "thistype", 0, "Overflow.")
set this = collectionCount + 1
set collectionCount = this
else
set thistype(0)._first = _first
endif
return this
endmethod
private static method allocateNode takes nothing returns thistype
local thistype this = thistype(0)._next
if (0 == this) then
debug call ThrowError(nodeCount == 8191, "List", "allocateNode", "thistype", 0, "Overflow.")
set this = nodeCount + 1
set nodeCount = this
else
set thistype(0)._next = _next
endif
return this
endmethod
static method create takes nothing returns thistype
local thistype this = allocateCollection()
debug set isCollection = true
set _first = 0
return this
endmethod
method push takes nothing returns thistype
local thistype node = allocateNode()
debug call ThrowError(this == 0, "List", "push", "thistype", this, "Attempted To Push On To Null List.")
debug call ThrowError(not isCollection, "List", "push", "thistype", this, "Attempted To Push On To Invalid List.")
debug set node.isNode = true
set node._list = this
if (_first == 0) then
set _first = node
set _last = node
set node._next = 0
else
set _first._prev = node
set node._next = _first
set _first = node
endif
set node._prev = 0
return node
endmethod
method enqueue takes nothing returns thistype
local thistype node = allocateNode()
debug call ThrowError(this == 0, "List", "enqueue", "thistype", this, "Attempted To Enqueue On To Null List.")
debug call ThrowError(not isCollection, "List", "enqueue", "thistype", this, "Attempted To Enqueue On To Invalid List.")
debug set node.isNode = true
set node._list = this
if (_first == 0) then
set _first = node
set _last = node
set node._prev = 0
else
set _last._next = node
set node._prev = _last
set _last = node
endif
set node._next = 0
return node
endmethod
method pop takes nothing returns nothing
local thistype node = _first
debug call ThrowError(this == 0, "List", "pop", "thistype", this, "Attempted To Pop Null List.")
debug call ThrowError(not isCollection, "List", "pop", "thistype", this, "Attempted To Pop Invalid List.")
debug call ThrowError(node == 0, "List", "pop", "thistype", this, "Attempted To Pop Empty List.")
debug set node.isNode = false
set _first._list = 0
set _first = _first._next
if (_first == 0) then
set _last = 0
else
set _first._prev = 0
endif
set node._next = thistype(0)._next
set thistype(0)._next = node
endmethod
method dequeue takes nothing returns nothing
local thistype node = _last
debug call ThrowError(this == 0, "List", "dequeue", "thistype", this, "Attempted To Dequeue Null List.")
debug call ThrowError(not isCollection, "List", "dequeue", "thistype", this, "Attempted To Dequeue Invalid List.")
debug call ThrowError(node == 0, "List", "dequeue", "thistype", this, "Attempted To Dequeue Empty List.")
debug set node.isNode = false
set _last._list = 0
set _last = _last._prev
if (_last == 0) then
set _first = 0
else
set _last._next = 0
endif
set node._next = thistype(0)._next
set thistype(0)._next = node
endmethod
method remove takes nothing returns nothing
local thistype node = this
set this = node._list
debug call ThrowError(node == 0, "List", "remove", "thistype", this, "Attempted To Remove Null Node.")
debug call ThrowError(not node.isNode, "List", "remove", "thistype", this, "Attempted To Remove Invalid Node (" + I2S(node) + ").")
debug set node.isNode = false
set node._list = 0
if (0 == node._prev) then
set _first = node._next
else
set node._prev._next = node._next
endif
if (0 == node._next) then
set _last = node._prev
else
set node._next._prev = node._prev
endif
set node._next = thistype(0)._next
set thistype(0)._next = node
endmethod
method clear takes nothing returns nothing
debug local thistype node = _first
debug call ThrowError(this == 0, "List", "clear", "thistype", this, "Attempted To Clear Null List.")
debug call ThrowError(not isCollection, "List", "clear", "thistype", this, "Attempted To Clear Invalid List.")
static if DEBUG_MODE then
loop
exitwhen node == 0
set node.isNode = false
set node = node._next
endloop
endif
if (_first == 0) then
return
endif
set _last._next = thistype(0)._next
set thistype(0)._next = _first
set _first = 0
set _last = 0
endmethod
method destroy takes nothing returns nothing
debug call ThrowError(this == 0, "List", "destroy", "thistype", this, "Attempted To Destroy Null List.")
debug call ThrowError(not isCollection, "List", "destroy", "thistype", this, "Attempted To Destroy Invalid List.")
static if DEBUG_MODE then
debug call clear()
debug set isCollection = false
else
if (_first != 0) then
set _last._next = thistype(0)._next
set thistype(0)._next = _first
set _last = 0
endif
endif
set _first = thistype(0)._first
set thistype(0)._first = this
endmethod
static if DEBUG_MODE then
static method calculateMemoryUsage takes nothing returns integer
local thistype start = 1
local thistype end = 8191
local integer count = 0
loop
exitwhen integer(start) > integer(end)
if (integer(start) + 500 > integer(end)) then
return count + checkRegion(start, end)
else
set count = count + checkRegion(start, start + 500)
set start = start + 501
endif
endloop
return count
endmethod
private static method checkRegion takes thistype start, thistype end returns integer
local integer count = 0
loop
exitwhen integer(start) > integer(end)
if (start.isNode) then
set count = count + 1
endif
if (start.isCollection) then
set count = count + 1
endif
set start = start + 1
endloop
return count
endmethod
static method getAllocatedMemoryAsString takes nothing returns string
local thistype start = 1
local thistype end = 8191
local string memory = null
loop
exitwhen integer(start) > integer(end)
if (integer(start) + 500 > integer(end)) then
if (memory != null) then
set memory = memory + ", "
endif
set memory = memory + checkRegion2(start, end)
set start = end + 1
else
if (memory != null) then
set memory = memory + ", "
endif
set memory = memory + checkRegion2(start, start + 500)
set start = start + 501
endif
endloop
return memory
endmethod
private static method checkRegion2 takes thistype start, thistype end returns string
local string memory = null
loop
exitwhen integer(start) > integer(end)
if (start.isNode) then
if (memory == null) then
set memory = I2S(start)
else
set memory = memory + ", " + I2S(start) + "N"
endif
endif
if (start.isCollection) then
if (memory == null) then
set memory = I2S(start)
else
set memory = memory + ", " + I2S(start) + "C"
endif
endif
set start = start + 1
endloop
return memory
endmethod
endif
endmodule
endlibrary
//TESH.scrollpos=382
//TESH.alwaysfold=0
library Table /* made by Bribe, special thanks to Vexorian & Nestharus, version 3.1.1.0
One map, one hashtable. Welcome to NewTable 3.1
This library was originally called NewTable so it didn't conflict with
the API of Table by Vexorian. However, the damage is done and it's too
late to change the library name now. To help with damage control, I
have provided an extension library called TableBC, which bridges all
the functionality of Vexorian's Table except for 2-D string arrays &
the ".flush(integer)" method. I use ".flush()" to flush a child hash-
table, because I wanted the API in NewTable to reflect the API of real
hashtables (I thought this would be more intuitive).
API
------------
struct Table
| static method create takes nothing returns Table
| create a new Table
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush all stored values inside of it
|
| method remove takes integer key returns nothing
| remove the value at index "key"
|
| method operator []= takes integer key, $TYPE$ value returns nothing
| assign "value" to index "key"
|
| method operator [] takes integer key returns $TYPE$
| load the value at index "key"
|
| method has takes integer key returns boolean
| whether or not the key was assigned
|
----------------
struct TableArray
| static method operator [] takes integer array_size returns TableArray
| create a new array of Tables of size "array_size"
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush and destroy it
|
| method operator size takes nothing returns integer
| returns the size of the TableArray
|
| method operator [] takes integer key returns Table
| returns a Table accessible exclusively to index "key"
*/
globals
private integer less = 0 //Index generation for TableArrays (below 0).
private integer more = 8190 //Index generation for Tables.
//Configure it if you use more than 8190 "key" variables in your map (this will never happen though).
private hashtable ht = InitHashtable()
private key sizeK
private key listK
endglobals
private struct dex extends array
static method operator size takes nothing returns Table
return sizeK
endmethod
static method operator list takes nothing returns Table
return listK
endmethod
endstruct
private struct handles extends array
method has takes integer key returns boolean
return HaveSavedHandle(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedHandle(ht, this, key)
endmethod
endstruct
private struct agents extends array
method operator []= takes integer key, agent value returns nothing
call SaveAgentHandle(ht, this, key, value)
endmethod
endstruct
//! textmacro NEW_ARRAY_BASIC takes SUPER, FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$(ht, this, key, value)
endmethod
method has takes integer key returns boolean
return HaveSaved$SUPER$(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSaved$SUPER$(ht, this, key)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//! textmacro NEW_ARRAY takes FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$Handle(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$Handle(ht, this, key, value)
endmethod
method has takes integer key returns boolean
return HaveSavedHandle(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedHandle(ht, this, key)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//Run these textmacros to include the entire hashtable API as wrappers.
//Don't be intimidated by the number of macros - Vexorian's map optimizer is
//supposed to kill functions which inline (all of these functions inline).
//! runtextmacro NEW_ARRAY_BASIC("Real", "Real", "real")
//! runtextmacro NEW_ARRAY_BASIC("Boolean", "Boolean", "boolean")
//! runtextmacro NEW_ARRAY_BASIC("String", "Str", "string")
//New textmacro to allow table.integer[] syntax for compatibility with textmacros that might desire it.
//! runtextmacro NEW_ARRAY_BASIC("Integer", "Integer", "integer")
//! runtextmacro NEW_ARRAY("Player", "player")
//! runtextmacro NEW_ARRAY("Widget", "widget")
//! runtextmacro NEW_ARRAY("Destructable", "destructable")
//! runtextmacro NEW_ARRAY("Item", "item")
//! runtextmacro NEW_ARRAY("Unit", "unit")
//! runtextmacro NEW_ARRAY("Ability", "ability")
//! runtextmacro NEW_ARRAY("Timer", "timer")
//! runtextmacro NEW_ARRAY("Trigger", "trigger")
//! runtextmacro NEW_ARRAY("TriggerCondition", "triggercondition")
//! runtextmacro NEW_ARRAY("TriggerAction", "triggeraction")
//! runtextmacro NEW_ARRAY("TriggerEvent", "event")
//! runtextmacro NEW_ARRAY("Force", "force")
//! runtextmacro NEW_ARRAY("Group", "group")
//! runtextmacro NEW_ARRAY("Location", "location")
//! runtextmacro NEW_ARRAY("Rect", "rect")
//! runtextmacro NEW_ARRAY("BooleanExpr", "boolexpr")
//! runtextmacro NEW_ARRAY("Sound", "sound")
//! runtextmacro NEW_ARRAY("Effect", "effect")
//! runtextmacro NEW_ARRAY("UnitPool", "unitpool")
//! runtextmacro NEW_ARRAY("ItemPool", "itempool")
//! runtextmacro NEW_ARRAY("Quest", "quest")
//! runtextmacro NEW_ARRAY("QuestItem", "questitem")
//! runtextmacro NEW_ARRAY("DefeatCondition", "defeatcondition")
//! runtextmacro NEW_ARRAY("TimerDialog", "timerdialog")
//! runtextmacro NEW_ARRAY("Leaderboard", "leaderboard")
//! runtextmacro NEW_ARRAY("Multiboard", "multiboard")
//! runtextmacro NEW_ARRAY("MultiboardItem", "multiboarditem")
//! runtextmacro NEW_ARRAY("Trackable", "trackable")
//! runtextmacro NEW_ARRAY("Dialog", "dialog")
//! runtextmacro NEW_ARRAY("Button", "button")
//! runtextmacro NEW_ARRAY("TextTag", "texttag")
//! runtextmacro NEW_ARRAY("Lightning", "lightning")
//! runtextmacro NEW_ARRAY("Image", "image")
//! runtextmacro NEW_ARRAY("Ubersplat", "ubersplat")
//! runtextmacro NEW_ARRAY("Region", "region")
//! runtextmacro NEW_ARRAY("FogState", "fogstate")
//! runtextmacro NEW_ARRAY("FogModifier", "fogmodifier")
//! runtextmacro NEW_ARRAY("Hashtable", "hashtable")
struct Table extends array
// Implement modules for intuitive syntax (tb.handle; tb.unit; etc.)
implement realm
implement integerm
implement booleanm
implement stringm
implement playerm
implement widgetm
implement destructablem
implement itemm
implement unitm
implement abilitym
implement timerm
implement triggerm
implement triggerconditionm
implement triggeractionm
implement eventm
implement forcem
implement groupm
implement locationm
implement rectm
implement boolexprm
implement soundm
implement effectm
implement unitpoolm
implement itempoolm
implement questm
implement questitemm
implement defeatconditionm
implement timerdialogm
implement leaderboardm
implement multiboardm
implement multiboarditemm
implement trackablem
implement dialogm
implement buttonm
implement texttagm
implement lightningm
implement imagem
implement ubersplatm
implement regionm
implement fogstatem
implement fogmodifierm
implement hashtablem
method operator handle takes nothing returns handles
return this
endmethod
method operator agent takes nothing returns agents
return this
endmethod
//set this = tb[GetSpellAbilityId()]
method operator [] takes integer key returns Table
return LoadInteger(ht, this, key) //return this.integer[key]
endmethod
//set tb[389034] = 8192
method operator []= takes integer key, Table tb returns nothing
call SaveInteger(ht, this, key, tb) //set this.integer[key] = tb
endmethod
//set b = tb.has(2493223)
method has takes integer key returns boolean
return HaveSavedInteger(ht, this, key) //return this.integer.has(key)
endmethod
//call tb.remove(294080)
method remove takes integer key returns nothing
call RemoveSavedInteger(ht, this, key) //call this.integer.remove(key)
endmethod
//Remove all data from a Table instance
method flush takes nothing returns nothing
call FlushChildHashtable(ht, this)
endmethod
//local Table tb = Table.create()
static method create takes nothing returns Table
local Table this = dex.list[0]
if this == 0 then
set this = more + 1
set more = this
else
set dex.list[0] = dex.list[this]
call dex.list.remove(this) //Clear hashed memory
endif
debug set dex.list[this] = -1
return this
endmethod
// Removes all data from a Table instance and recycles its index.
//
// call tb.destroy()
//
method destroy takes nothing returns nothing
debug if dex.list[this] != -1 then
debug call BJDebugMsg("Table Error: Tried to double-free instance: " + I2S(this))
debug return
debug endif
call this.flush()
set dex.list[this] = dex.list[0]
set dex.list[0] = this
endmethod
//! runtextmacro optional TABLE_BC_METHODS()
endstruct
//! runtextmacro optional TABLE_BC_STRUCTS()
struct TableArray extends array
//Returns a new TableArray to do your bidding. Simply use:
//
// local TableArray ta = TableArray[array_size]
//
static method operator [] takes integer array_size returns TableArray
local Table tb = dex.size[array_size] //Get the unique recycle list for this array size
local TableArray this = tb[0] //The last-destroyed TableArray that had this array size
debug if array_size <= 0 then
debug call BJDebugMsg("TypeError: Invalid specified TableArray size: " + I2S(array_size))
debug return 0
debug endif
if this == 0 then
set this = less - array_size
set less = this
else
set tb[0] = tb[this] //Set the last destroyed to the last-last destroyed
call tb.remove(this) //Clear hashed memory
endif
set dex.size[this] = array_size //This remembers the array size
return this
endmethod
//Returns the size of the TableArray
method operator size takes nothing returns integer
return dex.size[this]
endmethod
//This magic method enables two-dimensional[array][syntax] for Tables,
//similar to the two-dimensional utility provided by hashtables them-
//selves.
//
//ta[integer a].unit[integer b] = unit u
//ta[integer a][integer c] = integer d
//
//Inline-friendly when not running in debug mode
//
method operator [] takes integer key returns Table
static if DEBUG_MODE then
local integer i = this.size
if i == 0 then
call BJDebugMsg("IndexError: Tried to get key from invalid TableArray instance: " + I2S(this))
return 0
elseif key < 0 or key >= i then
call BJDebugMsg("IndexError: Tried to get key [" + I2S(key) + "] from outside TableArray bounds: " + I2S(i))
return 0
endif
endif
return this + key
endmethod
//Destroys a TableArray without flushing it; I assume you call .flush()
//if you want it flushed too. This is a public method so that you don't
//have to loop through all TableArray indices to flush them if you don't
//need to (ie. if you were flushing all child-keys as you used them).
//
method destroy takes nothing returns nothing
local Table tb = dex.size[this.size]
debug if this.size == 0 then
debug call BJDebugMsg("TypeError: Tried to destroy an invalid TableArray: " + I2S(this))
debug return
debug endif
if tb == 0 then
//Create a Table to index recycled instances with their array size
set tb = Table.create()
set dex.size[this.size] = tb
endif
call dex.size.remove(this) //Clear the array size from hash memory
set tb[this] = tb[0]
set tb[0] = this
endmethod
private static Table tempTable
private static integer tempEnd
//Avoids hitting the op limit
private static method clean takes nothing returns nothing
local Table tb = .tempTable
local integer end = tb + 0x1000
if end < .tempEnd then
set .tempTable = end
call ForForce(bj_FORCE_PLAYER[0], function thistype.clean)
else
set end = .tempEnd
endif
loop
call tb.flush()
set tb = tb + 1
exitwhen tb == end
endloop
endmethod
//Flushes the TableArray and also destroys it. Doesn't get any more
//similar to the FlushParentHashtable native than this.
//
method flush takes nothing returns nothing
debug if this.size == 0 then
debug call BJDebugMsg("TypeError: Tried to flush an invalid TableArray instance: " + I2S(this))
debug return
debug endif
set .tempTable = this
set .tempEnd = this + this.size
call ForForce(bj_FORCE_PLAYER[0], function thistype.clean)
call this.destroy()
endmethod
endstruct
endlibrary
//TESH.scrollpos=9
//TESH.alwaysfold=0
library ErrorMessage /* v1.0.1.4
*************************************************************************************
*
* Issue Compliant Error Messages
*
************************************************************************************
*
* debug function ThrowError takes boolean expression, string libraryName, string functionName, string objectName, integer objectInstance, string description returns nothing
* - In the event of an error the game will be permanently paused
*
* debug function ThrowWarning takes boolean expression, string libraryName, string functionName, string objectName, integer objectInstance, string description returns nothing
*
************************************************************************************/
static if DEBUG_MODE then
private struct Fields extends array
static constant string COLOR_RED = "|cffff0000"
static constant string COLOR_YELLOW = "|cffffff00"
static string lastError = null
endstruct
private function Pause takes nothing returns nothing
call PauseGame(true)
endfunction
private function ThrowMessage takes string libraryName, string functionName, string objectName, integer objectInstance, string description, string errorType, string color returns nothing
local string str
local string color_braces = "|cff66FF99"
local string orange = "|cffff6600"
set str = "->\n-> " + color_braces + "{|r " + "Library" + color_braces + "(" + orange + libraryName + color_braces + ")"
if (objectName != null) then
if (objectInstance > 0) then
set str = str + "|r.Object" + color_braces + "(" + orange + objectName + color_braces + " (|rinstance = " + orange + I2S(objectInstance) + color_braces + ") )" + "|r." + "Method" + color_braces + "(" + orange + functionName + color_braces + ")"
else
set str = str + "|r.Object" + color_braces + "(" + orange + objectName + color_braces + ")|r." + "Method" + color_braces + "(" + orange + functionName + color_braces + ")"
endif
else
set str = str + "|r." + "Function" + color_braces + "(" + orange + functionName + color_braces + ")"
endif
set str = str + color_braces + " }|r " + "has thrown an exception of type " + color_braces + "(" + color + errorType + color_braces + ")|r."
set Fields.lastError = str + "\n->\n" + "-> " + color + description + "|r\n->"
endfunction
function ThrowError takes boolean expression, string libraryName, string functionName, string objectName, integer objectInstance, string description returns nothing
if (Fields.lastError != null) then
set objectInstance = 1/0
endif
if (expression) then
call ThrowMessage(libraryName, functionName, objectName, objectInstance, description, "Error", Fields.COLOR_RED)
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60000,Fields.lastError)
call TimerStart(CreateTimer(), 0, true, function Pause)
set objectInstance = 1/0
endif
endfunction
function ThrowWarning takes boolean expression, string libraryName, string functionName, string objectName, integer objectInstance, string description returns nothing
if (Fields.lastError != null) then
set objectInstance = 1/0
endif
if (expression) then
call ThrowMessage(libraryName, functionName, objectName, objectInstance, description, "Warning", Fields.COLOR_YELLOW)
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60000,Fields.lastError)
set Fields.lastError = null
endif
endfunction
endif
endlibrary
//TESH.scrollpos=45
//TESH.alwaysfold=0
scope UnitScaleDemo initializer Init
globals
private unit target = null
private constant real DURATION = 2
endglobals
private function onAdd takes nothing returns nothing
local real scale = S2R(SubString(GetEventPlayerChatString(), 5, StringLength(GetEventPlayerChatString())))
local UnitScaleData scaleData = UnitScale[target].apply(GetUnitScale(target) + scale, DURATION)
endfunction
private function onSet takes nothing returns nothing
local real scale = S2R(SubString(GetEventPlayerChatString(), 5, StringLength(GetEventPlayerChatString())))
call UnitScale[target].apply(scale, DURATION)
endfunction
private function onSelect takes nothing returns nothing
set target = GetTriggerUnit()
return
call BJDebugMsg("UnitScale: " + R2S(GetUnitScale(target)) )
call BJDebugMsg("UnitDefaultScale: " + R2S(GetUnitDefaultScale(target)) )
endfunction
private function onHelp takes nothing returns nothing
call BJDebugMsg("Select a unit and use commands:
-add x
-set x
-clear")
endfunction
private function onClear takes nothing returns nothing
call ClearTextMessages()
endfunction
private function callback takes nothing returns nothing
if target != null then
call ClearTextMessages()
call BJDebugMsg("UnitScale: " + R2S(GetUnitScale(target)) )
call BJDebugMsg("UnitDefaultScale: " + R2S(GetUnitDefaultScale(target)) )
endif
endfunction
private function Init takes nothing returns nothing
local trigger t
local player p = Player(0)
set t = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(t, p, EVENT_PLAYER_UNIT_SELECTED, null)
call TriggerAddAction(t, function onSelect )
set t = CreateTrigger( )
call TriggerRegisterPlayerChatEvent(t, p, "-set ", false )
call TriggerAddAction(t, function onSet )
set t = CreateTrigger( )
call TriggerRegisterPlayerChatEvent(t, p, "-add ", false )
call TriggerAddAction(t, function onAdd )
set t = CreateTrigger( )
call TriggerRegisterPlayerChatEvent(t, p, "-h", true )
call TriggerRegisterPlayerChatEvent(t, p, "-help", true )
call TriggerAddAction(t, function onHelp )
set t = CreateTrigger( )
call TriggerRegisterPlayerChatEvent(t, p, "-c", true )
call TriggerRegisterPlayerChatEvent(t, p, "-clear", true )
call TriggerAddAction(t, function onClear )
call TimerStart(CreateTimer(), 0.2, true, function callback)
call FogEnable(false)
call FogMaskEnable(false)
call SetFloatGameState(GAME_STATE_TIME_OF_DAY, bj_MELEE_STARTING_TOD)
call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 2000.00, 0)
call BJDebugMsg("Write -h or -help")
endfunction
endscope