Lua 훅
훅은 game.hooks에 있으며 콜백 목록입니다.
훅 등록하기
game.add_hook을 사용하여 훅을 등록합니다:
game.add_hook("on_game_save", function(params)
-- ...
end)
등록 중에 현재 모드 ID를 자동으로 캡처합니다.
우선순위를 설정하기 위해 테이블을 전달할 수도 있습니다:
game.add_hook("on_game_save", {
priority = 10, -- 선택사항 (높을수록 먼저 실행, 기본값 0)
fn = function(params)
-- ...
end
})
실행 순서
훅은 priority가 내림차순으로 실행됩니다. 우선순위가 같으면 삽입 순서가 유지됩니다(안정적).
체이닝과 결과
훅이 실행될 때 params 테이블을 받습니다.
params.results: 이cata.run_hooks호출에 대한 공유 결과 테이블. 훅은 자유롭게 읽고 수정할 수 있습니다.params.prev: 이전 훅의 반환값 (첫 번째 훅의 경우nil).
cata.run_hooks( name )은 동일한 params.results 테이블을 반환합니다.
어떤 훅이 불리언 false를 반환하면, 결과 테이블에 다음이 포함됩니다:
results.allowed = false
훅은 작업의 성공 또는 실패를 나타내기 위해 불리언 true 또는 false를 반환할 수 있습니다. 호출 지점은 또한 성능을 위해 첫 번째 false에서 { .exit_early = true }를 사용하여 조기 종료를 요청할 수 있습니다.
사용 예시
function table_to_string(table)
local result = "{ "
for k, v in pairs(table) do
if type(v) == "table" then
result = result .. tostring(k) .. " = " .. table_to_string(v) .. ", "
else
result = result .. tostring(k) .. " = " .. tostring(v) .. ", "
end
end
result = result .. " }"
return result
end
game.add_hook("on_character_try_move", {
priority = 50,
fn = function(params)
gapi.add_msg("50 priority hook: " .. table_to_string(params))
local map = gapi.get_map()
local to = params.to
local ter_id = map:get_ter_at(to):str_id()
if ter_id:str() == "t_grass" then
gapi.add_msg("The floor is lava!")
return false
end
return true
end,
})
game.add_hook("on_character_try_move", {
priority = 100,
fn = function(params)
params.results.extra_info = "Checked by highest priority hook"
gapi.add_msg("100 priority hook: " .. table_to_string(params))
end,
})
game.add_hook("on_character_try_move", {
priority = 0,
fn = function(params)
gapi.add_msg("0 priority hook: " .. table_to_string(params))
end,
})
다음과 같은 로그 출력을 생성합니다:
turn=1335125 time=" 1 second" type=neutral message="100 priority hook: { to = (66,60,0), from = (65,60,0), results = { extra_info = Checked by highest priority hook, allowed = true, }, char = sol.avatar *: 0x7effcc33ea58, via_ramp = false, movement_mode = 1, }"
turn=1335125 time=" 1 second" type=neutral message="50 priority hook: { to = (66,60,0), from = (65,60,0), results = { 1 = { mod_id = <unknown>, priority = 100, }, extra_info = Checked by highest priority hook, allowed = true, }, char = sol.avatar *: 0x7effcc33ea58, via_ramp = false, movement_mode = 1, }"
turn=1335125 time=" 1 second" type=neutral message="0 priority hook: { to = (66,60,0), from = (65,60,0), results = { 1 = { mod_id = <unknown>, priority = 100, }, 2 = { mod_id = <unknown>, priority = 50, result = true, }, 3 = { mod_id = bn, priority = 0, result = true, }, extra_info = Checked by highest priority hook, allowed = true, }, char = sol.avatar *: 0x7effcc33ea58, prev = true, via_ramp = false, movement_mode = 1, }"
turn=1335125 time=" 1 second" type=warning message="Moving onto this mound of dirt is slow!"
turn=1335126 time=" 0 seconds" type=neutral message="100 priority hook: { to = (67,60,0), from = (66,60,0), results = { extra_info = Checked by highest priority hook, allowed = true, }, char = sol.avatar *: 0x3fe77c38, via_ramp = false, movement_mode = 1, }"
turn=1335126 time=" 0 seconds" type=neutral message="50 priority hook: { to = (67,60,0), from = (66,60,0), results = { 1 = { mod_id = <unknown>, priority = 100, }, extra_info = Checked by highest priority hook, allowed = true, }, char = sol.avatar *: 0x3fe77c38, via_ramp = false, movement_mode = 1, }"
turn=1335126 time=" 0 seconds" type=neutral message="The floor is lava!"
'the floor is lava'일 때, 호출 지점에서 on_character_try_move에 .exit_early가 true로 설정되어 있어 0 우선순위 훅이 취소되는 것을 볼 수 있습니다.