Name | Type | is_array | initial_value |
Players | force | No |
library HeroReviveCancelEvent /* v1.1 -- hiveworkshop.com/threads/herorevivecancelevent.293491/#resource-72550
Information
¯¯¯¯¯¯¯¯¯¯¯¯
Provides an event that fires when a player cancels a hero revival at the altar.
When using this system, you don't need the default event EVENT_PLAYER_HERO_REVIVE_CANCEL anymore.
Mechanics
¯¯¯¯¯¯¯¯¯¯
(Issue:)
The default problem is that EVENT_PLAYER_HERO_REVIVE_CANCEL will only fire when using
the "Cancel" spell, but not when directly clicking on the hero icon in training queue.
(Solution:)
When a hero starts reviving process, so enters the queue, we periodicly order the altar to try to 'revive'
the hero. Normaly this order will return "false", as the hero is already being revived, but once it returns "true"
we know, that the hero must not be in queue anymore. Then we fire the event.
This method will work for both, when the "Cancel" spell is used, and when the hero icon is clicked in queue.
*/
// ====API ====
//! novjass
struct HeroReviveCancelEvent
// register code
static method register takes code c returns nothing
static method unregister takes code c returns nothing
// Inside registered code, you can access data:
static thistype instance
readonly unit hero // hero that was reviving
readonly unit building // altar for revival
//! endnovjass
// ===== End API ====
native UnitAlive takes unit u returns boolean
struct HeroReviveCancelEvent
private static constant integer REVIVE_ORDER_ID_OFFSET = 852027
private static constant integer CANCEL_ORDER_ID = 851976
private static constant integer MAX_HERO_AMOUNT = 4
private static constant real TIMEOUT = 0.1
private static hashtable hash = InitHashtable()
private static trigger handler = CreateTrigger()
readonly static thistype instance
readonly unit hero
readonly unit building
private timer clock
private player owner
private boolean exists
private method destroy takes nothing returns nothing
if .exists then
set .exists = false
call RemoveSavedInteger(hash, GetHandleId(.clock), 0)
call RemoveSavedInteger(hash, GetHandleId(.hero), 0)
call DestroyTimer(.clock)
set .clock = null
set .hero = null
set .building = null
call .deallocate()
endif
endmethod
private static method callback takes nothing returns nothing
local integer food
local integer gold
local integer lumber
local thistype this = LoadInteger(hash, GetHandleId(GetExpiredTimer()), 0)
if not UnitAlive(.building) or UnitAlive(.hero) then
call .destroy()
endif
// resources backup
set gold = GetPlayerState(.owner, PLAYER_STATE_RESOURCE_GOLD)
set lumber = GetPlayerState(.owner, PLAYER_STATE_RESOURCE_LUMBER)
set food = GetPlayerState(.owner, PLAYER_STATE_RESOURCE_FOOD_USED)
// give some conditions that will hopefully be always enough to successfuly order the revive order
call SetPlayerState(.owner, PLAYER_STATE_RESOURCE_GOLD, 1000000)
call SetPlayerState(.owner, PLAYER_STATE_RESOURCE_LUMBER, 1000000)
call SetPlayerState(.owner, PLAYER_STATE_RESOURCE_FOOD_USED, 0)
if IssueTargetOrder(.building, "revive", .hero) then
//
call IssueImmediateOrderById(.building, CANCEL_ORDER_ID)
// retrieve original resources before the handler is fired
call SetPlayerState(.owner, PLAYER_STATE_RESOURCE_GOLD, gold)
call SetPlayerState(.owner, PLAYER_STATE_RESOURCE_LUMBER, lumber)
call SetPlayerState(.owner, PLAYER_STATE_RESOURCE_FOOD_USED, food)
// fire event
set instance = this
call TriggerEvaluate(.handler)
call .destroy()
return
endif
// retrieve original resources
call SetPlayerState(.owner, PLAYER_STATE_RESOURCE_GOLD, gold)
call SetPlayerState(.owner, PLAYER_STATE_RESOURCE_LUMBER, lumber)
call SetPlayerState(.owner, PLAYER_STATE_RESOURCE_FOOD_USED, food)
endmethod
private static method create takes unit b, unit h returns thistype
local thistype this = allocate()
set .exists = true
set .clock = CreateTimer()
set .hero = h
set .building = b
set .owner = GetOwningPlayer(h)
call TimerStart(.clock, TIMEOUT, true, function thistype.callback)
call SaveInteger(hash, GetHandleId(.clock), 0, this)
call SaveInteger(hash, GetHandleId(.hero), 0, this)
return this
endmethod
// hero gets into revive queue, so now we start periodicaly watching it
private static method onReviveStart takes nothing returns boolean
local integer orderId = GetIssuedOrderId()
if (orderId >= REVIVE_ORDER_ID_OFFSET and orderId <= REVIVE_ORDER_ID_OFFSET + MAX_HERO_AMOUNT) then
call create(GetOrderedUnit(), GetOrderTargetUnit())
endif
return false
endmethod
// instantly destroy instance when unit finished reviving
private static method onReviveFinish takes nothing returns boolean
call thistype(LoadInteger(hash, GetHandleId(GetTriggerUnit()), 0)).destroy()
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
call TriggerAddCondition(t, Condition(function thistype.onReviveStart))
set t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_REVIVE_FINISH )
call TriggerAddCondition(t, Condition(function thistype.onReviveFinish))
endmethod
// for API
public static method register takes code c returns nothing
local boolexpr bx = Condition(c)
call SaveTriggerConditionHandle(hash, GetHandleId(bx), 0, TriggerAddCondition(handler, bx))
set bx = null
endmethod
public static method unregister takes code c returns nothing
local boolexpr bx = Condition(c)
call TriggerRemoveCondition(handler, LoadTriggerConditionHandle(hash, GetHandleId(bx), 0))
call FlushChildHashtable(hash, GetHandleId(bx))
call DestroyBoolExpr(bx)
set bx = null
endmethod
endstruct
endlibrary
library FrameLoader initializer init_function
// in 1.31 and upto 1.32.9 PTR (when I wrote this). Frames are not correctly saved and loaded, breaking the game.
// This library runs all functions added to it with a 0s delay after the game was loaded.
// function FrameLoaderAdd takes code func returns nothing
// func runs when the game is loaded.
globals
private trigger eventTrigger = CreateTrigger()
private trigger actionTrigger = CreateTrigger()
private timer t = CreateTimer()
endglobals
function FrameLoaderAdd takes code func returns nothing
call TriggerAddAction(actionTrigger, func)
endfunction
private function timerAction takes nothing returns nothing
call TriggerExecute(actionTrigger)
endfunction
private function eventAction takes nothing returns nothing
call TimerStart(t, 0, false, function timerAction)
endfunction
private function init_function takes nothing returns nothing
call TriggerRegisterGameEvent(eventTrigger, EVENT_GAME_LOADED)
call TriggerAddAction(eventTrigger, function eventAction)
endfunction
endlibrary
library OrdersWatcher initializer Init
globals
private trigger orderTrigger
endglobals
private function TriggerConditionDebugOrder takes nothing returns boolean
local string order = OrderId2String(GetIssuedOrderId())
//return order != "move" and order != "harvest" and order != "stop" and order != "attack" and order != "resumeharvesting" and order != "smart" and order != "unsubmerge"
return true
endfunction
function GetOrderName takes integer orderId returns string
if (UnitId2String(orderId) != "" and UnitId2String(orderId) != null) then
return UnitId2String(orderId)
elseif (AbilityId2String(orderId) != "" and AbilityId2String(orderId) != null) then
return AbilityId2String(orderId)
endif
return OrderId2String(orderId)
endfunction
private function TriggerActionDebugOrder takes nothing returns nothing
if (GetOrderTargetUnit() != null) then
call BJDebugMsg(GetPlayerName(GetOwningPlayer(GetTriggerUnit())) + ": Issuing order with ID " + I2S(GetIssuedOrderId()) + " with name " + GetOrderName(GetIssuedOrderId()) + " for unit " + GetUnitName(GetTriggerUnit()) + " for target unit " + GetUnitName(GetOrderTargetUnit()))
elseif (GetOrderTargetDestructable() != null) then
call BJDebugMsg(GetPlayerName(GetOwningPlayer(GetTriggerUnit())) + ": Issuing order with ID " + I2S(GetIssuedOrderId()) + " with name " + GetOrderName(GetIssuedOrderId()) + " for unit " + GetUnitName(GetTriggerUnit()) + " for target destructible " + GetDestructableName(GetOrderTargetDestructable()))
elseif (GetOrderTargetItem() != null) then
call BJDebugMsg(GetPlayerName(GetOwningPlayer(GetTriggerUnit())) + ": Issuing order with ID " + I2S(GetIssuedOrderId()) + " with name " + GetOrderName(GetIssuedOrderId()) + " for unit " + GetUnitName(GetTriggerUnit()) + " for target item " + GetItemName(GetOrderTargetItem()))
else
call BJDebugMsg(GetPlayerName(GetOwningPlayer(GetTriggerUnit())) + ": Issuing order with ID " + I2S(GetIssuedOrderId()) + " with name " + GetOrderName(GetIssuedOrderId()) + " for unit " + GetUnitName(GetTriggerUnit()))
endif
endfunction
private function Init takes nothing returns nothing
set orderTrigger = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(orderTrigger, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerRegisterAnyUnitEventBJ(orderTrigger, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
call TriggerRegisterAnyUnitEventBJ(orderTrigger, EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerAddCondition(orderTrigger, Condition(function TriggerConditionDebugOrder))
call TriggerAddAction(orderTrigger, function TriggerActionDebugOrder)
endfunction
function EnableOrderDebugger takes nothing returns nothing
call EnableTrigger(orderTrigger)
endfunction
function DisableOrderDebugger takes nothing returns nothing
call DisableTrigger(orderTrigger)
endfunction
endlibrary
library HeroReviveEvents initializer Init requires HeroReviveCancelEvent
globals
public constant integer ORDER_ID_START_REVIVE = 852027
public constant integer ORDER_ID_REVIVE = 852039
private trigger orderTrigger = CreateTrigger()
private trigger startReviveTrigger = CreateTrigger()
private trigger finishReviveTrigger = CreateTrigger()
private group heroes = CreateGroup()
private hashtable h = InitHashtable()
private trigger array callbackOrderStartReviveTriggers
private integer callbackStartOrderStartTriggersCounter = 0
private trigger array callbackOrderCancelReviveTriggers
private integer callbackStartOrderCancelTriggersCounter = 0
private trigger array callbackStartReviveTriggers
private integer callbackStartReviveTriggersCounter = 0
private trigger array callbackFinishReviveTriggers
private integer callbackFinishReviveTriggersCounter = 0
private unit triggerReviveAltar = null
private unit triggerReviveHero = null
endglobals
function TriggerRegisterHeroReviveOrderStartEvent takes trigger whichTrigger returns nothing
set callbackOrderStartReviveTriggers[callbackStartOrderStartTriggersCounter] = whichTrigger
set callbackStartOrderStartTriggersCounter = callbackStartOrderStartTriggersCounter + 1
endfunction
function TriggerRegisterHeroReviveOrderCancelEvent takes trigger whichTrigger returns nothing
set callbackOrderCancelReviveTriggers[callbackStartOrderCancelTriggersCounter] = whichTrigger
set callbackStartOrderCancelTriggersCounter = callbackStartOrderCancelTriggersCounter + 1
endfunction
function TriggerRegisterHeroReviveStartEvent takes trigger whichTrigger returns nothing
set callbackStartReviveTriggers[callbackStartReviveTriggersCounter] = whichTrigger
set callbackStartReviveTriggersCounter = callbackStartReviveTriggersCounter + 1
endfunction
function TriggerRegisterHeroReviveFinishEvent takes trigger whichTrigger returns nothing
set callbackFinishReviveTriggers[callbackFinishReviveTriggersCounter] = whichTrigger
set callbackFinishReviveTriggersCounter = callbackFinishReviveTriggersCounter + 1
endfunction
function GetTriggerReviveAltar takes nothing returns unit
return triggerReviveAltar
endfunction
function GetTriggerReviveHero takes nothing returns unit
return triggerReviveHero
endfunction
private function ExecuteCallbacksOrderStartRevive takes unit altar, unit hero returns nothing
local integer i = 0
set triggerReviveAltar = altar
set triggerReviveHero = hero
loop
exitwhen (i == callbackStartOrderStartTriggersCounter)
if (IsTriggerEnabled(callbackOrderStartReviveTriggers[i])) then
call ConditionalTriggerExecute(callbackOrderStartReviveTriggers[i])
endif
set i = i + 1
endloop
endfunction
private function ExecuteCallbacksOrderCancelRevive takes unit altar, unit hero returns nothing
local integer i = 0
set triggerReviveAltar = altar
set triggerReviveHero = hero
loop
exitwhen (i == callbackStartOrderCancelTriggersCounter)
if (IsTriggerEnabled(callbackOrderCancelReviveTriggers[i])) then
call ConditionalTriggerExecute(callbackOrderCancelReviveTriggers[i])
endif
set i = i + 1
endloop
endfunction
private function ExecuteCallbacksStartRevive takes unit altar, unit hero returns nothing
local integer i = 0
set triggerReviveAltar = altar
set triggerReviveHero = hero
loop
exitwhen (i == callbackStartReviveTriggersCounter)
if (IsTriggerEnabled(callbackStartReviveTriggers[i])) then
call ConditionalTriggerExecute(callbackStartReviveTriggers[i])
endif
set i = i + 1
endloop
endfunction
private function ExecuteCallbacksFinishRevive takes unit altar, unit hero returns nothing
local integer i = 0
set triggerReviveAltar = altar
set triggerReviveHero = hero
loop
exitwhen (i == callbackFinishReviveTriggersCounter)
if (IsTriggerEnabled(callbackFinishReviveTriggers[i])) then
call ConditionalTriggerExecute(callbackFinishReviveTriggers[i])
endif
set i = i + 1
endloop
endfunction
private function TriggerConditionOrder takes nothing returns boolean
local unit altar = GetTriggerUnit()
local unit hero = GetOrderTargetUnit()
local integer orderId = GetIssuedOrderId()
//call BJDebugMsg("Order " + GetUnitName(altar) + " " + I2S(orderId) + " with target unit " + GetUnitName(hero))
// https://www.hiveworkshop.com/threads/getting-the-reviving-altar-for-event_unit_hero_revive_start.356746/#post-3645129
if (orderId == ORDER_ID_START_REVIVE) then
// save the corresponding altar for the hero
call SaveUnitHandle(h, GetHandleId(hero), 0, altar)
call ExecuteCallbacksOrderStartRevive(altar, hero)
elseif (orderId == ORDER_ID_REVIVE) then // works only with HeroReviveCancelEvent
call FlushChildHashtable(h, GetHandleId(hero))
call GroupRemoveUnit(heroes, hero)
call ExecuteCallbacksOrderCancelRevive(altar, hero)
endif
set altar = null
set hero = null
return false
endfunction
private function TriggerConditionStartRevive takes nothing returns boolean
local unit hero = GetRevivingUnit()
if (not IsUnitInGroup(hero, heroes)) then
call GroupAddUnit(heroes, hero)
// GetTriggerUnit is not the altar https://www.hiveworkshop.com/threads/getting-the-reviving-altar-for-event_unit_hero_revive_start.356746/
call ExecuteCallbacksStartRevive(LoadUnitHandle(h, GetHandleId(hero), 0), hero)
endif
set hero = null
return false
endfunction
private function TriggerConditionFinishRevive takes nothing returns boolean
local unit hero = GetRevivingUnit()
if (IsUnitInGroup(GetRevivingUnit(), heroes)) then
call GroupRemoveUnit(heroes, hero)
call ExecuteCallbacksFinishRevive(LoadUnitHandle(h, GetHandleId(hero), 0), hero)
call FlushChildHashtable(h, GetHandleId(hero))
endif
set hero = null
return false
endfunction
private function Init takes nothing returns nothing
call TriggerRegisterAnyUnitEventBJ(orderTrigger, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerRegisterAnyUnitEventBJ(orderTrigger, EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerAddCondition(orderTrigger, Condition(function TriggerConditionOrder))
call TriggerRegisterAnyUnitEventBJ(startReviveTrigger, EVENT_PLAYER_HERO_REVIVE_START)
call TriggerAddCondition(startReviveTrigger, Condition(function TriggerConditionStartRevive))
call TriggerRegisterAnyUnitEventBJ(finishReviveTrigger, EVENT_PLAYER_HERO_REVIVE_FINISH)
call TriggerAddCondition(finishReviveTrigger, Condition(function TriggerConditionFinishRevive))
endfunction
private function RemoveUnitHook takes unit whichUnit returns nothing
call FlushChildHashtable(h, GetHandleId(whichUnit))
if (IsUnitInGroup(whichUnit, heroes)) then
call GroupRemoveUnit(heroes, whichUnit)
endif
endfunction
hook RemoveUnit RemoveUnitHook
endlibrary
library Queue initializer Init requires optional HeroReviveEvents
globals
// This is an indicator for an invalid ObjectName. It has to be the same for every language to avoid desyncs.
private constant string EMPTY_STRING = "Default string"
private trigger cancelTrainTrigger = CreateTrigger()
private trigger finishTrainTrigger = CreateTrigger()
private trigger cancelResearchTrigger = CreateTrigger()
private trigger finishResearchTrigger = CreateTrigger()
private trigger cancelUpgradeTrigger = CreateTrigger()
private trigger finishUpgradeTrigger = CreateTrigger()
private trigger startConstructTrigger = CreateTrigger()
private trigger finishConstructTrigger = CreateTrigger()
private trigger orderReviveStartTrigger = CreateTrigger()
private trigger orderReviveCancelTrigger = CreateTrigger()
private trigger finishReviveTrigger = CreateTrigger()
private trigger orderTrigger = CreateTrigger()
private trigger deathTrigger = CreateTrigger()
private Queue array playerQueue
private boolean array isEnabledForPlayer
private hashtable h = InitHashtable()
private group constructions = CreateGroup()
private group ignored = CreateGroup()
// callbacks
private trigger array callbackTriggers
private integer callbackTriggersCount = 0
private unit triggerUnit = null
private integer triggerId = 0
endglobals
struct Queue
integer id
group sources = CreateGroup()
integer counter = 0
Queue previous = 0
Queue next = 0
method onDestroy takes nothing returns nothing
if (this.next != 0) then
set this.next.previous = this.previous
endif
if (this.previous != 0) then
set this.previous.next = this.next
endif
call GroupClear(sources)
call DestroyGroup(sources)
set sources = null
endmethod
endstruct
function IsQueueEnabledForPlayer takes player whichPlayer returns boolean
return isEnabledForPlayer[GetPlayerId(whichPlayer)]
endfunction
function SetQueueEnabledForPlayer takes player whichPlayer, boolean enabled returns nothing
set isEnabledForPlayer[GetPlayerId(whichPlayer)] = enabled
endfunction
function IgnoreQueueUnit takes unit whichUnit returns nothing
call GroupAddUnit(ignored, whichUnit)
endfunction
function UnignoreQueueUnit takes unit whichUnit returns nothing
call GroupRemoveUnit(ignored, whichUnit)
endfunction
function IsQueueUnitIgnored takes unit whichUnit returns boolean
return IsUnitInGroup(whichUnit, ignored)
endfunction
private function SetSourceCounter takes unit source, integer id, integer count returns nothing
call SaveInteger(h, GetHandleId(source), id, count)
endfunction
private function GetSourceCounter takes unit source, integer id returns integer
return LoadInteger(h, GetHandleId(source), id)
endfunction
private function ClearSourceCounter takes unit source returns nothing
call FlushChildHashtable(h, GetHandleId(source))
endfunction
function GetTriggerQueueUnit takes nothing returns unit
return triggerUnit
endfunction
function GetTriggerQueueId takes nothing returns integer
return triggerId
endfunction
function TriggerRegisterQueueEvent takes trigger whichTrigger returns nothing
set callbackTriggers[callbackTriggersCount] = whichTrigger
set callbackTriggersCount = callbackTriggersCount + 1
endfunction
private function ExecuteTriggerCallbacks takes unit whichUnit, integer id returns nothing
local integer i = 0
loop
exitwhen (i == callbackTriggersCount)
if (IsTriggerEnabled(callbackTriggers[i])) then
set triggerUnit = whichUnit
set triggerId = id
call ConditionalTriggerExecute(callbackTriggers[i])
endif
set i = i + 1
endloop
endfunction
function GetPlayerQueue takes player whichPlayer returns Queue
return playerQueue[GetPlayerId(whichPlayer)]
endfunction
function GetPlayerQueueByIndex takes player whichPlayer, integer index returns Queue
local Queue current = GetPlayerQueue(whichPlayer)
local integer i = 0
loop
exitwhen (current == 0 or index == i)
set current = current.next
set i = i + 1
endloop
return current
endfunction
function ClearQueue takes Queue queue returns nothing
local Queue current = queue
local unit source = null
local integer j = 0
local integer max = 0
loop
exitwhen (current == 0)
set queue = current.next
set j = 0
set max = BlzGroupGetSize(queue.sources)
loop
exitwhen (j == max)
set source = BlzGroupUnitAt(current.sources, j)
call SetSourceCounter(source, current.id, GetSourceCounter(source, current.id) - 1)
set source = null
set j = j + 1
endloop
call current.destroy()
set current = queue
endloop
endfunction
function AddQueue takes unit source, integer id returns nothing
local Queue current = GetPlayerQueue(GetOwningPlayer(source))
local Queue previous = 0
local boolean found = false
loop
exitwhen (current == 0)
//call BJDebugMsg("Test: " + I2S(current) + " with ID " + GetObjectName(current.id) + " looking for ID " + GetObjectName(id))
if (current.id == id) then
set found = true
endif
exitwhen (found)
set previous = current
set current = current.next
endloop
if (current == 0) then
set current = Queue.create()
set current.id = id
//call BJDebugMsg("Creating new queue " + I2S(current) + " with previous " + I2S(previous))
if (playerQueue[GetPlayerId(GetOwningPlayer(source))] == 0) then
set playerQueue[GetPlayerId(GetOwningPlayer(source))] = current
elseif (previous != 0) then
set current.previous = previous
set previous.next = current
endif
endif
//call BJDebugMsg("Current: " + I2S(current))
if (not IsUnitInGroup(source, current.sources)) then
call GroupAddUnit(current.sources, source)
endif
call SetSourceCounter(source, id, GetSourceCounter(source, id) + 1)
set current.counter = current.counter + 1
call ExecuteTriggerCallbacks(source, id)
endfunction
function RemoveQueue takes unit source, integer id returns nothing
local player owner = GetOwningPlayer(source)
local integer playerId = GetPlayerId(owner)
local Queue current = GetPlayerQueue(owner)
local Queue previous = current
local boolean found = false
loop
exitwhen (current == 0)
if (current.id == id and IsUnitInGroup(source, current.sources)) then
set found = true
endif
exitwhen (found)
set previous = current
set current = current.next
endloop
if (current != 0) then
call SetSourceCounter(source, id, GetSourceCounter(source, id) - 1)
set current.counter = current.counter - 1
if (GetSourceCounter(source, id) == 0) then
call GroupRemoveUnit(current.sources, source)
endif
if (BlzGroupGetSize(current.sources) == 0) then
if (GetPlayerQueue(owner) == current) then
set playerQueue[playerId] = current.next
endif
//call BJDebugMsg("Destroying " + I2S(current))
call current.destroy()
endif
endif
call ExecuteTriggerCallbacks(source, id)
endfunction
private function TriggerConditionCancelTrain takes nothing returns boolean
if (IsQueueEnabledForPlayer(GetOwningPlayer(GetTriggerUnit()))) then
call RemoveQueue(GetTriggerUnit(), GetTrainedUnitType())
endif
return false
endfunction
private function TriggerConditionFinishTrain takes nothing returns boolean
if (IsQueueEnabledForPlayer(GetOwningPlayer(GetTriggerUnit()))) then
call RemoveQueue(GetTriggerUnit(), GetTrainedUnitType())
endif
return false
endfunction
private function TriggerConditionCancelResearch takes nothing returns boolean
if (IsQueueEnabledForPlayer(GetOwningPlayer(GetTriggerUnit()))) then
call RemoveQueue(GetTriggerUnit(), GetResearched())
endif
return false
endfunction
private function TriggerConditionFinishResearch takes nothing returns boolean
if (IsQueueEnabledForPlayer(GetOwningPlayer(GetTriggerUnit()))) then
call RemoveQueue(GetTriggerUnit(), GetResearched())
endif
return false
endfunction
private function TriggerConditionCancelUpgrade takes nothing returns boolean
if (IsQueueEnabledForPlayer(GetOwningPlayer(GetTriggerUnit()))) then
call RemoveQueue(GetTriggerUnit(), LoadInteger(h, GetHandleId(GetTriggerUnit()), 0)) // Use the ID from start upgrade.
endif
return false
endfunction
private function TriggerConditionFinishUpgrade takes nothing returns boolean
if (IsQueueEnabledForPlayer(GetOwningPlayer(GetTriggerUnit()))) then
call RemoveQueue(GetTriggerUnit(), GetUnitTypeId(GetTriggerUnit())) // Already has the new ID from start upgrade at this point.
endif
return false
endfunction
private function TriggerConditionStartConstruct takes nothing returns boolean
if (IsQueueEnabledForPlayer(GetOwningPlayer(GetConstructingStructure()))) then
call AddQueue(GetConstructingStructure(), GetUnitTypeId(GetConstructingStructure()))
call GroupAddUnit(constructions, GetConstructingStructure())
endif
return false
endfunction
private function TriggerConditionCancelConstruct takes nothing returns boolean
//call BJDebugMsg("Cancel construction of " + GetUnitName(GetTriggerUnit()))
return false
endfunction
private function TriggerConditionFinishConstruct takes nothing returns boolean
if (IsQueueEnabledForPlayer(GetOwningPlayer(GetConstructedStructure()))) then
call RemoveQueue(GetConstructedStructure(), GetUnitTypeId(GetConstructedStructure()))
call GroupRemoveUnit(constructions, GetConstructedStructure())
endif
return false
endfunction
static if (LIBRARY_HeroReviveEvents) then
private function TriggerConditionOrderReviveStart takes nothing returns boolean
//call BJDebugMsg("Altar " + GetUnitName(GetTriggerReviveAltar()) + " starts the revival of hero " + GetUnitName(GetTriggerReviveHero()))
if (IsQueueEnabledForPlayer(GetOwningPlayer(GetTriggerReviveAltar()))) then
call AddQueue(GetTriggerReviveAltar(), GetUnitTypeId(GetTriggerReviveHero()))
endif
return false
endfunction
private function TriggerConditionOrderReviveCancel takes nothing returns boolean
//call BJDebugMsg("Altar " + GetUnitName(GetTriggerReviveAltar()) + " cancels the revival of hero " + GetUnitName(GetTriggerReviveHero()))
if (IsQueueEnabledForPlayer(GetOwningPlayer(GetTriggerReviveAltar()))) then
call RemoveQueue(GetTriggerReviveAltar(), GetUnitTypeId(GetTriggerReviveHero()))
endif
return false
endfunction
private function TriggerConditionFinishRevive takes nothing returns boolean
//call BJDebugMsg("Altar " + GetUnitName(GetTriggerReviveAltar()) + " finishes revival of hero " + GetUnitName(GetTriggerReviveHero()))
if (IsQueueEnabledForPlayer(GetOwningPlayer(GetTriggerReviveAltar()))) then
call RemoveQueue(GetTriggerReviveAltar(), GetUnitTypeId(GetTriggerReviveHero()))
endif
return false
endfunction
endif
private function IsValidBuilding takes unit whichUnit returns boolean
if (not IsUnitType(whichUnit, UNIT_TYPE_STRUCTURE)) then
return false
elseif (IsUnitType(whichUnit, UNIT_TYPE_HERO)) then // structure heroes are possible with the Root ability
return false
elseif (GetUnitAbilityLevel(whichUnit, 'Aneu') > 0) then
return false
elseif (GetUnitAbilityLevel(whichUnit, 'Ane2') > 0) then
return false
elseif (GetUnitAbilityLevel(whichUnit, 'Apit') > 0) then
return false
elseif (IsUnitInGroup(whichUnit, ignored)) then
return false
endif
return true
endfunction
private function TriggerConditionOrder takes nothing returns boolean
local unit building = GetTriggerUnit()
local integer trainId = GetIssuedOrderId()
//call BJDebugMsg("Order " + I2S(GetIssuedOrderId()) + ": " + GetObjectName(GetIssuedOrderId()))
// Use only structures which do not sell units or items to avoid getting summoned and sold units and sold items.
if (IsQueueEnabledForPlayer(GetOwningPlayer(building)) and GetObjectName(trainId) != EMPTY_STRING and GetObjectName(trainId) != null and IsValidBuilding(building)) then
call SaveInteger(h, GetHandleId(building), 0, trainId)
call AddQueue(building, trainId)
endif
set building = null
return false
endfunction
private function ClearSourceCounterExtended takes unit whichUnit returns nothing
if (IsUnitInGroup(whichUnit, constructions)) then
call RemoveQueue(whichUnit, GetUnitTypeId(whichUnit))
call GroupRemoveUnit(constructions, whichUnit)
endif
call ClearSourceCounter(whichUnit)
endfunction
private function TriggerConditionDeath takes nothing returns boolean
if (IsQueueEnabledForPlayer(GetOwningPlayer(GetTriggerUnit()))) then
call ClearSourceCounterExtended(GetTriggerUnit())
endif
return false
endfunction
private function Init takes nothing returns nothing
local player slotPlayer = null
local integer i = 0
loop
exitwhen (i == bj_MAX_PLAYERS)
set slotPlayer = Player(i)
if (GetPlayerSlotState(slotPlayer) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(slotPlayer) == MAP_CONTROL_USER) then
set isEnabledForPlayer[i] = true
endif
set slotPlayer = null
set i = i + 1
endloop
call TriggerRegisterAnyUnitEventBJ(cancelTrainTrigger, EVENT_PLAYER_UNIT_TRAIN_CANCEL)
call TriggerAddCondition(cancelTrainTrigger, Condition(function TriggerConditionCancelTrain))
call TriggerRegisterAnyUnitEventBJ(finishTrainTrigger, EVENT_PLAYER_UNIT_TRAIN_FINISH)
call TriggerAddCondition(finishTrainTrigger, Condition(function TriggerConditionFinishTrain))
call TriggerRegisterAnyUnitEventBJ(cancelResearchTrigger, EVENT_PLAYER_UNIT_RESEARCH_CANCEL)
call TriggerAddCondition(cancelResearchTrigger, Condition(function TriggerConditionCancelResearch))
call TriggerRegisterAnyUnitEventBJ(finishResearchTrigger, EVENT_PLAYER_UNIT_RESEARCH_FINISH)
call TriggerAddCondition(finishResearchTrigger, Condition(function TriggerConditionFinishResearch))
call TriggerRegisterAnyUnitEventBJ(cancelUpgradeTrigger, EVENT_PLAYER_UNIT_UPGRADE_CANCEL)
call TriggerAddCondition(cancelUpgradeTrigger, Condition(function TriggerConditionCancelUpgrade))
call TriggerRegisterAnyUnitEventBJ(finishUpgradeTrigger, EVENT_PLAYER_UNIT_UPGRADE_FINISH)
call TriggerAddCondition(finishUpgradeTrigger, Condition(function TriggerConditionFinishUpgrade))
call TriggerRegisterAnyUnitEventBJ(startConstructTrigger, EVENT_PLAYER_UNIT_CONSTRUCT_START)
call TriggerAddCondition(startConstructTrigger, Condition(function TriggerConditionStartConstruct))
call TriggerRegisterAnyUnitEventBJ(finishConstructTrigger, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH)
call TriggerAddCondition(finishConstructTrigger, Condition(function TriggerConditionFinishConstruct))
static if (LIBRARY_HeroReviveEvents) then
call TriggerRegisterHeroReviveOrderStartEvent(orderReviveStartTrigger)
call TriggerAddCondition(orderReviveStartTrigger, Condition(function TriggerConditionOrderReviveStart))
call TriggerRegisterHeroReviveOrderCancelEvent(orderReviveCancelTrigger)
call TriggerAddCondition(orderReviveCancelTrigger, Condition(function TriggerConditionOrderReviveCancel))
call TriggerRegisterHeroReviveFinishEvent(finishReviveTrigger)
call TriggerAddCondition(finishReviveTrigger, Condition(function TriggerConditionFinishRevive))
endif
call TriggerRegisterAnyUnitEventBJ(orderTrigger, EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerAddCondition(orderTrigger, Condition(function TriggerConditionOrder))
call TriggerRegisterAnyUnitEventBJ(deathTrigger, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(deathTrigger, Condition(function TriggerConditionDeath))
endfunction
private function RemoveUnitHook takes unit whichUnit returns nothing
call ClearSourceCounterExtended(whichUnit)
if (IsQueueUnitIgnored(whichUnit)) then
call UnignoreQueueUnit(whichUnit)
endif
endfunction
hook RemoveUnit ClearSourceCounterExtended
endlibrary
library QueueUIResearches initializer Init
globals
private hashtable h = InitHashtable()
private constant integer KEY_LEVELS = 0
private constant integer KEY_LEVEL_1 = 1 // start with level
endglobals
private struct Research
string name
string icon
endstruct
private function AddResearch takes integer id, string name, string icon returns nothing
local Research this = Research.create()
local integer level = LoadInteger(h, id, KEY_LEVELS)
set this.name = name
set this.icon = icon
call SaveInteger(h, id, KEY_LEVEL_1 + level, this)
call SaveInteger(h, id, KEY_LEVELS, level + 1)
endfunction
private function GetResearch takes integer id, player whichPlayer returns Research
local integer level = GetPlayerTechCount(whichPlayer, id, true)
if (level > 0) then
return LoadInteger(h, id, level) // start with level 1
endif
return 0
endfunction
public function GetName takes integer id, player whichPlayer returns string
local Research r = GetResearch(id, whichPlayer)
if (r != 0) then
return r.name
endif
return GetObjectName(id)
endfunction
public function GetIcon takes integer id, player whichPlayer returns string
local Research r = GetResearch(id, whichPlayer)
if (r != 0) then
return r.icon
endif
return BlzGetAbilityIcon(id)
endfunction
private function Init takes nothing returns nothing
// Human
call AddResearch('Rhme', "Steel Forged Swords", "ReplaceableTextures\\CommandButtons\\BTNThoriumMelee.blp")
call AddResearch('Rhme', "Mithril Forged Swords", "ReplaceableTextures\\CommandButtons\\BTNArcaniteMelee.blp")
call AddResearch('Rhra', "Refined Gunpowder", "ReplaceableTextures\\CommandButtons\\BTNHumanMissileUpTwo.blp")
call AddResearch('Rhra', "Imbued Gunpowder", "ReplaceableTextures\\CommandButtons\\BTNHumanMissileUpThree.blp")
call AddResearch('Rhla', "Reinforced Leather Armor", "ReplaceableTextures\\CommandButtons\\BTNLeatherUpgradeTwo.blp")
call AddResearch('Rhla', "Dragonhide Armor", "ReplaceableTextures\\CommandButtons\\BTNLeatherUpgradeThree.blp")
call AddResearch('Rhar', "Steel Plating", "ReplaceableTextures\\CommandButtons\\BTNHumanArmorUpTwo.blp")
call AddResearch('Rhar', "Mithril Plating", "ReplaceableTextures\\CommandButtons\\BTNHumanArmorUpThree.blp")
call AddResearch('Rhlh', "Advanced Lumber Harvesting", "ReplaceableTextures\\CommandButtons\\BTNHumanLumberUpgrade2.blp")
call AddResearch('Rhac', "Advanced Masonry", "ReplaceableTextures\\CommandButtons\\BTNArcaniteArchitecture.blp")
call AddResearch('Rhac', "Imbued Masonry", "ReplaceableTextures\\CommandButtons\\BTNImbuedMasonry.blp")
call AddResearch('Rhpt', "Priest Master Training", "ReplaceableTextures\\CommandButtons\\BTNPriestMaster.blp")
call AddResearch('Rhst', "Sorceress Master Training", "ReplaceableTextures\\CommandButtons\\BTNSorceressMaster.blp")
// Orc
call AddResearch('Rost', "Shaman Master Training", "ReplaceableTextures\\CommandButtons\\BTNShamanMaster.blp")
call AddResearch('Rosp', "Improved Spiked Barricades", "ReplaceableTextures\\CommandButtons\\BTNImprovedSpikedBarricades.blp")
call AddResearch('Rosp', "Advanced Spiked Barricades", "ReplaceableTextures\\CommandButtons\\BTNAdvancedSpikedBarricades.blp")
call AddResearch('Rowt', "Spirit Walker Master Training", "ReplaceableTextures\\CommandButtons\\BTNSpiritWalkerMasterTraining.blp")
call AddResearch('Roar', "Thorium Armor", "ReplaceableTextures\\CommandButtons\\BTNThoriumArmor.blp")
call AddResearch('Roar', "Arcanite Armor", "ReplaceableTextures\\CommandButtons\\BTNArcaniteArmor.blp")
call AddResearch('Rome', "Thorium Melee Weapons", "ReplaceableTextures\\CommandButtons\\BTNOrcMeleeUpTwo.blp")
call AddResearch('Rome', "Arcanite Melee Weapons", "ReplaceableTextures\\CommandButtons\\BTNOrcMeleeUpThree.blp")
call AddResearch('Rora', "Thorium Ranged Weapons", "ReplaceableTextures\\CommandButtons\\BTNThoriumRanged.blp")
call AddResearch('Rora', "Arcanite Ranged Weapons", "ReplaceableTextures\\CommandButtons\\BTNArcaniteRanged.blp")
call AddResearch('Rowd', "Witch Doctor Master Training", "ReplaceableTextures\\CommandButtons\\BTNWitchDoctorMaster.blp")
// Undead
call AddResearch('Ruba', "Banshee Master Training", "ReplaceableTextures\\CommandButtons\\BTNBansheeMaster.blp")
call AddResearch('Rura', "Improved Creature Attack", "ReplaceableTextures\\CommandButtons\\BTNImprovedCreatureAttack.blp")
call AddResearch('Rura', "Advanced Creature Attack", "ReplaceableTextures\\CommandButtons\\BTNAdvancedCreatureAttack.blp")
call AddResearch('Rucr', "Improved Creature Carapace", "ReplaceableTextures\\CommandButtons\\BTNImprovedCreatureCarapace.blp")
call AddResearch('Rucr', "Advanced Creature Carapace", "ReplaceableTextures\\CommandButtons\\BTNAdvancedCreatureCarapace.blp")
call AddResearch('Rune', "Necromancer Master Training", "ReplaceableTextures\\CommandButtons\\BTNNecromancerMaster.blp")
call AddResearch('Ruar', "Improved Unholy Armor", "ReplaceableTextures\\CommandButtons\\BTNImprovedUnholyArmor.blp")
call AddResearch('Ruar', "Advanced Unholy Armor", "ReplaceableTextures\\CommandButtons\\BTNAdvancedUnholyArmor.blp")
call AddResearch('Rume', "Improved Unholy Strength", "ReplaceableTextures\\CommandButtons\\BTNImprovedUnholyStrength.blp")
call AddResearch('Rume', "Advanced Unholy Strength", "ReplaceableTextures\\CommandButtons\\BTNAdvancedUnholyStrength.blp")
// Night Elf
call AddResearch('Redc', "Druid of the Claw Master Training", "ReplaceableTextures\\CommandButtons\\BTNDOCMasterTraining.blp")
call AddResearch('Redt', "Druid of the Talon Master Training", "ReplaceableTextures\\CommandButtons\\BTNDOTMasterTraining.blp")
call AddResearch('Rema', "Improved Moon Armor", "ReplaceableTextures\\CommandButtons\\BTNImprovedMoonArmor.blp")
call AddResearch('Rema', "Advanced Moon Armor", "ReplaceableTextures\\CommandButtons\\BTNAdvancedMoonArmor.blp")
call AddResearch('Rerh', "Improved Reinforced Hides", "ReplaceableTextures\\CommandButtons\\BTNImprovedReinforcedHides.blp")
call AddResearch('Rerh', "Advanced Reinforced Hides", "ReplaceableTextures\\CommandButtons\\BTNAdvancedReinforcedHides.blp")
call AddResearch('Resm', "Improved Strength of the Moon", "ReplaceableTextures\\CommandButtons\\BTNImprovedStrengthOfTheMoon.blp")
call AddResearch('Resm', "Advanced Strength of the Moon", "ReplaceableTextures\\CommandButtons\\BTNAdvancedStrengthOfTheMoon.blp")
call AddResearch('Resw', "Improved Strength of the Wild", "ReplaceableTextures\\CommandButtons\\BTNImprovedStrengthOfTheWild.blp")
call AddResearch('Resw', "Advanced Strength of the Wild", "ReplaceableTextures\\CommandButtons\\BTNAdvancedStrengthOfTheWild.blp")
// Naga
call AddResearch('Rnat', "Chitinous Blades", "ReplaceableTextures\\CommandButtons\\BTNNagaWeaponUp2.blp")
call AddResearch('Rnat', "Razorspine Blades", "ReplaceableTextures\\CommandButtons\\BTNNagaWeaponUp3.blp")
call AddResearch('Rnam', "Chitinous Scales", "ReplaceableTextures\\CommandButtons\\BTNNagaArmorUp2.blp")
call AddResearch('Rnam', "Razorspine Scales", "ReplaceableTextures\\CommandButtons\\BTNNagaArmorUp3.blp")
call AddResearch('Rnsw', "Naga Siren Master Training", "ReplaceableTextures\\CommandButtons\\BTNSirenMaster.blp")
endfunction
endlibrary
library QueueUI initializer Init requires Queue, optional QueueUIResearches, optional FrameLoader
globals
// Set to false if the TOC file should not be loaded automatically.
public constant boolean LOAD_TOC_FILE = true
public constant string TOC_FILE = "war3mapImported\\QueueUI.toc"
public constant integer MAX_SLOTS = 8
public constant boolean PAN_CAMERA = true
public constant string PREFIX = "QueueUI"
public constant real Y = 0.19
public constant real CHECK_BOX_X = 0.05
public constant real CHECK_BOX_Y = Y
public constant real CHECK_BOX_SIZE = 0.02
public constant real BUTTON_SPACE = 0.001
public constant real BUTTON_X = CHECK_BOX_X + CHECK_BOX_SIZE + BUTTON_SPACE
public constant real BUTTON_Y = Y
public constant real BUTTON_SIZE = 0.024
public constant real CHARGES_SIZE = 0.014
public constant real TOOLTIP_FONT_HEIGHT = 0.009
public constant real TOOLTIP_Y = 0.007
public constant string TOOLTIP_FONT = "fonts\\dfst-m3u.ttf"
private boolean array enabledForPlayer
private trigger CheckboxCheckedTrigger
private trigger CheckboxUncheckedTrigger
private framehandle Checkbox
private framehandle CheckboxTooltip
private framehandle array SlotFrame
private framehandle array SlotBackdropFrame
private framehandle array SlotChargesBackdropFrame
private framehandle array SlotChargesFrame
private framehandle array SlotTooltip
private trigger array SlotClickTrigger
private boolean array checked
private hashtable h = InitHashtable()
private trigger syncTrigger = CreateTrigger()
private trigger queueTrigger = CreateTrigger()
endglobals
function IsQueueUIEnabledForPlayer takes player whichPlayer returns boolean
return enabledForPlayer[GetPlayerId(whichPlayer)]
endfunction
private function SetSlotVisible takes integer i, boolean visible returns nothing
call BlzFrameSetVisible(SlotFrame[i], visible)
call BlzFrameSetVisible(SlotBackdropFrame[i], visible)
call BlzFrameSetVisible(SlotChargesBackdropFrame[i], visible)
call BlzFrameSetVisible(SlotChargesFrame[i], visible)
call BlzFrameSetEnable(SlotTooltip[i], visible)
endfunction
private function SetAllSlotChargesVisible takes boolean visible returns nothing
local integer i = 0
loop
exitwhen (i >= MAX_SLOTS)
call SetSlotVisible(i, visible)
set i = i + 1
endloop
endfunction
private function UpdateUIForPlayer takes player whichPlayer returns nothing
local integer playerId = GetPlayerId(whichPlayer)
local Queue current = GetPlayerQueue(whichPlayer)
local integer i = 0
if (IsQueueUIEnabledForPlayer(whichPlayer) and not checked[playerId]) then
//call BJDebugMsg("Update for player " + GetPlayerName(whichPlayer))
loop
exitwhen (i >= MAX_SLOTS or current == 0)
if (whichPlayer == GetLocalPlayer() and BlzFrameIsVisible(Checkbox)) then // has not been manually hidden before
//call BJDebugMsg("Show slot " + I2S(i))
static if (LIBRARY_QueueUIResearches) then
call BlzFrameSetTexture(SlotBackdropFrame[i], QueueUIResearches_GetIcon(current.id, whichPlayer), 0, true)
call BlzFrameSetText(SlotTooltip[i], QueueUIResearches_GetName(current.id, whichPlayer))
else
call BlzFrameSetTexture(SlotBackdropFrame[i], BlzGetAbilityIcon(current.id), 0, true)
call BlzFrameSetText(SlotTooltip[i], GetObjectName(current.id))
endif
call BlzFrameSetText(SlotChargesFrame[i], I2S(current.counter))
call BlzFrameSetEnable(SlotTooltip[i], true)
call SetSlotVisible(i, true)
endif
//call BJDebugMsg("Show slot " + I2S(i) + ": " + BlzGetAbilityIcon(current.id))
//call BJDebugMsg("UI check " + I2S(current) + " with ID " + GetObjectName(current.id))
set current = current.next
set i = i + 1
endloop
endif
loop
exitwhen (i >= MAX_SLOTS)
if (whichPlayer == GetLocalPlayer()) then
call BlzFrameSetTexture(SlotBackdropFrame[i], "", 0, true)
call BlzFrameSetEnable(SlotTooltip[i], false)
call SetSlotVisible(i, false)
endif
set i = i + 1
endloop
endfunction
private function ForForceUpdateUI takes nothing returns nothing
call UpdateUIForPlayer(GetEnumPlayer())
endfunction
private function UpdateUI takes nothing returns nothing
call ForForce(GetPlayersAll(), function ForForceUpdateUI)
endfunction
private function GetNextUnitToSelect takes group g,player whichPlayer returns unit
local integer max = BlzGroupGetSize(g)
local integer i= 0
local unit u= null
local unit result= null
local boolean found = false
if (max > 0) then
loop
exitwhen (i == max)
set u = BlzGroupUnitAt(g, i)
if (IsUnitSelected(u, whichPlayer)) then
set found = true
elseif (found) then
set result = u
endif
set u = null
set i = i + 1
endloop
// this happens if none of them is selected or the last one
if (result == null) then
set result = BlzGroupUnitAt(g, 0) // start at first
endif
endif
return result
endfunction
private function DistanceBetweenCoordinates takes real x1, real y1, real x2, real y2 returns real
local real dx = (x2 - x1)
local real dy = (y2 - y1)
return SquareRoot(dx * dx + dy * dy)
endfunction
private function SmartCameraPanToUnit takes player whichPlayer,unit target,real duration returns nothing
local real dist
local real x = GetUnitX(target)
local real y = GetUnitY(target)
if (GetLocalPlayer() == whichPlayer) then
// Use only local code (no net traffic) within this block to avoid desyncs.
set dist = DistanceBetweenCoordinates(x, y, GetCameraTargetPositionX(), GetCameraTargetPositionY())
if (dist >= bj_SMARTPAN_TRESHOLD_SNAP) then
// If the user is too far away, snap the camera.
call PanCameraToTimed(x, y, 0)
elseif (dist >= bj_SMARTPAN_TRESHOLD_PAN) then
// If the user is moderately close, pan the camera.
call PanCameraToTimed(x, y, duration)
else
// User is close enough, so don't touch the camera.
endif
endif
endfunction
private function SelectNextSource takes player whichPlayer, integer slot returns nothing
local Queue q = GetPlayerQueueByIndex(whichPlayer, slot)
local unit n = null
if (q != 0) then
set n = GetNextUnitToSelect(q.sources , whichPlayer)
if (n != null) then
call SelectUnitForPlayerSingle(n, whichPlayer)
static if (PAN_CAMERA) then
call SmartCameraPanToUnit(whichPlayer, n, 0.0)
endif
endif
endif
endfunction
private function TriggerActionSyncData takes nothing returns nothing
local player whichPlayer = GetTriggerPlayer()
local integer playerId = GetPlayerId(whichPlayer)
local string data = BlzGetTriggerSyncData()
local integer slot = 0
if (data == "Checked") then
set checked[playerId] = true
if (whichPlayer == GetLocalPlayer()) then
call BlzFrameSetText(CheckboxTooltip, GetLocalizedString("SHOW_QUEUE_UI"))
endif
call UpdateUIForPlayer(whichPlayer)
elseif (data == "Unchecked") then
set checked[playerId] = false
if (whichPlayer == GetLocalPlayer()) then
call BlzFrameSetText(CheckboxTooltip, GetLocalizedString("HIDE_QUEUE_UI"))
endif
call UpdateUIForPlayer(whichPlayer)
else
set slot = S2I(data)
call SelectNextSource(whichPlayer, slot)
endif
set whichPlayer = null
endfunction
function ShowQueueUI takes nothing returns nothing
call BlzFrameSetVisible(Checkbox, true)
//call BlzFrameSetVisible(CheckboxTooltip, true) // will show the text
call SetAllSlotChargesVisible(true)
endfunction
function HideQueueUI takes nothing returns nothing
call BlzFrameSetVisible(Checkbox, false)
call BlzFrameSetVisible(CheckboxTooltip, false)
call SetAllSlotChargesVisible(false)
endfunction
function SetQueueUIEnabledForPlayer takes player whichPlayer, boolean enabled returns nothing
set enabledForPlayer[GetPlayerId(whichPlayer)] = enabled
if (enabled) then
if (whichPlayer == GetLocalPlayer()) then
call ShowQueueUI()
endif
call UpdateUIForPlayer(whichPlayer)
else
if (whichPlayer == GetLocalPlayer()) then
call HideQueueUI()
endif
endif
endfunction
private function CheckedFunction takes nothing returns nothing
if (GetLocalPlayer() == GetTriggerPlayer()) then
call BlzSendSyncData(PREFIX, "Checked")
endif
endfunction
private function UncheckedFunction takes nothing returns nothing
if (GetLocalPlayer() == GetTriggerPlayer()) then
call BlzSendSyncData(PREFIX, "Unchecked")
endif
endfunction
private function ClickItemFunction takes nothing returns nothing
local integer handleId = GetHandleId(GetTriggeringTrigger())
local integer slot = LoadInteger(h, handleId, 0)
if (GetLocalPlayer() == GetTriggerPlayer()) then
call BlzSendSyncData(PREFIX, I2S(slot))
endif
endfunction
public function CreateUI takes nothing returns nothing
local integer i = 0
local integer handleId = 0
local real x = 0.0
local real y = 0.0
set x = CHECK_BOX_X
set y = CHECK_BOX_Y
set Checkbox = BlzCreateFrame("QuestCheckBox2", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
call BlzFrameSetAbsPoint(Checkbox, FRAMEPOINT_TOPLEFT, x, y)
call BlzFrameSetAbsPoint(Checkbox, FRAMEPOINT_BOTTOMRIGHT, x + CHECK_BOX_SIZE, y - CHECK_BOX_SIZE)
set CheckboxTooltip = BlzCreateFrameByType("TEXT", "QueueUICheckboxTooltip", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
call BlzFrameSetTooltip(Checkbox, CheckboxTooltip)
call BlzFrameSetPoint(CheckboxTooltip, FRAMEPOINT_BOTTOM, Checkbox, FRAMEPOINT_TOP, 0, TOOLTIP_Y)
call BlzFrameSetFont(CheckboxTooltip, TOOLTIP_FONT, TOOLTIP_FONT_HEIGHT, 0)
call BlzFrameSetText(CheckboxTooltip, GetLocalizedString("HIDE_QUEUE_UI"))
set CheckboxCheckedTrigger = CreateTrigger()
call BlzTriggerRegisterFrameEvent(CheckboxCheckedTrigger, Checkbox, FRAMEEVENT_CHECKBOX_CHECKED)
call TriggerAddAction(CheckboxCheckedTrigger, function CheckedFunction)
set CheckboxUncheckedTrigger = CreateTrigger()
call BlzTriggerRegisterFrameEvent(CheckboxUncheckedTrigger, Checkbox, FRAMEEVENT_CHECKBOX_UNCHECKED)
call TriggerAddAction(CheckboxUncheckedTrigger, function UncheckedFunction)
set x = BUTTON_X
set y = BUTTON_Y
set i = 0
loop
exitwhen (i == MAX_SLOTS)
set SlotFrame[i] = BlzCreateFrame("ScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
call BlzFrameSetAbsPoint(SlotFrame[i], FRAMEPOINT_TOPLEFT, x, y)
call BlzFrameSetAbsPoint(SlotFrame[i], FRAMEPOINT_BOTTOMRIGHT, x + BUTTON_SIZE, y - BUTTON_SIZE)
//call BlzFrameSetTexture(SlotFrame[index], GetIconByItemType(0), 0, true)
//call BlzFrameSetText(SlotFrame[index], I2S(index))
set SlotBackdropFrame[i] = BlzCreateFrameByType("BACKDROP", "QueueUIBackdropFrame" + I2S(i), SlotFrame[i], "", 1)
call BlzFrameSetAllPoints(SlotBackdropFrame[i], SlotFrame[i])
// call BlzFrameSetTexture(SlotBackdropFrame[index], "UI\\Widgets\\Console\\Human\\human-inventory-slotfiller.blp", 0, true)
// TODO Set Tooltip frame for the object name
set SlotChargesBackdropFrame[i] = BlzCreateFrameByType("BACKDROP", "QueueUIChargesBackdropFrame" + I2S(i), BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
call BlzFrameSetAbsPoint(SlotChargesBackdropFrame[i], FRAMEPOINT_TOPLEFT, x + BUTTON_SIZE - CHARGES_SIZE, y - BUTTON_SIZE + CHARGES_SIZE)
call BlzFrameSetAbsPoint(SlotChargesBackdropFrame[i], FRAMEPOINT_BOTTOMRIGHT, x + BUTTON_SIZE, y - BUTTON_SIZE)
call BlzFrameSetTexture(SlotChargesBackdropFrame[i], "ui\\widgets\\console\\human\\commandbutton\\human-button-lvls-overlay.blp", 0, true)
call BlzFrameSetLevel(SlotChargesBackdropFrame[i], 1)
set SlotChargesFrame[i] = BlzCreateFrameByType("TEXT", "QueueUIChargesFrame" + I2S(i), SlotChargesBackdropFrame[i], "", 0)
call BlzFrameSetAllPoints(SlotChargesFrame[i], SlotChargesBackdropFrame[i])
call BlzFrameSetTextAlignment(SlotChargesFrame[i], TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_CENTER)
call BlzFrameSetScale(SlotChargesFrame[i], 0.7)
call BlzFrameSetEnable(SlotChargesFrame[i], false)
call BlzFrameSetLevel(SlotChargesFrame[i], 2)
set SlotClickTrigger[i] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(SlotClickTrigger[i], SlotFrame[i], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(SlotClickTrigger[i], function ClickItemFunction)
set handleId = GetHandleId(SlotClickTrigger[i])
call SaveInteger(h, handleId, 0, i)
set SlotTooltip[i] = BlzCreateFrameByType("TEXT", "QueueUITooltip" + I2S(i), BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
call BlzFrameSetTooltip(SlotFrame[i], SlotTooltip[i])
call BlzFrameSetPoint(SlotTooltip[i], FRAMEPOINT_BOTTOM, SlotFrame[i], FRAMEPOINT_TOP, 0, TOOLTIP_Y)
call BlzFrameSetFont(SlotTooltip[i], TOOLTIP_FONT, TOOLTIP_FONT_HEIGHT, 0)
call BlzFrameSetEnable(SlotTooltip[i], false)
set x = x + BUTTON_SIZE + BUTTON_SPACE
set i = i + 1
endloop
call UpdateUI()
endfunction
private function TriggerActionUpdateQueue takes nothing returns nothing
//call BJDebugMsg("Queue update " + GetObjectName(GetTriggerQueueId()))
call UpdateUIForPlayer(GetOwningPlayer(GetTriggerQueueUnit()))
endfunction
private function TimerFunctionStart takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer i = 0
local player slotPlayer = null
loop
exitwhen (i == bj_MAX_PLAYERS)
set slotPlayer = Player(i)
if (GetPlayerSlotState(slotPlayer) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(slotPlayer) == MAP_CONTROL_USER) then
set enabledForPlayer[i] = true
call BlzTriggerRegisterPlayerSyncEvent(syncTrigger, slotPlayer, PREFIX, false)
endif
set slotPlayer = null
set i = i + 1
endloop
call TriggerAddAction(syncTrigger, function TriggerActionSyncData)
call CreateUI()
call TriggerRegisterQueueEvent(queueTrigger)
call TriggerAddAction(queueTrigger, function TriggerActionUpdateQueue)
call PauseTimer(t)
call DestroyTimer(t)
set t = null
endfunction
private function Init takes nothing returns nothing
static if (LOAD_TOC_FILE) then
call BlzLoadTOCFile(TOC_FILE)
endif
call TimerStart(CreateTimer(), 0.0, false, function TimerFunctionStart)
static if (LIBRARY_FrameLoader) then
call FrameLoaderAdd(function CreateUI)
endif
endfunction
endlibrary