mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-04 00:15:45 +02:00
Merge branch 'develop' into Inventory-fullness-flying-text
This commit is contained in:
commit
6b7316874d
@ -30,6 +30,16 @@ local starting_items = {
|
||||
['explosives'] = 32
|
||||
}
|
||||
|
||||
local random_respawn_messages = {
|
||||
'The doctors stitched you up as best they could.',
|
||||
'Ow! Your right leg hurts.',
|
||||
'Ow! Your left leg hurts.',
|
||||
'You can feel your whole body aching.',
|
||||
"You still have some bullet wounds that aren't patched up.",
|
||||
'You feel dizzy but adrenalin is granting you speed.',
|
||||
'Adrenalin is kicking in, but your body is damaged.'
|
||||
}
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(t)
|
||||
@ -41,6 +51,7 @@ local Public = {}
|
||||
|
||||
local random = math.random
|
||||
local floor = math.floor
|
||||
local round = math.round
|
||||
local remove = table.remove
|
||||
local sqrt = math.sqrt
|
||||
local magic_crafters_per_tick = 3
|
||||
@ -1339,6 +1350,8 @@ function Public.on_player_respawned(event)
|
||||
end
|
||||
if player.character and player.character.valid then
|
||||
Task.set_timeout_in_ticks(15, boost_movement_speed_on_respawn, {player = player})
|
||||
player.character.health = round(player.character.health * 0.25)
|
||||
player.print(random_respawn_messages[random(1, #random_respawn_messages)])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
--luacheck: ignore
|
||||
local Scheduler = require 'utils.scheduler'
|
||||
|
||||
local table_insert = table.insert
|
||||
local string_find = string.find
|
||||
local len = string.len
|
||||
|
||||
local Public = {}
|
||||
|
||||
@ -37,7 +40,7 @@ local function set_crafting_machines()
|
||||
end
|
||||
end
|
||||
|
||||
local uncommon_recipes = {'barrel', 'void', 'blackhole'}
|
||||
local uncommon_recipes = {'compressing', 'barrel', 'canister', 'void', 'blackhole'}
|
||||
local function is_uncommon_recipe(recipe_name)
|
||||
for _, name in pairs(uncommon_recipes) do
|
||||
local a, b = string_find(recipe_name, name, 1, true)
|
||||
@ -223,20 +226,58 @@ local function set_item_whitelists_for_all_forces()
|
||||
end
|
||||
end
|
||||
|
||||
local function get_localised_name(name)
|
||||
local item = game.item_prototypes[name]
|
||||
if item then
|
||||
return item.localised_name
|
||||
end
|
||||
local fluid = game.fluid_prototypes[name]
|
||||
if fluid then
|
||||
return fluid.localised_name
|
||||
end
|
||||
local recipe = game.recipe_prototypes[name]
|
||||
if recipe then
|
||||
return recipe.localised_name
|
||||
end
|
||||
return name
|
||||
end
|
||||
|
||||
local on_nth_translation_handler =
|
||||
Scheduler.set(
|
||||
function(data)
|
||||
for i = 1, #data do
|
||||
local player_index = data[i].player_index
|
||||
local name = data[i].name
|
||||
local player = game.get_player(player_index)
|
||||
|
||||
local localized = get_localised_name(name)
|
||||
player.request_translation(localized)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
function Public.set_filtered_list(player)
|
||||
local player_data = global.fjei.player_data[player.index]
|
||||
player_data.filtered_list = {}
|
||||
player_data.active_page = 1
|
||||
local filtered_list = player_data.filtered_list
|
||||
local active_filter = player_data.active_filter
|
||||
local active_filter = player_data.active_filter and player_data.active_filter:lower() or false
|
||||
local sorted_item_list = global.fjei.sorted_item_list
|
||||
local item_whitelist = global.fjei.item_whitelist[player.force.name]
|
||||
local locale_data = player_data.translated_data
|
||||
|
||||
local i = 1
|
||||
for key, name in pairs(sorted_item_list) do
|
||||
if item_whitelist[name] then
|
||||
if active_filter then
|
||||
local a, b = string_find(name, active_filter, 1, true)
|
||||
local translated = locale_data and locale_data[name] and locale_data[name]:lower() or false
|
||||
if translated and active_filter then
|
||||
local r = translated:find(active_filter)
|
||||
if r then
|
||||
filtered_list[i] = key
|
||||
i = i + 1
|
||||
end
|
||||
elseif active_filter then
|
||||
local a = name:find(active_filter, 1, true)
|
||||
if a then
|
||||
filtered_list[i] = key
|
||||
i = i + 1
|
||||
@ -250,9 +291,43 @@ function Public.set_filtered_list(player)
|
||||
player_data.size_of_filtered_list = #player_data.filtered_list
|
||||
end
|
||||
|
||||
-- this is the only way of providing the translated strings to the gui
|
||||
-- or you could use the translated event to provide directly to the function
|
||||
function Public.set_translated_data(player, result, localised_string)
|
||||
local player_data = global.fjei.player_data[player.index]
|
||||
if not player_data.translated_data then
|
||||
player_data.translated_data = {}
|
||||
end
|
||||
|
||||
local data = player_data.translated_data
|
||||
|
||||
if not data[localised_string] and len(result) > 0 then
|
||||
data[localised_string] = result
|
||||
end
|
||||
end
|
||||
|
||||
function Public.handle_translations_fetch(player)
|
||||
local sorted_item_list = global.fjei.sorted_item_list
|
||||
local tick = game.tick
|
||||
local item_whitelist = global.fjei.item_whitelist[player.force.name]
|
||||
local player_data = global.fjei.player_data[player.index]
|
||||
if not player_data.translated_data then
|
||||
player_data.translated_data = {}
|
||||
end
|
||||
|
||||
local data = player_data.translated_data
|
||||
|
||||
for key, name in pairs(sorted_item_list) do
|
||||
if item_whitelist[name] and not data[name] then
|
||||
Scheduler.timer(tick, on_nth_translation_handler, {name = name, player_index = player.index})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.build_tables()
|
||||
global.fjei = {}
|
||||
global.fjei.player_data = {}
|
||||
global.fjei.item_whitelist_translated = {}
|
||||
set_item_list() --creates list of all items as key and two tables for each key containing [1] product recipes and [2] ingredient recipes
|
||||
set_sorted_item_list() --creates sorted list of all items in the game for faster searching
|
||||
set_crafting_machines() --creates list of available crafting entities
|
||||
|
@ -1,12 +1,13 @@
|
||||
--luacheck: ignore
|
||||
local Functions = require 'modules.fjei.functions'
|
||||
local Gui = require 'utils.gui'
|
||||
local math_ceil = math.ceil
|
||||
local math_abs = math.abs
|
||||
local table_remove = table.remove
|
||||
local table_insert = table.insert
|
||||
local main_window_width = 228
|
||||
local recipe_window_width = 480
|
||||
local recipe_window_amount_width = 38
|
||||
local recipe_window_amount_width = 40
|
||||
local recipe_window_item_name_width = 128
|
||||
local recipe_window_position = 'screen'
|
||||
local column_count = 5
|
||||
@ -25,7 +26,7 @@ local function save_window_location(player, frame)
|
||||
end
|
||||
|
||||
local function get_total_page_count(player)
|
||||
if not global.fjei.player_data[player.index].filtered_list then
|
||||
if not global.fjei.player_data[player.index].size_of_filtered_list then
|
||||
Functions.set_filtered_list(player)
|
||||
end
|
||||
local count = math_ceil(global.fjei.player_data[player.index].size_of_filtered_list / items_per_page)
|
||||
@ -53,7 +54,7 @@ end
|
||||
|
||||
local function get_formatted_amount(amount)
|
||||
if amount < 1000 then
|
||||
amount = amount .. ' x '
|
||||
amount = amount .. ' x '
|
||||
return amount
|
||||
end
|
||||
if amount >= 1000000 then
|
||||
@ -138,7 +139,7 @@ local function add_choose_elem_button(element, name, is_recipe)
|
||||
choose_elem_button.style.padding = 2
|
||||
end
|
||||
|
||||
local function add_sprite_icon(element, name, is_recipe, use_localised_name)
|
||||
local function add_sprite_icon(element, name, is_recipe)
|
||||
local sprite_type
|
||||
if is_recipe then
|
||||
sprite_type = 'recipe'
|
||||
@ -150,13 +151,7 @@ local function add_sprite_icon(element, name, is_recipe, use_localised_name)
|
||||
return
|
||||
end
|
||||
|
||||
local sprite
|
||||
if use_localised_name then
|
||||
sprite = element.add({type = 'sprite', name = name, sprite = sprite_type .. '/' .. name, tooltip = get_localised_name(name)})
|
||||
else
|
||||
sprite = element.add({type = 'sprite', name = name, sprite = sprite_type .. '/' .. name, tooltip = name})
|
||||
end
|
||||
|
||||
local sprite = element.add({type = 'sprite', name = name, sprite = sprite_type .. '/' .. name, tooltip = get_localised_name(name)})
|
||||
sprite.style.minimal_width = 32
|
||||
sprite.style.minimal_height = 32
|
||||
sprite.style.maximal_width = 32
|
||||
@ -184,7 +179,7 @@ local function display_item_list(player)
|
||||
if not filtered_list[i] then
|
||||
return
|
||||
end
|
||||
add_sprite_icon(item_list_table, sorted_item_list[filtered_list[i]], false)
|
||||
add_sprite_icon(item_list_table, sorted_item_list[filtered_list[i]])
|
||||
end
|
||||
end
|
||||
|
||||
@ -203,7 +198,7 @@ local function display_history(player)
|
||||
for i = player_data.size_of_history - column_count, player_data.size_of_history, 1 do
|
||||
local name = history[i]
|
||||
if name then
|
||||
add_sprite_icon(history_table, name, false)
|
||||
add_sprite_icon(history_table, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -275,14 +270,14 @@ local function refresh_recipe_bar(player, selected_recipe)
|
||||
|
||||
local container = fjei_recipe_window_select_table[old_recipe_name]
|
||||
container.clear()
|
||||
add_sprite_icon(container, old_recipe_name, true)
|
||||
add_sprite_icon(container, old_recipe_name)
|
||||
|
||||
local container = fjei_recipe_window_select_table[selected_recipe]
|
||||
container.clear()
|
||||
local element = container.add({type = 'frame', name = 'fjei_recipe_window_selected_recipe'})
|
||||
element.style.margin = 0
|
||||
element.style.padding = -4
|
||||
add_sprite_icon(element, selected_recipe, true)
|
||||
add_sprite_icon(element, selected_recipe)
|
||||
end
|
||||
|
||||
local function draw_recipe_window_header(player, container, item_name, recipes, mode, recipe_name)
|
||||
@ -311,9 +306,9 @@ local function draw_recipe_window_header(player, container, item_name, recipes,
|
||||
local element = ttt.add({type = 'frame', name = 'fjei_recipe_window_selected_recipe'})
|
||||
element.style.margin = 0
|
||||
element.style.padding = -4
|
||||
add_sprite_icon(element, name, true)
|
||||
add_sprite_icon(element, name)
|
||||
else
|
||||
add_sprite_icon(ttt, name, true)
|
||||
add_sprite_icon(ttt, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -362,7 +357,7 @@ local function draw_recipe(player, container, recipe_name)
|
||||
|
||||
local amount = product.amount
|
||||
if not amount then
|
||||
amount = 1
|
||||
amount = math.round((product.amount_min + product.amount_max) * 0.5, 2)
|
||||
end
|
||||
amount = amount * product.probability
|
||||
|
||||
@ -389,6 +384,10 @@ local function draw_recipe(player, container, recipe_name)
|
||||
element.style.single_line = false
|
||||
element.style.font = 'default'
|
||||
end
|
||||
if not product.amount or not product.probability or product.probability ~= 1 then
|
||||
element.tooltip = 'This number is an approximate value.'
|
||||
element.style.font_color = {255, 255, 0}
|
||||
end
|
||||
end
|
||||
|
||||
local element = container.add({type = 'label', caption = 'Ingredients:'})
|
||||
@ -624,6 +623,7 @@ local function toggle_main_window(element, player, button)
|
||||
player.gui[recipe_window_position].fjei_recipe_window.destroy()
|
||||
end
|
||||
else
|
||||
Functions.handle_translations_fetch(player)
|
||||
draw_main_window(player)
|
||||
end
|
||||
return true
|
||||
@ -717,15 +717,15 @@ function Public.gui_click_actions(element, player, button)
|
||||
end
|
||||
|
||||
function Public.draw_top_toggle_button(player)
|
||||
if player.gui.top['fjei_toggle_button'] then
|
||||
local button_flow = Gui.mod_button(player)
|
||||
if button_flow.fjei_toggle_button then
|
||||
return
|
||||
end
|
||||
local button = player.gui.top.add({type = 'sprite-button', name = 'fjei_toggle_button', caption = 'FJEI'})
|
||||
button.style.font = 'heading-1'
|
||||
button.style.font_color = {222, 222, 222}
|
||||
button.style.minimal_height = 38
|
||||
button.style.minimal_width = 50
|
||||
button.style.padding = -2
|
||||
button_flow.add {type = 'sprite-button', name = 'fjei_toggle_button', caption = 'FJEI'}
|
||||
button_flow.style.minimal_height = 38
|
||||
button_flow.style.maximal_height = 38
|
||||
button_flow.style.minimal_width = 40
|
||||
button_flow.style.padding = -2
|
||||
end
|
||||
|
||||
function Public.open_recipe(element, player, button)
|
||||
|
@ -11,8 +11,9 @@ local function on_player_joined_game(event)
|
||||
local player = game.players[event.player_index]
|
||||
|
||||
if not global.fjei then
|
||||
Public.build_tables()
|
||||
Functions.build_tables()
|
||||
end
|
||||
|
||||
if not global.fjei.player_data[player.index] then
|
||||
global.fjei.player_data[player.index] = {}
|
||||
end
|
||||
@ -23,6 +24,18 @@ end
|
||||
|
||||
local function on_player_left_game(event)
|
||||
local player = game.players[event.player_index]
|
||||
if player.gui.left['fjei_main_window'] then
|
||||
player.gui.left['fjei_main_window'].destroy()
|
||||
end
|
||||
if player.gui.screen['fjei_recipe_window'] then
|
||||
player.gui.screen['fjei_recipe_window'].destroy()
|
||||
end
|
||||
if player.gui[recipe_window_position]['fjei_recipe_window'] then
|
||||
player.gui[recipe_window_position]['fjei_recipe_window'].destroy()
|
||||
end
|
||||
if not global.fjei.player_data[player.index] then
|
||||
return
|
||||
end
|
||||
global.fjei.player_data[player.index].history = nil
|
||||
global.fjei.player_data[player.index].filtered_list = nil
|
||||
global.fjei.player_data[player.index] = nil
|
||||
@ -95,6 +108,7 @@ local function on_gui_text_changed(event)
|
||||
else
|
||||
global.fjei.player_data[player.index].active_filter = element.text
|
||||
end
|
||||
|
||||
Functions.set_filtered_list(player)
|
||||
Gui.refresh_main_window(player)
|
||||
end
|
||||
@ -111,6 +125,24 @@ local function on_configuration_changed()
|
||||
end
|
||||
end
|
||||
|
||||
local function on_string_translated(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
local result = event.result
|
||||
if not result then
|
||||
return
|
||||
end
|
||||
|
||||
local localised_string = event.localised_string
|
||||
if not localised_string then
|
||||
return
|
||||
end
|
||||
|
||||
localised_string = localised_string[1]
|
||||
localised_string = string.match(localised_string, '[^.]*$')
|
||||
|
||||
Functions.set_translated_data(player, result, localised_string)
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
Functions.build_tables()
|
||||
end
|
||||
@ -127,6 +159,7 @@ event.add(defines.events.on_player_left_game, on_player_left_game)
|
||||
event.add(defines.events.on_research_finished, on_research_finished)
|
||||
event.add(defines.events.on_gui_click, on_gui_click)
|
||||
event.add(defines.events.on_gui_text_changed, on_gui_text_changed)
|
||||
event.add(defines.events.on_string_translated, on_string_translated)
|
||||
script.on_configuration_changed(on_configuration_changed)
|
||||
event.on_init(on_init)
|
||||
event.on_init(on_load)
|
||||
|
@ -2,6 +2,7 @@ local Token = require 'utils.token'
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local SpamProtection = require 'utils.spam_protection'
|
||||
local mod_gui = require('__core__/lualib/mod-gui')
|
||||
|
||||
local tostring = tostring
|
||||
local next = next
|
||||
@ -329,4 +330,7 @@ if _DEBUG then
|
||||
end
|
||||
end
|
||||
|
||||
Gui.get_button_flow = mod_gui.get_button_flow
|
||||
Gui.mod_button = mod_gui.get_button_flow
|
||||
|
||||
return Gui
|
||||
|
105
utils/scheduler.lua
Normal file
105
utils/scheduler.lua
Normal file
@ -0,0 +1,105 @@
|
||||
local Event = require 'utils.event'
|
||||
local Public = {}
|
||||
local loaded = {}
|
||||
local count = 1
|
||||
|
||||
function Public.set(var)
|
||||
if game then
|
||||
return
|
||||
end
|
||||
|
||||
count = count + 1
|
||||
loaded[count] = var
|
||||
|
||||
return count
|
||||
end
|
||||
|
||||
function Public.get_handler()
|
||||
local handler = global.tick_handler
|
||||
|
||||
if not handler then
|
||||
global.tick_handler = {
|
||||
index = game.tick
|
||||
}
|
||||
handler = global.tick_handler
|
||||
end
|
||||
return handler
|
||||
end
|
||||
|
||||
function Public.get(id)
|
||||
return loaded[id]
|
||||
end
|
||||
|
||||
function Public.timer(tick, id, data)
|
||||
if not id then
|
||||
return
|
||||
end
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
if not tick then
|
||||
return
|
||||
end
|
||||
|
||||
local handler = global.tick_handler
|
||||
if not handler then
|
||||
handler = Public.get_handler()
|
||||
end
|
||||
|
||||
local limit = 30
|
||||
|
||||
handler.index = handler.index + 1
|
||||
::retry::
|
||||
|
||||
if handler[tick] and handler[tick].index >= limit then
|
||||
tick = tick + 2
|
||||
goto retry
|
||||
elseif handler[tick] and handler[tick].index <= limit then
|
||||
handler[tick].index = handler[tick].index + 1
|
||||
local index = handler[tick].index
|
||||
|
||||
handler[tick][index] = data
|
||||
else
|
||||
handler[tick] = {
|
||||
index = 1,
|
||||
id = id,
|
||||
[1] = data
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function on_tick()
|
||||
local tick = game.tick
|
||||
local handler = global.tick_handler
|
||||
|
||||
if not handler then
|
||||
handler = Public.get_handler()
|
||||
end
|
||||
|
||||
if not handler[tick] then
|
||||
return
|
||||
end
|
||||
|
||||
local id = handler[tick].id
|
||||
local data = handler[tick]
|
||||
|
||||
local func = Public.get(id)
|
||||
if not func then
|
||||
return
|
||||
end
|
||||
if not data then
|
||||
return
|
||||
end
|
||||
|
||||
if data and data.id then
|
||||
data.id = nil
|
||||
data.index = nil
|
||||
end
|
||||
|
||||
func(data)
|
||||
handler[tick] = nil
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_tick, on_tick)
|
||||
|
||||
return Public
|
Loading…
Reference in New Issue
Block a user