예제 댓글에 타일에 전기흐르게? 해달라는 글이 하나보여서 그게 가능할까? 고찰을 해보도록 하자.


우선

전신주 : https://wiki.factorio.com/Prototype/ElectricPole

타일 : https://wiki.factorio.com/Prototype/Tile

프로토타입은 전혀 달라서 호환이 전혀 안된다. 상속관계도 없다.

타일에는 전신주에 있는 supply어쩌고가 코빼기도 안보인다.

쟤 기능을 쟤한테 옮기질 못한다 이말이다.


그럼 API에서 구현가능성 답을 찾아봐야하는데, 가능성을 따져보자.


API로 할 수 있는 일 중에 프로토타입에서는 지원을 안하지만 여러가지 기능을 동시에하는 무언가를 만드는 경우,

이게 만들어지면 저것도 같이 만들고, 저건 안보이게 숨긴다거나,

이것도 저것도 안되면 한놈만 만들고 원하는 기능을 하도록 스크립트로 존나게 복잡하게 구현하는거다.


내 생각에는 타일을 깔면 전봇대를 숨기거나 투명전봇대를 깔면 타일을 같이 깔거나 하는 식으로 하면 존나 복잡하게 안만들어도 될 것 같다.


그럼 진짜 될라나? 고찰한번 해보자.



API에서 제공하는 이벤트 목록 중에

https://lua-api.factorio.com/latest/events.html


타일이 만들어지거나 타일의 종류가 변화하는 것을 알아챌 수 있는 이벤트는

on_chunk_generated -- 만들려고 하는 타일이 autoplace 가능한 타일인 경우.

on_player_built_tile

on_player_mined_tile

on_robot_built_tile

on_robot_mined_tile

내가 알기론 이렇게 5가지가 현재 존재하는데,


on_player_built_tile, on_robot_built_tile 같은 이벤트를 사용해서 특정 타일이 깔리면 그곳에 투명전봇대를 LuaSurface::create_entity 로 만들면 일단 전기가 통하는 타일이 되겠지.

on_player_mined_tile, on_robot_mined_tile 을 사용하면 타일이 채취에 의해 사라지는것을 탐지하고 투명전봇대를 LuaEntity.destroy()를 사용해서 치워버릴 수 있다.


문제는 타일이 손상되는 경우이다.


이것이 모든 타일의 변화를 다 캐치할 수 있느냐하면, 아님. 이다.

예를 들면 핵무기를 발사해서 땅이 시커멓게 되는거는 그 어떤 이벤트도 발생하지 않아서 추적이 불가능하다.

그리고 다른 모드에서 타일을 스크립트로 변경시키면 그것도 추적을 못함. 이건 별수가 없다.

누가 핵을 쐈고 쏜 위치 근처를 모니터링하다가 타일이 바뀌는걸 알아내는 존나 복잡한 코드를 짜거나,

주기적으로 온 맵 타일 검사를 한다거나 하는 아~주 무거운 UPS개떡락 코드를 짜지 않는 이상 못한다.


이런식으로 이벤트 추적능력 밖에서 타일이 사라지면 타일은 없어졌는데 투명전봇대는 남아있는 버그가 생기거나

그걸 주기적으로 온맵을 스캔해서 커버치려고하면 UPS떡락이 찾아온다.



----------------------------------



아무튼 타일은 좀더 이따 생각하기로 하고,

일단 시점을 전봇대로 옮겨보자.


전봇대는 프로토타입 위키 페이지를 참조하면, https://wiki.factorio.com/Prototype/ElectricPole

draw_copper_wires

supply_area_distance

maximum_wire_distance

라는걸 변경할 수 있고, 구리선 안보이게 하고 한칸거리만 연결되게하고, 전기공급 면적을 최소로 하면 될 것 같다고 보여지는 키들이다.

지도에서 전봇대 아이콘이 보여서 불편하지 않을까? 싶은건

flag 키하고,

flag의 값으로써, https://wiki.factorio.com/Types/EntityPrototypeFlags 여기보면 not-on-map 이라는게 있긴 하다. 전선도 안보일지는 모르겠지만.


