library NumberKeyEvent initializer init
// Configurations
globals
// Key detector dummy's raw code in OE
private constant integer DUMMY_ID = 'h000'
// Location of dummy, better to be a permanently
// invisible spot in your map
private constant real DUMMY_X = 2521.32
private constant real DUMMY_Y = -2827.15
// If true, system will use periodical check
// results in more instaneous press event
private constant boolean USE_TIMER = true
private constant real CHECK_RATE = 0.01
endglobals
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* NumberKeyEvent v1.3
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*
* Description
* ¯¯¯¯¯¯¯¯¯¯¯
* Allows you to do actions when a player presses
* any number key (0-9)
*
* Cons
* ¯¯¯¯
* - Needs calibration (check demo)
* - Disturbs unit selection
*
* Requirement
* ¯¯¯¯¯¯¯¯¯¯¯
* -
*
* How to import
* ¯¯¯¯¯¯¯¯¯¯¯¯¯
* - Copy KeyDetectorDummy unit from object editor to your map
* - Copy the trigger folder to your map
* - Configure the system accordingly
*
* API
* ¯¯¯
* function CalibrateNumberKeys takes integer playerId returns nothing
* function GetPressedNumberKey takes nothing returns integer
* function GetPressingPlayer takes nothing returns player
* function RegisterAnyNumberKeyEvent takes boolexpr func returns triggercondition
* function UnregisterAnyNumberKeyEvent takes triggercondition tc returns nothing
*
* Notes
* ¯¯¯¯¯
* - Better to preserve an invisible area for dummy
* units to avoid unwanted camera panning
* - Player must be pressing CTRL when CalibrateNumberKeys
* function is called
* - You must allow players to calibrate their keys
* anytime whenever they want, in case the calibration
* is failed or broken
* - By using this system players are no longer supposed
* to use the control group shortcut keys: CTRL+(0-9).
* Because it will break the calibration. Warn them.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
globals
private unit array KeyUnit
private boolean array IsCalibrated
private boolean array IsRegistered
private trigger Handler = CreateTrigger()
private integer EventPressed = -1
private player EventPresser = null
private player Locale
private timer Timer = null
endglobals
private function onSelection takes nothing returns boolean
static if USE_TIMER then
local integer i = 0
local integer j
local integer k
local player p
loop
exitwhen i > 11
if IsCalibrated[i] then
set p = Player(i)
set j = 0
loop
exitwhen j > 9
set k = i*10+j
if IsUnitSelected(KeyUnit[k], p) then
if Locale == p then
call ClearSelection()
endif
set EventPresser = p
set EventPressed = j
call TriggerEvaluate(Handler)
set EventPressed = -1
set EventPresser = null
endif
set j = j + 1
endloop
endif
set i = i + 1
endloop
else
local unit u = GetTriggerUnit()
local player p = GetOwningPlayer(u)
local integer id = GetPlayerId(p)
local integer dt = GetUnitUserData(u)
if Locale == p then
call ClearSelection()
endif
if IsCalibrated[id] then
set EventPresser = p
set EventPressed = dt
call TriggerEvaluate(Handler)
set EventPressed = -1
set EventPresser = null
elseif dt == 9 then
set IsCalibrated[id] = true
endif
set u = null
endif
return false
endfunction
function CalibrateNumberKeys takes integer playerId returns nothing
local integer i
if IsRegistered[playerId] then
set IsCalibrated[playerId] = true
if Locale == Player(playerId) then
call ClearSelection()
set i = 0
loop
exitwhen i > 9
call SelectUnit(KeyUnit[playerId*10+i], true)
call ForceUIKey(I2S(i))
call SelectUnit(KeyUnit[playerId*10+i], false)
set i = i + 1
endloop
endif
endif
static if USE_TIMER then
if Timer == null then
set Timer = CreateTimer()
call TimerStart(Timer, CHECK_RATE, true, function onSelection)
endif
endif
endfunction
function GetPressedNumberKey takes nothing returns integer
return EventPressed
endfunction
function GetPressingPlayer takes nothing returns player
return EventPresser
endfunction
function RegisterAnyNumberKeyEvent takes boolexpr func returns triggercondition
return TriggerAddCondition(Handler, func)
endfunction
function UnregisterAnyNumberKeyEvent takes triggercondition tc returns nothing
call TriggerRemoveCondition(Handler, tc)
endfunction
private function init takes nothing returns nothing
local integer i = 0
local integer j
local integer k
local player p
static if not USE_TIMER then
local trigger t = CreateTrigger()
call TriggerAddCondition(t, Condition(function onSelection))
endif
set Locale = GetLocalPlayer()
loop
exitwhen i > 11
set p = Player(i)
set IsRegistered[i] = GetPlayerController(p) == MAP_CONTROL_USER and GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING
if IsRegistered[i] then
set j = 0
loop
exitwhen j > 9
set k = i*10+j
set KeyUnit[k] = CreateUnit(p, DUMMY_ID, DUMMY_X, DUMMY_Y, 0)
static if not USE_TIMER then
call TriggerRegisterUnitEvent(t, KeyUnit[k], EVENT_UNIT_SELECTED)
call SetUnitUserData(KeyUnit[k], j)
endif
call SetUnitX(KeyUnit[k], DUMMY_X)
call SetUnitY(KeyUnit[k], DUMMY_Y)
call PauseUnit(KeyUnit[k], true)
set j = j + 1
endloop
endif
set i = i + 1
endloop
endfunction
endlibrary