시나리오/모드 제작시 도움이 될만한 커맨드를 만들어왔다.
사용방법은,
밑에 ■■ 사이에 있는거 복사해서 그냥 채팅창에 붙여넣고 엔터치면 된다.
블랙리스트 내용만 필요에 따라 수정하면 된다. 의미없이 화면을 뒤덮는 이벤트를 블랙리스트에 넣으면 된다.
메모장에 하나 넣어두고 써.
on_player_changed_position은 타일에서 타일로 이동하거나, 같은 surface내에서 teleport를 쓸 때 발동하더라.
플레이어 이동은 발동조건이랑 내용은 단순한데 불편해서 블랙리스트.
on_entity_damaged도 여기저기서 피해가 발생하고 있을땐 블랙리스트에 넣을만함.
on_selected_entity_changed도 거슬릴때 있더라
세이브가 안되는 무표기 전역변수를 사용하니까 멀티에서는 쓰지말고.
멀티에서 쓰려면 아예 시나리오 파일의 control.lua에 등록해야함.
무표기 전역변수를 쓰고, 이벤트 등록을 커맨드로 변경한건 save가 안되기 때문에,
추적기를 끄는 방법은 단순하게 맵을 저장했다가 다시 불러오는거다.
-------------------------------------
script.on_event 에 사용하는 이벤트만 추적하기 때문에, on_init, on_load, on_configuration_changed, on_nth_tick 같은건 블랙리스트에 없어도 추적을 안한다. 앞에 세개는 게임하는중엔 발동도 안함.
시나리오에서 걸어둔 이벤트 필터를 그대로 살려두기 때문에, 필터가 걸린 이벤트는 조건이 안맞으면 발동을 안할 수 있음. 왜냐면 필터를 풀면 시나리오가 고장날 수도 있어서...
https://lua-api.factorio.com/latest/Event-Filters.html
혹시 추적기를 걸었는데 이벤트가 발생해야하는데 안하는거 같다 그러면 시나리오 안에서 필터를 걸어둔거임. 그럴땐 소스코드 뒤져서 어떤 필터가 걸려있는지 찾아야함.
아니면 필터가 제대로 걸려있는지 테스트하는 목적으로 써도 되고.
모드로 만들면, 현재 돌리고 있는 시나리오, 바닐라의 base 모드 및 기타 모드들의 이벤트 등록은 독립적이라서, 이벤트 필터 관계없이 모니터링 할 수 있을거 같아.
반대로 모드에서 건 필터는 채팅창의 커맨드에서 쓰는거(이벤트가 시나리오 레벨에서 등록됨)랑 관계가 없으니 제작한 모드에서 건 필터가 걸려있는지 확인하는 용도로는 쓸 수 없다.
-------------------------------------
화이트리스트 버전도 필요할까...? 싶은건 좀 그닥인건,
그냥 스크립트 안에다 만들어둔 이벤트 처리 함수에다가 확인용도로 game.print(뭐시기) 한줄 넣으면 되잖아?
밑에 코드 좀만 수정하면 화이트리스트 버전으로 바꿀 수 있을거임. 지우는 용도인 del 함수 고치면 되지.
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
local blacklist = {
'on_tick',
'on_chunk_generated',
'on_player_changed_position',
}
local copy = function(t) local r = {} for k, v in pairs(t) do r[k] = v end return r end
local del = function(t,d) for _, k in pairs(d) do t[k] = nil end return t end
local null_to_name = function(e) for k, v in pairs(e) do
pcall(function() if e[k].name then e[k] = '[color=cyan]'..tostring(v.name)..'[/color]' end end)
pcall(function() if e[k].object_name then e[k] = '[color=purple]'..tostring(v.object_name)..'[/color]' end end)
end e.name = nil e.tick = nil end
local get_handlers = function(event_list)
local r = {}
for k, v in pairs(event_list) do
r[k] = script.get_event_handler(v)
if not r[k] then r[k] = true end
end
return r
end
local set_handlers = function(handler_list)
if not prevent_repeat_use then
for k, v in pairs(handler_list) do
if type(v) == 'function' then
local f = v
script.on_event(
defines.events[k],
function(e)
f(e)
local tick = e.tick
event_counter[k] = event_counter[k] + 1
if k == 'on_console_command' then e.parameters = '[color=pink](생략)[/color]' end
if k == 'on_console_chat' then e.message = '[color=pink](생략)[/color]' end
null_to_name(e)
game.print{"",'[color=0.5,0.5,0.5][font=count-font]',tick,' : [color=yellow][font=default-game]',k,'[/font][/color] ',event_counter[k],'[/font][/color] ',
game.table_to_json(e),
}
end,
script.get_event_filter(defines.events[k])
)
else
script.on_event(
defines.events[k],
function(e)
local tick = e.tick
event_counter[k] = event_counter[k] + 1
if k == 'on_console_command' then e.parameters = '[color=pink](생략)[/color]' end
if k == 'on_console_chat' then e.message = '[color=pink](생략)[/color]' end
null_to_name(e)
game.print{"",'[color=0.5,0.5,0.5][font=count-font]',tick,' : [color=yellow][font=default-game]',k,'[/font][/color] ',event_counter[k],'[/font][/color] ',
game.table_to_json(e),
}
end,
script.get_event_filter(defines.events[k])
)
end
end
game.print('이벤트 추적기를 달았음')
else
game.print('이벤트 추적기가 이미 달려있음')
end
end
event_counter = copy(defines.events)
for k, _ in pairs(event_counter) do event_counter[k] = 0 end
set_handlers(get_handlers(del(copy(defines.events), blacklist)))
prevent_repeat_use = true
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
shift+space로 일시정지가 되니까 뭔가 중요한 이벤트가 나온거 같다 그러면 일시정지걸고 보면 됨.
수정하나 했다. event.name이랑 event.tick은 중복정보라서 안나오게 했다.