멀티 게임이 존나 하드코어한 경우, 사람이 모일 때까지 일시정지 거는 경우가 종종있는데,
기본 일시정지 기능이 병신같은건 알 사람은 다 알거임.
이건 뭐 채팅도 안되고, 정지된 상태에서 들어오면 까만 화면 밖에 안보이고.
병신같은 기능임.
근데 더 좋은 기능이 있었어.
https://lua-api.factorio.com/latest/LuaGameScript.html#LuaGameScript.tick_paused
이걸 쓰면 game.tick 이 흐르는건 멈추고, game.ticks_played만 흐르는데,
이게 무슨 의미냐면, 게임내 오브젝트 같은것만 업데이트가 멈추고, gui같은건 멀쩡하게 시간이 흘러간다는 거임.
시나리오나 모드에서 시간이 흐름에 따라 뭔가를 조작하는데 많이 쓰는 on_tick 이벤트랑 on_nth_tick 이벤트도 game.tick을 참조하기 때문에,
왠만해선 이걸 아무 시나리오에서나 써도 gui나 사용자 요청이랑 game.tick이 미스매치가 일어나서 고장날 것 같지는 않다.
game.ticks_played는 서버 브라우저의 플레이 시간에도 반영된다. 일시정지되있지만 서버 플탐 기록은 올라간다는 뜻.
어드민이 게임을 일시정지하거나 풀거나 하려고 하는 경우엔
/c game.tick_paused = true
/c game.tick_paused = false
true면 정지, false면 푸는건데, 토글식으로 하려면
/c game.tick_paused = not game.tick_paused
이렇게 입력하면 됨.
근데 /c커맨드를 쓰는건 업적이 막히기 때문에 이걸 우회하려면 세이브 파일의 control.lua만 빼서 커맨드를 추가해주는 작업을 한 뒤, 세이브 압축파일에 도로 집어넣어주면 된다.
(이건 업적막히는거 우회하는 꼼수다. 이런식으로 그 어떤 임의의 코드라도 업적이 뚫린 상태로 실행할 수 있음. 악용하면 스팀업적 의미없어지고 개노잼되니 주의.)
시나리오가 기본 event_handler를 사용하는 경우엔 이렇게 한다.
(프리플레이나 기타 여러가지 기본 시나리오는 이벤트 핸들러를 core\lualib\event_handler.lua를 사용한다.)
시나리오나 모드 제작자가 자체적으로 제작한 이벤트 핸들러를 사용하는 경우 이벤트 등록을 거기에 맞춰서 해줘야 함.
기능상 별 차이가 없지만 lua 모듈 구조를 디렉토리 구조로 만들어서 쓰면 좀 불편해서 새로 만들어 쓰는 듯 함.
--------------- 세이브파일 내부 혹은 시나리오 견본의 control.lua ----------------
local handler = require("event_handler")
--이벤트핸들러 lua 모듈 목록들...블라블라
--이벤트핸들러 lua 모듈 목록들...
local pauser = {
on_load = function()
--on_load : 게임을 불러오거나, 멀티의 참가자가 다운받은 뒤 참가하려는 순간 참가자의 클라이언트에서만 실행되는 이벤트.
commands.add_command( --커맨드를 추가하는 함수. /help로 추가된걸 볼 수 있다.
'pause', ': toggle pause',
function(data)
if data.player_index then --플레이어가 사용하면 data의 key에 이 값이 추가된다.
local player = game.players[data.player_index]
if not player.admin then player.print('not admin') return end --어드민이 아니면 return에서 코드실행 중단
game.tick_paused = not game.tick_paused
game.print(player.name..' paused : '..tostring(game.tick_paused))
localised_print(player.name..' paused : '..tostring(game.tick_paused))
else --서버 콘솔이 사용하는 경우.
game.tick_paused = not game.tick_paused
game.print('<server> paused : '..tostring(game.tick_paused))
localised_print('<server> paused : '..tostring(game.tick_paused))
end
end
)
end
}
pauser.on_init = function() pauser.on_load() end
--on_init : 게임을 처음부터 시작할 때 실행되는 이벤트. script.dat 파일이 시나리오 견본에 없어야 실행된다.
handler.add_lib(pauser)
----------------------------
맵이 기본 event_handler를 사용한다고 위에 코드가 적혀있는 경우,
control.lua 내용 맨밑에다가 local pauser = { 부터 복붙하면 된다.
lua 코드 보기 불편할까봐 색 한번 넣어봤는데,
대략
파랑색은 lua언어의 문법에 포함된 이름들이고
빨간색은 lua언어 및 팩토리오 전역에서 미리 정의되서 왠만하면 어디서든지 그냥 호출하면 쓸 수 있는 변수나 함수임.
핑크색은 string변수고
초록색은 코멘트다.
업적이 상관없더라도,
어드민 말고 아무나 쓰게 해주려면 위처럼 코드를 삽입해줘야하는데,
저기 어드민 아니면 걸러내는 코드 한줄을 지우면 다음 라인으로 통과가 되서 아무나 쓸 수 있다.
업적상관없고 어드민만 쓰려면 위에위에 중간에 적은대로 간단하게 /c로 쓰는 커맨드만 쓰면 됨.
서버 콘솔에서도 저걸로 일시정지를 걸 수 있다.
game.tick_paused는 플레이어가 게임내에서 게임메뉴GUI의 기본 일시정지버튼을 눌러서 일시정지했는지 여부를 알려주지 않음.
서버안에 사람이 있는 경우, 서버콘솔에선
/silent-command localised_print(game.ticks_played)
를 여러번 입력해서 출력값이 큰변동이 없을 경우(1씩 변화할 경우. 1초면 60씩 증가하니까 구분하기 쉬움)
게임이 일시정지 되어있다고 판단하고,
플레이어가 일시정지를 걸어놓고 나갔고, auto-pause설정이 되어있는 경우엔, 일시정지되어있는지 여부를 알 방법이 없는 거 같음.
어드민이 아니더라도 일시정지를 걸 수 있게 서버를 설정했고 누군가 일시정지를 걸어두고 나갔더라도, 그 사이에 새로 방문한 플레이어는 게임메뉴의 해제버튼을 통해서 일시정지를 풀 수가 없음.
다시한번 말하지만 기본 일시정지기능은 채팅도 안되고 화면도 안보이고 서버콘솔에서 체크도 안되고 존나 병신같음.
아무튼 기본 일시정지 기능은 이렇게 존나 병신같으니까 이렇게 다른 방식으로 일시정지하는 방법이 있다는걸 알아둘 수 있으면 알아둿으면 좋겠다.
알려주는 이 방법은 채팅도 되고 지도도 볼 수 있다.
이거 뭐 수정하려니까 들여쓰기랑 \ 문자 다 증발하네; 디씨 어우...
사진으로 찍어서 올려 나도 저번에 회로공략 쓸 때 똑같은 일 있었음
그러면 복붙을 못하잔아
이거 쓰면 업적 못깨는거 아님?
좀 읽어봐라;;; 업적 우회 관련해서 써놨잔아.
이거 웬지 개발자가 보면 막을듯 - dc App
게임하려면 코딩도 할줄 알아야함?? - dc App