Files
factorio-scenario-ExpCluster/modules/ExpGamingCore/Gui/control.lua
2019-01-11 22:32:30 +00:00

189 lines
7.9 KiB
Lua

--- Adds a objective version to custom guis.
-- @module ExpGamingCore.Gui
-- @alias Gui
-- @author Cooldude2606
-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE
local Game = require('FactorioStdLib.Game')
local Color = require('FactorioStdLib.Color')
local Server -- ExpGamingCore.Server@?^4.0.0
local Gui = {}
local global = global()
--- Used to set and get data about different guis
-- @usage Gui.data[location] -- returns the gui data for that gui location ex center
-- @usage Gui.data(location,gui_name,gui_data) -- adds gui data for a gui at a location
-- @tparam string location the location to get/set the data, center left etc...
-- @tparam[opt] string key the name of the gui to set the value of
-- @param[opt] value the data that will be set can be any value but table advised
-- @treturn[1] table all the gui data that is located in that location
Gui.data = setmetatable({},{
__call=function(tbl,location,key,value)
if not location then return tbl end
if not key then return rawget(tbl,location) or rawset(tbl,location,{}) and rawget(tbl,location) end
if game then error('New guis cannot be added during runtime',2) end
if not rawget(tbl,location) then rawset(tbl,location,{}) end
rawset(rawget(tbl,location),key,value)
end
})
--- Add a white bar to any gui frame
-- @usage Gui.bar(frame,100)
-- @param frame the frame to draw the line to
-- @param[opt=10] width the width of the bar
-- @return the line that was made type is progress bar
function Gui.bar(frame,width)
local line = frame.add{
type='progressbar',
size=1,
value=1
}
line.style.height = 3
line.style.width = width or 10
line.style.color = defines.color.white
return line
end
--- Adds a label that is centered
-- @usage Gui.centered_label(frame, 'Hello, world!')
-- @tparam LuaGuiElement frame the parent frame to add the label to
-- @tparam string string the string that the label will have
function Gui.centered_label(frame, string)
local flow = frame.add {frame = 'flow'}
local flow_style = flow.style
flow_style.align = 'center'
flow_style.horizontally_stretchable = true
local label = flow.add {type = 'label', caption = string}
local label_style = label.style
label_style.align = 'center'
label_style.single_line = false
return label
end
--- Used to set the index of a drop down to a certain item
-- @usage Gui.set_dropdown_index(dropdown,player.name) -- will select the index with the players name as the value
-- @param dropdown the dropdown that is to be effected
-- @param _item this is the item to look for
-- @return returns the dropdown if it was successful
function Gui.set_dropdown_index(dropdown,_item)
if not dropdown or not dropdown.valid or not dropdown.items or not _item then return end
local _index = 1
for index, item in pairs(dropdown.items) do
if item == _item then _index = index break end
end
dropdown.selected_index = _index
return dropdown
end
--- Prams for Gui.cam_link
-- @table ParametersForCamLink
-- @field entity this is the entity that the camera will follow
-- @field cam a camera that you already have in the gui
-- @field frame the frame to add the camera to, no effect if cam param is given
-- @field zoom the zoom to give the new camera
-- @field width the width to give the new camera
-- @field height the height to give the new camera
-- @field surface this will over ride the surface that the camera follows on, allowing for a 'ghost surface' while keeping same position
-- @field respawn_open if set to true then the camera will auto re link to the player after a respawn
--- Adds a camera that updates every tick (or less depending on how many are opening) it will move to follow an entity
-- @usage Gui.cam_link{entity=game.player.character,frame=frame,width=50,hight=50,zoom=1}
-- @usage Gui.cam_link{entity=game.player.character,cam=frame.camera,surface=game.surfaces['testing']}
-- @tparam table data contains all other params given below
-- @return the camera that the function used be it made or given as a param
function Gui.cam_link(data)
if not data.entity or not data.entity.valid then return end
if is_type(data.cam,'table') and data.cam.__self and data.cam.valid then
data.cam = data.cam
elseif data.frame then
data.cam={}
data.cam.type='camera'
data.cam.name='camera'
data.cam.position= data.entity.position
data.cam.surface_index= data.surface and data.surface.index or data.entity.surface.index
data.cam.zoom = data.zoom
data.cam = data.frame.add(data.cam)
data.cam.style.width = data.width or 100
data.cam.style.height = data.height or 100
else return end
if not Server or not Server.get_thread('camera-follow') then
if not global.cams then
global.cams = {}
global.cam_index = 1
end
if data.cam then
local surface = data.surface and data.surface.index or nil
table.insert(global.cams,{cam=data.cam,entity=data.entity,surface=surface})
end
if not global.players then
global.players = {}
end
if data.respawn_open then
if data.entity.player then
if not global.players[data.entity.player.index] then global.players[data.entity.player.index] = {} end
table.insert(global.players[data.entity.player.index],data.cam)
end
end
else
local thread = Server.get_thread('camera-follow')
local surface = data.surface and data.surface.index or nil
table.insert(thread.data.cams,{cam=data.cam,entity=data.entity,surface=surface})
if data.respawn_open then
if data.entity.player then
if not thread.data.players[data.entity.player.index] then thread.data.players[data.entity.player.index] = {} end
table.insert(thread.data.players[data.entity.player.index],data.cam)
end
end
end
return data.cam
end
script.on_event('on_tick', function(event)
if loaded_modules['ExpGamingCore.Server'] then return end
if global.cams and is_type(global.cams,'table') and #global.cams > 0 then
local update = 4
if global.cam_index >= #global.cams then global.cam_index = 1 end
if update > #global.cams then update = #global.cams end
for cam_offset = 0,update do
local _cam = global.cams[global.cam_index+cam_offset]
if not _cam then break end
if not _cam.cam.valid then table.remove(global.cams,global.cam_index)
elseif not _cam.entity.valid then table.remove(global.cams,global.cam_index)
else _cam.cam.position = _cam.entity.position if not _cam.surface then _cam.cam.surface_index = _cam.entity.surface.index end global.cam_index = global.cam_index+1
end
end
global.cam_index = global.cam_index+update
end
end)
script.on_event('on_player_respawned',function(event)
if loaded_modules['ExpGamingCore.Server'] then return end
if global.players and is_type(global.players,'table') and #global.players > 0 and global.players[event.player_index] then
local remove = {}
local player = Game.get_player(event)
for index,cam in pairs(global.players[event.player_index]) do
if cam.valid then table.insert(global.cams,{cam=cam,entity=player.character,surface=player.surface})
else table.insert(remove,index) end
end
for n,index in pairs(remove) do
table.remove(global.players[event.player_index],index-n+1)
end
end
end)
function Gui:on_init()
if loaded_modules['ExpGamingCore.Server'] then
Server = require('ExpGamingCore.Server')
verbose('ExpGamingCore.Server is installed; Loading server src')
script.on_init(require(module_path..'/src/server',{Gui=self}))
end
end
function Gui.on_post()
Gui.test = require(module_path..'/src/test',{Gui=Gui})
end
return Gui