316 lines
10 KiB
Lua
316 lines
10 KiB
Lua
--[[
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
C A M E R A S
|
|
|
|
v 1.09 21/08/2022 (cam size opt, screen cameras, fix active cam limits, removed position tracking)
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
|
|
** Usage:
|
|
Add this file to mod root, and this to your control.lua events:
|
|
|
|
require "cameras"
|
|
|
|
cam_on_init() ==> on_init / on_changed
|
|
cam_on_tick(event) ==> on_tick
|
|
cam_on_gui_click(event) ==> on_gui_click - on the last line of the event
|
|
|
|
|
|
** Create cameras with:
|
|
CreateCameraForConnectedPlayers(Object,Surface,Text,size,seconds,Zoom)
|
|
CreateCameraForForce(Force,Object,Surface,Text,size,seconds,Zoom)
|
|
CreateCameraForPlayer(player,Object,Surface,Text,size,AutoCloseTick,Zoom)
|
|
|
|
|
|
Parameters:
|
|
Object = may be an entity or a fixed position. If entity is a unit, camera will follow its position
|
|
Surface = optional. If object is entity, gets its surface. If Surface is nil and Object is not entity, gets nauvis
|
|
Text = nil or {text='Camera', color={r=1,g=1,b=1}}
|
|
size = nil or camera size
|
|
AutoCloseTick = nil or number - when it will be closed in game.tick
|
|
Zoom = nil or Camera Zoon value
|
|
|
|
-- you may add these to load game settings (optional)
|
|
global.disabled_player_camera[player.name] (bool) -- per player
|
|
global.enable_drag_camera[player.name] (bool) -- per player
|
|
global.camera_size[player.name] (int) -- per player
|
|
|
|
global.camera_count_limit (integer) - global
|
|
]]
|
|
|
|
|
|
--default values. May be changed by your mod
|
|
mod_name="Big-Monsters"
|
|
Camera_Default_Zoon = 0.25
|
|
Camera_Default_Size = 230
|
|
Camera_Default_Text = 'Camera'
|
|
Camera_Default_Icon = '[img=utility/gps_map_icon]'
|
|
Camera_Default_Time = nil -- Number - how many ticks it stays on screen. nil => undefined, 60 => 1 second
|
|
Camera_Count_Limit = 5
|
|
|
|
|
|
|
|
|
|
local function get_cam_gui(player)
|
|
local gui
|
|
if global.enable_drag_camera and global.enable_drag_camera[player.name] then
|
|
gui = player.gui.screen
|
|
else
|
|
gui = player.gui.left
|
|
if not gui.mf_flow_cameras then gui.add({type="flow", name="mf_flow_cameras", direction="horizontal"}) end
|
|
gui =player.gui.left.mf_flow_cameras
|
|
end
|
|
return gui
|
|
end
|
|
|
|
|
|
|
|
|
|
--## CAMERAS
|
|
-- Object may be an entity or a fixed position, if entity, camera will follow it
|
|
function CreateCameraForPlayer(player,Object,Surface,Text,size,AutoCloseTick,Zoom)
|
|
cam_player_list_validate_cams(player)
|
|
local cams = global.active_player_cameras[player.name]
|
|
local limit = global.camera_count_limit or Camera_Count_Limit
|
|
if #cams<Camera_Count_Limit then
|
|
if Zoom==nil then Zoom=Camera_Default_Zoon end
|
|
if size==nil
|
|
then
|
|
size=Camera_Default_Size
|
|
if global.camera_size and global.camera_size[player.name] then size=global.camera_size[player.name] end
|
|
end
|
|
local tick=game.tick
|
|
local gui = get_cam_gui(player)
|
|
-- gui.style.horizontally_stretchable = false
|
|
|
|
while gui["mf_framecam"..tick] do tick=tick+1 end
|
|
local frname="mf_framecam"..tick
|
|
local frame = gui.add({ type="frame", name=frname, direction="vertical"})
|
|
local title_table = frame.add{type="table", name="title_table", column_count=5, draw_horizontal_lines=false}
|
|
title_table.style.horizontally_stretchable = true
|
|
title_table.style.column_alignments[1] = "left"
|
|
title_table.style.column_alignments[2] = "left"
|
|
title_table.style.column_alignments[3] = "right"
|
|
title_table.style.column_alignments[4] = "right"
|
|
title_table.style.column_alignments[5] = "right"
|
|
|
|
--frame.style.horizontally_stretchable = false
|
|
--frame.style.minimal_height = size+55
|
|
--frame.style.maximal_height = size+55
|
|
--frame.style.minimal_width = size+10
|
|
--frame.style.maximal_width = size+10
|
|
|
|
local position
|
|
|
|
if (not AutoCloseTick) and Camera_Default_Time then AutoCloseTick=Camera_Default_Time end
|
|
|
|
if Object and Object.valid and Object.position then --if its an entity
|
|
Surface=Object.surface
|
|
position=Object.position
|
|
local tabdata = {player=player, camframe=frame,tick=tick, entity=Object,autoclosetick=AutoCloseTick}
|
|
table.insert(global.mf_frame_cameras,tabdata)
|
|
else
|
|
if Surface==nil then Surface=game.surfaces[1] end
|
|
local tabdata = {player=player, camframe=frame,tick=tick, entity=nil,autoclosetick=AutoCloseTick}
|
|
table.insert(global.mf_frame_cameras,tabdata)
|
|
position=Object
|
|
end
|
|
|
|
local Capt = Camera_Default_Text
|
|
if Text then Capt = Text end
|
|
|
|
|
|
local title_frame = title_table.add{type="frame", name="title_frame", caption=Camera_Default_Icon, style="ic_title_frame"} --
|
|
|
|
title_frame.ignored_by_interaction = true
|
|
|
|
-- local tab = frame.add{type = "table", column_count = 4}
|
|
local title = title_table.add{type = "label", caption = Capt}
|
|
|
|
title.style.font = "default-bold"
|
|
title.style.maximal_width = math.max (size - 120,50)
|
|
|
|
|
|
if gui==player.gui.screen then
|
|
frame.auto_center = true
|
|
title.drag_target = frame
|
|
title_table.drag_target = frame
|
|
end
|
|
|
|
local zoomin = title_table.add{name="mf_bt_camerazoomin"..tick, type="sprite-button", sprite = "utility/speed_up", style = "shortcut_bar_button_small"}
|
|
local zoomout= title_table.add{name="mf_bt_camerazoomout"..tick,type="sprite-button", sprite = "utility/editor_speed_down", style = "shortcut_bar_button_small"}
|
|
local closeb = title_table.add{name="mf_bt_cameraclose"..tick, type="sprite-button", sprite = "utility/close_black", style = "shortcut_bar_button_small"}
|
|
|
|
|
|
--if Text and Text.color then title.style.font_color = Text.color end
|
|
|
|
local surface_index = Surface.index
|
|
|
|
local cam = frame.add({ type="camera", name="mf_camera"..tick, position = position, surface_index=surface_index, zoom = Zoom })
|
|
cam.style.width = size
|
|
cam.style.height = size
|
|
if Object and Object.valid and Object.position then cam.entity=Object end --if its an entity
|
|
--frame.force_auto_center()
|
|
table.insert (global.active_player_cameras[player.name],frname)
|
|
end
|
|
end
|
|
|
|
|
|
function CreateCameraForConnectedPlayers(Object,Surface,Text,size,seconds,Zoom)
|
|
local AutoCloseTick
|
|
if seconds then AutoCloseTick = game.tick + seconds*60 end
|
|
for p, pl in pairs(game.connected_players) do
|
|
CreateCameraForPlayer(pl,Object,Surface,Text,size,AutoCloseTick,Zoom)
|
|
end
|
|
end
|
|
|
|
function CreateCameraForForce(Force,Object,Surface,Text,size,seconds,Zoom)
|
|
local AutoCloseTick
|
|
if seconds then AutoCloseTick = game.tick + seconds*60 end
|
|
for p, pl in pairs(Force.connected_players) do
|
|
if not global.disabled_player_camera[pl.name] then CreateCameraForPlayer(pl,Object,Surface,Text,size,AutoCloseTick,Zoom) end
|
|
end
|
|
end
|
|
|
|
|
|
function CloseAllCameras()
|
|
if #global.mf_frame_cameras>0 then
|
|
for K,tabdata in pairs (global.mf_frame_cameras) do
|
|
local frame = tabdata.camframe
|
|
if frame and frame.valid then frame.destroy() end
|
|
end
|
|
global.mf_frame_cameras = {}
|
|
end
|
|
|
|
|
|
global.active_player_cameras = {}
|
|
end
|
|
|
|
|
|
function CloseAllCamerasForPlayer(player)
|
|
if #global.mf_frame_cameras>0 then
|
|
for K,tabdata in pairs (global.mf_frame_cameras) do
|
|
local frame = tabdata.camframe
|
|
if player==frame.gui.player then
|
|
if frame and frame.valid then frame.destroy() end end
|
|
end
|
|
global.mf_frame_cameras = {}
|
|
end
|
|
if global.active_player_cameras[player.name] then global.active_player_cameras[player.name] = {} end
|
|
end
|
|
|
|
|
|
local function get_gps_cam_tag(position,surface)
|
|
local r = '[gps='..math.floor(position.x)..','..math.floor(position.y)
|
|
if surface then r=r..','..surface.name end
|
|
r=r..']'
|
|
return r
|
|
end
|
|
|
|
|
|
function del_cam_list(list, obj)
|
|
for i, obj2 in pairs(list) do
|
|
if obj2 == obj then
|
|
table.remove( list, i )
|
|
return(true)
|
|
end
|
|
end
|
|
return(false)
|
|
end
|
|
|
|
|
|
-- Gui click
|
|
function CameraClose(player,gui)
|
|
local frame = gui.parent.parent
|
|
local name = frame.name
|
|
del_cam_list(global.active_player_cameras[player.name], name)
|
|
table.remove(global.active_player_cameras[player.name],c)
|
|
frame.destroy()
|
|
end
|
|
|
|
function CameraZoomIn(player,gui,num)
|
|
local frame = gui.parent.parent
|
|
local cam = frame["mf_camera"..num]
|
|
local z = cam.zoom
|
|
if z>0.1 then cam.zoom = z - 0.05 end
|
|
end
|
|
|
|
function CameraZoomOut(player,gui,num)
|
|
local frame = gui.parent.parent
|
|
local cam = frame["mf_camera"..num]
|
|
local z = cam.zoom
|
|
if z<1 then cam.zoom = z + 0.1 end
|
|
end
|
|
|
|
function ClickCamera(player,gui,num)
|
|
local frame = gui.parent
|
|
local cam = frame["mf_camera"..num]
|
|
local surface = game.surfaces[cam.surface_index]
|
|
local position = cam.position
|
|
if cam.entity and cam.entity.valid then position = cam.entity.position end
|
|
player.print(get_gps_cam_tag(position,surface))
|
|
end
|
|
|
|
-- ************ EVENTS ********************************
|
|
|
|
|
|
function cam_on_gui_click(event)
|
|
if event and event.element and event.element.valid and event.player_index and game.players[event.player_index] then
|
|
if event.element.get_mod()==mod_name then
|
|
local player = game.players[event.player_index]
|
|
local gui = event.element
|
|
local name= gui.name
|
|
if string.sub(name,1,17)=="mf_bt_cameraclose" then CameraClose(player,gui)
|
|
elseif string.sub(name,1,18)=="mf_bt_camerazoomin" then CameraZoomIn(player,gui,string.sub(name,19,string.len(name)))
|
|
elseif string.sub(name,1,19)=="mf_bt_camerazoomout" then CameraZoomOut(player,gui,string.sub(name,20,string.len(name)))
|
|
elseif string.sub(name,1,9)=="mf_camera" then ClickCamera(player,gui,string.sub(name,10,string.len(name)))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
--#Camera Updates
|
|
function cam_on_tick(event)
|
|
if #global.mf_frame_cameras>0 then
|
|
for K=#global.mf_frame_cameras,1,-1 do
|
|
local frame = global.mf_frame_cameras[K].camframe
|
|
local tick = global.mf_frame_cameras[K].tick
|
|
local autoclosetick = global.mf_frame_cameras[K].autoclosetick
|
|
if frame and frame.valid then
|
|
if autoclosetick and autoclosetick<game.tick then
|
|
table.remove(global.mf_frame_cameras,K)
|
|
frame.destroy()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function cam_on_init()
|
|
global.mf_frame_cameras = global.mf_frame_cameras or {}
|
|
global.active_player_cameras = global.active_player_cameras or {}
|
|
global.disabled_player_camera = global.disabled_player_camera or {}
|
|
global.enable_drag_camera = global.enable_drag_camera or {}
|
|
global.camera_size = global.camera_size or {}
|
|
end
|
|
|
|
|
|
local function cam_exists(player,cam_name)
|
|
if (player.gui.left.mf_flow_cameras and player.gui.left.mf_flow_cameras[cam_name]) or (player.gui.screen[cam_name]) then return true
|
|
else return false end
|
|
end
|
|
|
|
|
|
function cam_player_list_validate_cams(player)
|
|
if player and player.valid then
|
|
global.active_player_cameras[player.name] = global.active_player_cameras[player.name] or {}
|
|
for c=#global.active_player_cameras[player.name],1,-1 do
|
|
if not cam_exists(player,global.active_player_cameras[player.name][c]) then
|
|
table.remove(global.active_player_cameras[player.name],c)
|
|
end
|
|
end
|
|
end
|
|
end |