그리고 더 중요한건 전봇대가 땅속에 심어져서 다른것의 이동이나 놓여지는것을 방해하면 안된다고 하니까,

collision_mask를 손봐야한다.


우선 collision_mask에 대해 이해하기 위해서 이 링크를 한번 보자.

https://wiki.factorio.com/Prototype/Entity#collision_mask

들어가서 NOTE 옆에 expand를 보면 기존 개체들이 어떻게 설정되어있는지 나온다.


같은 collision_mask 내에 있는 entity끼리는 서로 충돌하고 방해한다. 라고 조그맣게 위에 쓰여있지...?

전신주나 전신주랑 같이 취급되는 건물 비슷한게 뭔지 구분이 안간다.

그럼 인게임 들어가서 빠르게 체크를 해보자.


/c for k,v in pairs( game.entity_prototypes['medium-electric-pole'].collision_mask ) do game.print{"",k,", ",v} end

물하고 충돌하고, 바닥에 떨어진 아이템하고 충돌하고, 개체, 플레이어 이렇게 있다.

이거, 디폴트 였네?



그럼 새로 만드는 전신주의 collision-mask에는 water-tile만 추가하면 되는건가?

그러면 위로 지나가는 것들을 방해하지 않을 것이다.



타일이 사라지는것을 완벽히 추적하는 것은 불가능하지만(핵무기 때문에),

투명전신주를 무적이 아니게 만들고,

on_entity_died 이벤트에 전신주의 죽음을 검사해서 전신주가 뒤지면 그 위치에 있는 타일도 같이 자연타일(hidden_tile) 만들면 될 것 같다.

타일이 뭔가 콘크리트 등으로 덮였을 때, 원래 타일을 LuaTile의 hidden_tile 값으로 저장되므로 이 값을 읽어서 되돌리면 되는 것.

https://lua-api.factorio.com/latest/LuaTile.html


대신 공격받을 때마다 타일이 사라지는 불편함은 감수해야겠지만...



----------------------------------


타일이 무적이 아니라니 이게 무슨 소리냐

해서 어떻게든 타일... 아니 투명전봇대를 무적으로 만들어야겠는데, 핵공격을 받으면 정상적으로 사라지는걸 만들고 싶다...

그러면 내가 또 생각이 있는데,

https://wiki.factorio.com/Types/CollisionMask

이걸보면 미사용 layer가 몇개 있다.

이 중에 하나를 채택해서 전기가 흐르게할 타일을 제외한 모~든 타일의 collision_mask에 그 layer를 추가하고, 전기가 흐르는 타일만 그 layer를 뺀다.

그러면 어차피 안쓰이는 layer니까 다른 개체들도 layer랑 충돌할 일이 없다.

그리고 오로지 투명전봇대만 그 layer랑 충돌하게 만든다.


그럼 투명전봇대 입장에선, 전기가 흐르는 타일 위에만 자기가 서있을 수 있고, 다른 타일 위에는 서있으면 충돌이 일어난 상황이되는거지.


위에 서있는게 불가능한 물 타일로 바닥이 바뀌면 위에 있는 엔티티는 걍 사라지던데,

(플레이어 캐릭터만 뒤지고 다른 엔티티는 on_entity_died이벤트도 발생시키지 않고 그냥 사라지던데?)


미사용 layer를 충돌 레이어로 해서 투명전봇대 위에 깔아서 전기가흐르는 타일을 치워버리면 투명전봇대가 제대로 사라질까?

는 만들고 싶은 사람이 테스트를 해봐야겠지.


만들땐 투명전봇대 스프라이트(sprite)를 넣어두고 타일을 깔고 치우고 핵쏴서 밀고에 따라서 투명전봇대가 정확하게 생겼다 없어졌다를 하는지를 우선 확인해보고,

제대로 동작되면 투명전봇대 스프라이트를 없애면 될 것 같다.


----------------------------------


전력공급해주는 바닥 고찰 끝.


만드는건 만들고 싶은 사람이 알아서... 시행착오를 거치며 만드는거임.

하다보면 내가 고찰한대로 안될수도 있고 뭔가 버그를 발견할 수도 있고. 더 나은 방법을 발견할 수도 있고.

그런거임. 뭐 만드는건 오래 걸리는 일이다.