Files
factorio-scenario-ExpCluster/ExpCore/gui.lua
2018-03-13 17:06:01 +00:00

183 lines
7.9 KiB
Lua

--[[
Explosive Gaming
This file can be used with permission but this and the credit below must remain in the file.
Contact a member of management on our discord to seek permission to use our code.
Any changes that you may make to the code are yours but that does not make the script yours.
Discord: https://discord.gg/r6dC2uK
]]
local Gui = {}
local Gui_data = {}
-- only really used when parts of expcore are missing, or script debuging (ie to store the location of frames)
function Gui._global(reset)
global.exp_core = not reset and global.exp_core or {}
global.exp_core.gui = not reset and global.exp_core.gui or {}
return global.exp_core.gui
end
-- this is to enforce the read only propetry of the gui
function Gui._add_data(key,value_key,value)
if game then return end
if not Gui_data[key] then Gui_data[key] = {} end
Gui_data[key][value_key] = value
end
function Gui._get_data(key) return Gui_data[key] end
function Gui:_load_parts(parts)
for _,part in pairs(parts) do
self[part] = require('/GuiParts/'..part)
end
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 progressbar
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
--- Used to set the index of a drop down to a certian item
-- @usage Gui.set_dropdown_index(dropdown,player.name)
-- @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 dropdown and dropdown.valid and dropdown.items and _item then else 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
Event.register(-1,function(event)
Server.new_thread{
name='camera-follow',
data={cams={},cam_index=1,players={}}
}:on_event('tick',function(self)
local _cam = self.data.cams[self.data.cam_index]
if not _cam then self.data.cam_index = 1 _cam = self.data.cams[self.data.cam_index] end
if not _cam then return end
if not _cam.cam.valid then table.remove(self.data.cams,self.data.cam_index)
elseif not _cam.entity.valid then table.remove(self.data.cams,self.data.cam_index)
else _cam.cam.position = _cam.entity.position if not _cam.surface then _cam.cam.surface_index = _cam.entity.surface.index end self.data.cam_index = self.data.cam_index+1
end
end):on_event('error',function(self,err)
-- posible error handling if needed
error(err)
end):on_event(defines.events.on_player_respawned,function(self,event)
if self.data.players[event.player_index] then
local remove = {}
for index,cam in pairs(self.data.players[event.player_index]) do
Gui.cam_link{cam=cam,entity=Game.get_player(event).character}
if not cam.valid then table.insert(remove,index) end
end
for _,index in pairs(remove) do
table.remove(self.data.players[event.player_index],index)
end
end
end):open()
end)
--- Adds a camera that updates every tick (or less depeading 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']}
-- @param entity this is the entity that the camera will follow
-- @param[opt] cam a camera that you already have in the gui
-- @param[opt] frame the frame to add the camera to, no effect if cam param is given
-- @param[chain=frame] zoom the zoom to give the new camera
-- @param[chain=frame] width the width to give the new camera
-- @param[chain=frame] height the height to give the new camera
-- @param[opt] surface this will over ride the surface that the camera follows on, allowing for a 'ghost surface' while keeping same position
-- @param[opt] respawn_open if set to true then the camera will auto re link to the player after a respawn
-- @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.zomm = 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._thread or not Server.get_thread('camera-follow') then
if not Gui._global().cams then
Gui._global().cams = {}
Gui._global().cam_index = 1
end
if data.cam then
local surface = data.surface and data.surface.index or nil
table.insert(Gui._global().cams,{cam=data.cam,entity=data.entity,surface=surface})
end
if not Gui._global().players then
Gui._global().players = {}
end
if data.respawn_open then
if data.entity.player then
if not Gui._global().players[data.entity.player.index] then Gui._global().players[data.entity.player.index] = {} end
table.insert(Gui._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
Event.register(defines.events.on_tick, function(event)
if Gui.left and ((event.tick+10)/(3600*game.speed)) % 15 == 0 then
Gui.left.update()
end
if Gui._global().cams and is_type(Gui._global().cams,'table') and #Gui._global().cams > 0 then
local _cam = Gui._global().cams[Gui._global().cam_index]
if not _cam then Gui._global().cam_index = 1 _cam = Gui._global().cams[Gui._global().cam_index] end
if not _cam then return end
if not _cam.cam.valid then table.remove(Gui._global().cams,Gui._global().cam_index)
elseif not _cam.entity.valid then table.remove(Gui._global().cams,Gui._global().cam_index)
else _cam.cam.position = _cam.entity.position if not _cam.surface then _cam.cam.surface_index = _cam.entity.surface.index end Gui._global().cam_index = Gui._global().cam_index+1
end
end
end)
Event.register(defines.events.on_player_respawned,function(event)
if Gui._global().players and is_type(Gui._global().players,'table') and #Gui._global().players > 0 and Gui._global().players[event.player_index] then
local remove = {}
for index,cam in pairs(Gui._global().players[event.player_index]) do
Gui.cam_link{cam=cam,entity=Game.get_player(event).character}
if not cam.valid then table.insert(remove,index) end
end
for _,index in pairs(remove) do
table.remove(Gui._global().players[event.player_index],index)
end
end
end)
return Gui