1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-04 00:15:45 +02:00
ComfyFactorio/maps/chronosphere/gui.lua
2024-10-22 21:47:11 +02:00

613 lines
27 KiB
Lua

local Chrono_table = require 'maps.chronosphere.table'
local Public_gui = {}
local math_floor = math.floor
local math_abs = math.abs
local math_max = math.max
local math_min = math.min
local Upgrades = require 'maps.chronosphere.upgrade_list'
local Production = require 'maps.chronosphere.production_list'
local ProdFunctions = require 'maps.chronosphere.production'
local Balance = require "maps.chronosphere.balance"
local Difficulty = require 'modules.difficulty_vote'
local Minimap = require 'maps.chronosphere.minimap'
local function create_gui(player)
local frame = player.gui.top.add({type = 'frame', name = 'chronosphere'})
frame.style.maximal_height = 38
local label
local button
label = frame.add({type = 'label', caption = {'chronosphere.gui_1'}, name = 'label'})
label.style.font_color = {r = 0.88, g = 0.88, b = 0.88}
label.style.font = 'default-bold'
label.style.font_color = {r = 0.33, g = 0.66, b = 0.9}
label = frame.add({type = 'label', caption = ' ', name = 'jump_number'})
label.style.font_color = {r = 0.88, g = 0.88, b = 0.88}
label.style.font = 'default-bold'
label.style.right_padding = 4
label.style.font_color = {r = 0.33, g = 0.66, b = 0.9}
label = frame.add({type = 'label', caption = {'chronosphere.gui_2'}, name = 'charger'})
label.style.font = 'default-bold'
label.style.left_padding = 4
label.style.font_color = {r = 255, g = 200, b = 200} --255 200 200 --150 0 255
label = frame.add({type = 'label', caption = ' ', name = 'charger_value'})
label.style.font = 'default-bold'
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 255, g = 200, b = 200}
local progressbar = frame.add({type = 'progressbar', name = 'progressbar', value = 0, style = 'achievement_progressbar'})
progressbar.style.minimal_width = 96
progressbar.style.maximal_width = 96
progressbar.style.top_padding = 1
label = frame.add({type = 'label', caption = ' ', name = 'timer'})
label.style.font = 'default-bold'
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 255, g = 200, b = 200}
label = frame.add({type = 'label', caption = ' ', name = 'timer_value', tooltip = ' '})
label.style.font = 'default-bold'
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 255, g = 200, b = 200}
label = frame.add({type = 'label', caption = ' ', name = 'timer2'})
label.style.font = 'default-bold'
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 0, g = 200, b = 0}
label = frame.add({type = 'label', caption = ' ', name = 'timer_value2'})
label.style.font = 'default-bold'
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 0, g = 200, b = 0}
-- local line = frame.add({type = "line", direction = "vertical"})
-- line.style.left_padding = 4
-- line.style.right_padding = 8
button = frame.add({type = 'button', caption = {'chronosphere.gui_world_button'}, name = 'world_button'})
button.style.font = 'default-bold'
button.style.font_color = {r = 0.99, g = 0.99, b = 0.99}
button.style.minimal_width = 75
button = frame.add({type = 'button', caption = {'chronosphere.gui_upgrades_button'}, name = 'upgrades_button'})
button.style.font = 'default-bold'
button.style.font_color = {r = 0.99, g = 0.99, b = 0.99}
button.style.minimal_width = 75
end
local function switch_upgrades(player, button)
local playertable = Chrono_table.get_player_table()
if not button then
button = 1
end
playertable.active_upgrades_gui[player.index] = button
local upgrades = Upgrades.upgrades()
if not player.gui.screen['gui_upgrades'] then
return
end
local frame = player.gui.screen['gui_upgrades']
local t2 = frame['production_table']
if button == 4 then
t2.visible = true
for i = 1, #upgrades, 1 do
frame['upgrades_table' .. i].visible = false
end
else
t2.visible = false
for i = 1, #upgrades, 1 do
local t = frame['upgrades_table' .. i]
if button == 1 then
if upgrades[i].type == 'train' and upgrades[i].enabled then
t.visible = true
else
t.visible = false
end
elseif button == 2 then
if upgrades[i].type == 'player' and upgrades[i].enabled then
t.visible = true
else
t.visible = false
end
elseif button == 3 then
if upgrades[i].type == 'quest' and upgrades[i].enabled then
t.visible = true
else
t.visible = false
end
end
end
end
end
local function calculate_xp(key)
local production_table = Chrono_table.get_production_table()
local level = ProdFunctions.calculate_factory_level(production_table.experience[key], false)
return level - math.floor(level)
end
local function update_upgrades_gui(player)
local objective = Chrono_table.get_table()
local playertable = Chrono_table.get_player_table()
local production_table = Chrono_table.get_production_table()
if not player.gui.screen['gui_upgrades'] then
return
end
local upgrades = Upgrades.upgrades()
local frame = player.gui.screen['gui_upgrades']
local tokens = frame['tokens']
for token, value in pairs(objective.research_tokens) do
tokens['token_' .. token].number = value
end
for i = 1, #upgrades, 1 do
local t = frame['upgrades_table' .. i]
t['upgrade' .. i].number = objective.upgrades[i]
t['upgrade' .. i].tooltip = upgrades[i].tooltip
t['upgrade_label' .. i].tooltip = upgrades[i].tooltip
if objective.upgrades[i] == upgrades[i].max_level then
t['maxed' .. i].visible = true
t['jump_req' .. i].visible = false
for index, _ in pairs(upgrades[i].virtual_cost) do
t[index .. '-v' .. i].visible = false
end
for index, _ in pairs(upgrades[i].cost) do
t[index .. '-' .. i].visible = false
end
else
t['maxed' .. i].visible = false
t['jump_req' .. i].visible = true
t['jump_req' .. i].number = upgrades[i].jump_limit
for index, item in pairs(upgrades[i].virtual_cost) do
t[index .. '-v' .. i].visible = true
t[index .. '-v' .. i].number = item.count
end
for index, item in pairs(upgrades[i].cost) do
t[index .. '-' .. i].visible = true
t[index .. '-' .. i].number = item.count
end
end
end
local t2 = frame['production_table']
for key, _ in pairs(Production) do
t2['product' .. key].number = ProdFunctions.calculate_factory_level(production_table.experience[key], true)
t2['product_bar' .. key].value = calculate_xp(key)
t2['product_bar' .. key].tooltip = math.floor(calculate_xp(key) * 1000) / 10 .. '%'
end
switch_upgrades(player, playertable.active_upgrades_gui[player.index])
end
local function ETA_seconds_until_full(power, storedbattery) -- in watts and joules
local objective = Chrono_table.get_table()
local n = objective.chronochargesneeded - objective.chronocharges
if n <= 0 then
return 0
else
local eta = math_max(0, n - storedbattery / 1000000) / (power / 1000000 + objective.passive_chronocharge_rate)
if eta < 1 then
return 1
end
return math_floor(eta)
end
end
local function overstay_timers(gui_element, seconds_ETA, min_jump_passed)
local objective = Chrono_table.get_table()
local overstay, evolution = false, false
local time_until_overstay = (objective.chronochargesneeded * 0.75 / objective.passive_chronocharge_rate - objective.passivetimer)
local time_until_evo = (objective.chronochargesneeded * 0.5 / objective.passive_chronocharge_rate - objective.passivetimer)
local color = {r = 0, g = 0.98, b = 0}
if min_jump_passed then
if time_until_overstay <= seconds_ETA then
color = {r = 0.98, g = 0, b = 0}
elseif time_until_evo <= seconds_ETA then
color = {r = 0.98, g = 0.5, b = 0}
end
end
gui_element.style.font_color = color
local evo_timer = {math_floor(time_until_overstay / 60), math_floor(time_until_overstay) % 60, math_floor(time_until_evo / 60), math_floor(time_until_evo) % 60}
if time_until_overstay < 0 then
evo_timer[2] = 59 - evo_timer[2]
overstay = true
end
if time_until_evo < 0 then
evo_timer[4] = 59 - evo_timer[4]
evolution = true
end
return evo_timer, overstay, evolution
end
local function update_world_gui(player)
if not player.gui.screen['gui_world'] then
return
end
local objective = Chrono_table.get_table()
local difficulty = Difficulty.get().difficulty_vote_value
local overstay_jump = Balance.jumps_until_overstay_is_on(difficulty) or 3
local world = objective.world
local evolution = game.forces['enemy'].get_evolution_factor(game.get_surface(objective.active_surface_index))
local evo_color = {
r = math_floor(255 * 1 * math_max(0, math_min(1, 1.2 - evolution * 2))),
g = math_floor(255 * 1 * math_max(math_abs(0.5 - evolution * 1.5), 1 - evolution * 4)),
b = math_floor(255 * 4 * math_max(0, 0.25 - math_abs(0.5 - evolution)))
}
local frame = player.gui.screen['gui_world']
frame['world_name'].caption = {'chronosphere.gui_world_0', world.variant.name}
frame['world_ores']['iron-ore'].number = world.variant.fe
frame['world_ores']['copper-ore'].number = world.variant.cu
frame['world_ores']['coal'].number = world.variant.c
frame['world_ores']['stone'].number = world.variant.s
frame['world_ores']['uranium-ore'].number = world.variant.u
frame['world_ores']['oil'].number = world.variant.o
frame['richness'].caption = {'chronosphere.gui_world_2', world.ores.name}
frame['world_biters'].caption = {'chronosphere.gui_world_3', math_floor(evolution * 100)}
frame['world_biters'].style.font_color = evo_color
frame['world_biters3'].caption = {'chronosphere.gui_world_4_1', objective.overstaycount * 2.5, objective.overstaycount * 10}
frame['world_time'].caption = {'chronosphere.gui_world_5', world.dayspeed.name}
local timers, overstayed, _ = overstay_timers(frame['overstay_time'], ETA_seconds_until_full(0, 0), objective.chronojumps >= overstay_jump)
if objective.jump_countdown_start_time == -1 then
if objective.chronojumps >= overstay_jump then
if overstayed then
frame['overstay_time'].caption = {'chronosphere.gui_overstayed'}
else
frame['overstay_time'].caption = {'chronosphere.gui_world_6', timers[1], timers[2]}
end
else
frame['overstay_time'].caption = {'chronosphere.gui_world_7', overstay_jump}
end
else
if objective.chronojumps >= overstay_jump then
if overstayed then
frame['overstay_time'].caption = {'chronosphere.gui_overstayed'}
else
frame['overstay_time'].caption = {'chronosphere.gui_not_overstayed'}
end
else
frame['overstay_time'].caption = {'chronosphere.gui_world_7', overstay_jump}
end
end
end
local function world_gui(player)
if player.gui.screen['gui_world'] then
player.gui.screen['gui_world'].destroy()
return
end
local objective = Chrono_table.get_table()
local world = objective.world
local evolution = game.forces['enemy'].get_evolution_factor(game.get_surface(objective.active_surface_index))
local frame = player.gui.screen.add {type = 'frame', name = 'gui_world', caption = {'chronosphere.gui_world_button'}, direction = 'vertical'}
frame.location = {x = 650, y = 45}
frame.style.minimal_height = 300
frame.style.maximal_height = 500
frame.style.minimal_width = 200
frame.style.maximal_width = 400
frame.add({type = 'label', name = 'world_name', caption = {'chronosphere.gui_world_0', world.variant.name}})
frame.add({type = 'label', caption = {'chronosphere.gui_world_1'}})
local table0 = frame.add({type = 'table', name = 'world_ores', column_count = 3})
table0.add({type = 'sprite-button', name = 'iron-ore', sprite = 'item/iron-ore', enabled = false, number = world.variant.fe})
table0.add({type = 'sprite-button', name = 'copper-ore', sprite = 'item/copper-ore', enabled = false, number = world.variant.cu})
table0.add({type = 'sprite-button', name = 'coal', sprite = 'item/coal', enabled = false, number = world.variant.c})
table0.add({type = 'sprite-button', name = 'stone', sprite = 'item/stone', enabled = false, number = world.variant.s})
table0.add({type = 'sprite-button', name = 'uranium-ore', sprite = 'item/uranium-ore', enabled = false, number = world.variant.u})
table0.add({type = 'sprite-button', name = 'oil', sprite = 'fluid/crude-oil', enabled = false, number = world.variant.o})
frame.add({type = 'label', name = 'richness', caption = {'chronosphere.gui_world_2', world.ores.name}})
frame.add({type = 'label', name = 'world_time', caption = {'chronosphere.gui_world_5', world.dayspeed.name}})
frame.add({type = 'line'})
frame.add({type = 'label', name = 'world_biters', caption = {'chronosphere.gui_world_3', math_floor(evolution * 100)}})
frame.add({type = 'label', name = 'world_biters2', caption = {'chronosphere.gui_world_4'}})
frame.add({type = 'label', name = 'world_biters3', caption = {'chronosphere.gui_world_4_1', objective.overstaycount * 2.5, objective.overstaycount * 10}})
frame.add({type = 'line'})
frame.add({type = 'label', name = 'overstay_time', caption = {'chronosphere.gui_world_7', 3}})
frame.add({type = 'line'})
local close = frame.add({type = 'button', name = 'close_world', caption = 'Close'})
close.style.horizontally_stretchable = true
update_world_gui(player)
end
function Public_gui.update_gui(player)
local objective = Chrono_table.get_table()
local difficulty = Difficulty.get().difficulty_vote_value
local playertable = Chrono_table.get_player_table()
if not player.gui.top.chronosphere then
create_gui(player)
end
local gui = player.gui.top.chronosphere
local guimode = playertable.guimode[player.index]
gui.jump_number.caption = objective.chronojumps
if (objective.chronochargesneeded < 100000) then
gui.charger_value.caption = string.format('%.2f', objective.chronocharges / 1000) .. ' / ' .. math_floor(objective.chronochargesneeded) / 1000 .. ' GJ'
else
gui.charger_value.caption = string.format('%.2f', objective.chronocharges / 1000000) .. ' / ' .. math_floor(objective.chronochargesneeded) / 1000000 .. ' TJ'
end
local interval = objective.chronochargesneeded
gui.progressbar.value = 1 - (objective.chronochargesneeded - objective.chronocharges) / interval
if objective.warmup then
if guimode ~= 'warmup' then
gui.timer.caption = {'chronosphere.gui_3_4'}
gui.timer_value.caption = ''
gui.timer.tooltip = {'chronosphere.gui_3_5'}
gui.timer_value.tooltip = ''
gui.timer2.caption = ''
gui.timer_value2.caption = ''
playertable.guimode[player.index] = 'warmup'
end
elseif objective.jump_countdown_start_time == -1 then
local powerobserved, storedbattery = 0, 0
local seconds_ETA = ETA_seconds_until_full(powerobserved, storedbattery)
gui.timer_value.caption = math_floor(seconds_ETA / 60) .. 'm' .. seconds_ETA % 60 .. 's'
if objective.world.id == 2 and objective.world.variant.id == 2 and objective.passivetimer > 31 then
if guimode ~= 'nuclear' then
gui.timer.caption = {'chronosphere.gui_3'}
gui.timer_value.style.font_color = {r = 0, g = 0.98, b = 0}
gui.timer2.caption = {'chronosphere.gui_3_2'}
gui.timer2.style.font_color = {r = 0.98, g = 0, b = 0}
gui.timer_value2.style.font_color = {r = 0.98, g = 0, b = 0}
playertable.guimode[player.index] = 'nuclear'
end
local nukecase = objective.dangertimer
gui.timer_value2.caption = math_floor(nukecase / 60) .. 'm' .. nukecase % 60 .. 's'
else
if objective.accumulators then
if guimode ~= 'accumulators' then
gui.timer.caption = {'chronosphere.gui_3'}
gui.timer_value.style.font_color = {r = 0, g = 0.98, b = 0}
gui.timer2.caption = {'chronosphere.gui_3_1'}
gui.timer2.style.font_color = {r = 0, g = 200, b = 0}
gui.timer_value2.style.font_color = {r = 0, g = 200, b = 0}
playertable.guimode[player.index] = 'accumulators'
end
local bestcase = math_floor(ETA_seconds_until_full(#objective.accumulators * 300000, storedbattery))
gui.timer_value2.caption = math_floor(bestcase / 60) .. 'm' .. bestcase % 60 .. 's (drawing ' .. #objective.accumulators * 0.3 .. 'MW)'
end
end
if objective.chronojumps >= Balance.jumps_until_overstay_is_on(difficulty) then
local timers = (overstay_timers(gui.timer_value, seconds_ETA, true))
gui.timer_value.tooltip = {'chronosphere.gui_biters_evolve', timers[1], timers[2], timers[3], timers[4]}
else
gui.timer_value.tooltip = ''
end
else
gui.timer_value.caption = 180 - (objective.passivetimer - objective.jump_countdown_start_time) .. 's'
if guimode ~= 'countdown' then
gui.timer.caption = {'chronosphere.gui_3_3'}
gui.timer.tooltip = ''
gui.timer_value.tooltip = ''
gui.timer2.caption = ''
gui.timer_value2.caption = ''
playertable.guimode[player.index] = 'countdown'
end
end
end
local function upgrades_gui(player)
if player.gui.screen['gui_upgrades'] then
player.gui.screen['gui_upgrades'].destroy()
return
end
local objective = Chrono_table.get_table()
local playertable = Chrono_table.get_player_table()
local production_table = Chrono_table.get_production_table()
local upgrades = Upgrades.upgrades()
local frame = player.gui.screen.add {type = 'frame', name = 'gui_upgrades', caption = 'ChronoTrain Upgrades', direction = 'vertical'}
frame.location = {x = 350, y = 45}
frame.style.minimal_height = 300
frame.style.maximal_height = 900
frame.style.minimal_width = 330
frame.style.maximal_width = 630
frame.add({type = 'label', caption = {'chronosphere.gui_upgrades_1'}})
frame.add({type = 'label', caption = {'chronosphere.gui_upgrades_2'}})
frame.add({type = 'label', caption = {'chronosphere.gui_upgrades_3'}})
local switches = frame.add({type = 'table', name = 'upgrades_switch', column_count = 4})
switches.add({type = 'button', caption = {'chronosphere.gui_upgrades_switch1'}, name = 'upgrade_switch1', tooltip = {'chronosphere.gui_upgrades_switch_tt1'}})
switches.add({type = 'button', caption = {'chronosphere.gui_upgrades_switch2'}, name = 'upgrade_switch2', tooltip = {'chronosphere.gui_upgrades_switch_tt2'}})
switches.add({type = 'button', caption = {'chronosphere.gui_upgrades_switch3'}, name = 'upgrade_switch3', tooltip = {'chronosphere.gui_upgrades_switch_tt3'}})
switches.add({type = 'button', caption = {'chronosphere.gui_upgrades_switch4'}, name = 'upgrade_switch4', tooltip = {'chronosphere.gui_upgrades_switch_tt4'}})
local tokens = frame.add({type = 'table', name = 'tokens', column_count = 6})
tokens.add({type = 'label', caption = {'chronosphere.gui_tokens'}})
for token, value in pairs(objective.research_tokens) do
tokens.add(
{
type = 'sprite-button',
name = 'token_' .. token,
enabled = Upgrades.tokens[token].enabled,
sprite = Upgrades.tokens[token].sprite,
number = value,
tooltip = Upgrades.tokens[token].tooltip
}
)
end
for i = 1, #upgrades, 1 do
local upg_table = frame.add({type = 'table', name = 'upgrades_table' .. i, column_count = 10})
upg_table.add({type = 'sprite-button', name = 'upgrade' .. i, enabled = false, sprite = upgrades[i].sprite, number = objective.upgrades[i], tooltip = upgrades[i].tooltip})
local name = upg_table.add({type = 'label', name = 'upgrade_label' .. i, caption = upgrades[i].name, tooltip = upgrades[i].tooltip})
name.style.width = 200
local maxed =
upg_table.add({type = 'sprite-button', name = 'maxed' .. i, enabled = false, sprite = 'virtual-signal/signal-check', tooltip = 'Upgrade maxed!', visible = false})
local jumps =
upg_table.add(
{
type = 'sprite-button',
name = 'jump_req' .. i,
enabled = false,
sprite = 'virtual-signal/signal-J',
number = upgrades[i].jump_limit,
tooltip = {'chronosphere.gui_upgrades_jumps'},
visible = true
}
)
for index, item in pairs(upgrades[i].virtual_cost) do
upg_table.add(
{
type = 'sprite-button',
name = index .. '-v' .. i,
number = item.count,
sprite = item.sprite,
enabled = false,
tooltip = {item.tt .. '.' .. item.name},
visible = true
}
)
end
for index, item in pairs(upgrades[i].cost) do
upg_table.add(
{
type = 'sprite-button',
name = index .. '-' .. i,
number = item.count,
sprite = item.sprite,
enabled = false,
tooltip = {item.tt .. '.' .. item.name},
visible = true
}
)
end
if objective.upgrades[i] == upgrades[i].max_level then
maxed.visible = true
jumps.visible = false
for index, _ in pairs(upgrades[i].virtual_cost) do
upg_table[index .. '-v' .. i].visible = false
end
for index, _ in pairs(upgrades[i].cost) do
upg_table[index .. '-' .. i].visible = false
end
else
maxed.visible = false
jumps.visible = true
for index, _ in pairs(upgrades[i].cost) do
upg_table[index .. '-' .. i].visible = true
end
for index, _ in pairs(upgrades[i].virtual_cost) do
upg_table[index .. '-v' .. i].visible = true
end
end
--if upgrades[i].type == "quest" then upg_table.visible = false end
end
local prod_table = frame.add({type = 'table', name = 'production_table', column_count = 4})
for key, product in pairs(Production) do
local recipe = product.recipe_override or product.name
prod_table.add(
{
type = 'sprite-button',
name = 'product' .. key,
enabled = false,
sprite = 'recipe/' .. recipe,
number = ProdFunctions.calculate_factory_level(production_table.experience[key], true)
}
)
local xp_bar = prod_table.add({type = 'progressbar', name = 'product_bar' .. key, value = calculate_xp(key), tooltip = math.floor(calculate_xp(key) * 1000) / 10 .. '%'})
xp_bar.style = 'achievement_progressbar'
end
switch_upgrades(player, playertable.active_upgrades_gui[player.index])
frame.add({type = 'line', direction = 'horizontal'})
local close = frame.add({type = 'button', name = 'close_upgrades', caption = 'Close'})
close.style.horizontally_stretchable = true
end
function Public_gui.on_gui_click(event)
if not event then
return
end
if not event.element then
return
end
if not event.element.valid then
return
end
local player = game.players[event.element.player_index]
if event.element.name == 'upgrades_button' then
upgrades_gui(player)
return
elseif event.element.name == 'world_button' then
world_gui(player)
return
elseif event.element.name == 'minimap_button' then
Minimap.minimap(player, false)
elseif event.element.name == 'icw_map' or event.element.name == 'icw_map_frame' then
Minimap.toggle_minimap(event)
elseif event.element.name == 'switch_auto_map' then
Minimap.toggle_auto(player)
end
if event.element.type ~= 'button' and event.element.type ~= 'sprite-button' then
return
end
local name = event.element.name
if name == 'close_upgrades' then
upgrades_gui(player)
return
end
if name == 'close_world' then
world_gui(player)
return
end
if name == 'upgrade_switch1' then
switch_upgrades(player, 1)
return
end
if name == 'upgrade_switch2' then
switch_upgrades(player, 2)
return
end
if name == 'upgrade_switch3' then
switch_upgrades(player, 3)
return
end
if name == 'upgrade_switch4' then
switch_upgrades(player, 4)
return
end
if name == 'token_ammo' then
Upgrades.add_ammo_tokens(player)
return
end
end
function Public_gui.update_all_player_gui()
for _, player in pairs(game.connected_players) do
Public_gui.update_gui(player)
end
end
function Public_gui.update_all_player_world_gui()
for _, player in pairs(game.connected_players) do
update_world_gui(player)
end
end
function Public_gui.update_all_player_upgrades_gui()
for _, player in pairs(game.connected_players) do
update_upgrades_gui(player)
end
end
return Public_gui