Aleksei-bird 7c9c708c92 Первый фикс
Пачки некоторых позиций увеличены
2024-03-01 20:54:33 +03:00

420 lines
16 KiB
Lua

return function (mod_name)
--~ log("Entered common.lua!")
local common = {}
------------------------------------------------------------------------------------
-- Get mod name and path to mod
common.modName = mod_name
common.modRoot = "__" .. mod_name .. "__"
------------------------------------------------------------------------------------
-- When looking for alternative characters, use this search pattern
common.pattern = "SKIN"
------------------------------------------------------------------------------------
-- Name of the surface we create as storage for dummy characters
common.dummy_surface = "dummy_dungeon"
------------------------------------------------------------------------------------
-- Name of the dummy character prototype
common.dummy_character_name = "minime_character_dummy"
------------------------------------------------------------------------------------
-- Name of God-mode button
common.remove_character_name = "God-mode"
------------------------------------------------------------------------------------
-- Names of inventories
common.inventory_list = { "ammo", "armor", "guns", "main", "trash" }
------------------------------------------------------------------------------------
-- Number of dummy's bonus trash slots
common.character_trash_slot_count_bonus = 500
------------------------------------------------------------------------------------
-- Enable character selector?
common.minime_character_selector = settings.startup["minime_character-selector"].value
------------------------------------------------------------------------------------
-- Close GUI after a character has been selected?
common.minime_close_gui_on_selection = settings.startup["minime_close-gui-on-selection"].value
------------------------------------------------------------------------------------
-- Look for matching pattern at start of a string
common.prefixed = function(str, start)
return str:sub(1, #start) == start
end
------------------------------------------------------------------------------------
-- Enable writing to log file until startup options are set, so debugging output
-- from the start of a game session can be logged. This depends on a locally
-- installed dummy mod to allow debugging output during development without
-- spamming real users.
-- If you don't have this mod or don't want to activate it, you can also change
-- the value of debug_default!
local debug_default = false
-- Control stage
if game then
common.debug_in_log = (game.active_mods["_debug"] and true) or debug_default
-- on_load
elseif script then
common.debug_in_log = (script.active_mods["_debug"] and true) or debug_default
-- Data stage
else
common.debug_in_log = (mods["_debug"] and true) or debug_default
end
------------------------------------------------------------------------------------
-- Output: Print to user and debug-print
common.output = function(player, msg)
--~ common.dprint("Entered function " .. common.modName .. ".output(" ..
--~ tostring(player.name) .. ", " .. tostring({msg}) .. ")")
if player.valid and player.is_player() then
player.print({"", msg})
--~ common.dprint({"", msg})
elseif not player.valid then
common.dprint({"", common.modName, ": Couldn't print to player -- player isn't valid!"})
else
common.dprint({"", common.modName, ": Couldn't print to " .. player.name .. " -- not a player!"})
end
--~ common.dprint("End of function " .. common.modName .. ".output(" ..
--~ tostring(player.name) .. ", " .. tostring({msg}) .. ")")
end
------------------------------------------------------------------------------------
-- Debug function
common.dprint = function(msg)
if common.debug_in_log then log({"", msg}) end
if game and msg then
for index, player in pairs(game.players) do
if global.player_settings and global.player_settings[index]
and global.player_settings[index].debug_in_game then
--~ game.players[index].print({"", common.modName, ': ', msg}, {r=.75, g=.5, b=.25})
game.players[index].print({"", common.modName, ': ', msg})
end
end
end
end
------------------------------------------------------------------------------------
-- Helper function to show value and type of variables
common.show = function(var, msg)
common.dprint({"", "Show", tostring(msg and " " .. msg), ":\t" .. serpent.block(var)})
end
------------------------------------------------------------------------------------
-- Localize entity names for output routines
-- (Returns localized entity name; falls back to entity name, or to default string)
common.loc_name = function (entity)
return entity and entity.valid and (entity.localised_name or entity.name) or ""
end
------------------------------------------------------------------------------------
-- Get the version of a mod and split the number! --
------------------------------------------------------------------------------------
local function split_number(version)
local ret = {}
if version then
for x in string.gmatch(version, "(%d+)") do
ret[#ret + 1] = tonumber(x)
end
end
return table_size(ret) == 3 and ret or nil
end
------------------------------------------------------------------------------------
-- Check if a mod has a version greater than or equal to this number! --
------------------------------------------------------------------------------------
common.check_mod_version_ge = function(mod_name, target_version)
--~ local f_name = "common.check_mod_version_ge"
--~ common.dprint("Entered function " .. f_name .. "(" .. tostring(mod_name) ..
--~ ", " .. tostring(target_version) .. ")")
if not (mod_name and target_version) then
error("Missing arguments!")
end
local mod_version = script and script.active_mods[mod_name] or
game and game.active_mods[mod_name]
local ret = false
--~ common.show(mod_version, "mod_version")
-- Only continue check if mod is active
mod_version = split_number(mod_version)
--~ common.show(mod_version, "mod_version after split")
if mod_version then
target_version = split_number(target_version)
--~ common.show(target_version, "target_version")
if mod_version[1] > target_version[1] then
ret = true
elseif mod_version[1] == target_version[1] then
if mod_version[2] > target_version[2] then
ret = true
elseif (
mod_version[2] == target_version[2] and
mod_version[3] >= target_version[3]
) then
ret = true
end
end
end
--~ common.show(ret, "Return")
--~ common.dprint("End of function " .. f_name .. "(" .. tostring(mod_name) ..
--~ ", " .. tostring(target_version) .. ")")
return ret
end
------------------------------------------------------------------------------------
-- Check if a mod has a version less than or equal to this number! --
------------------------------------------------------------------------------------
common.check_mod_version_le = function(mod_name, target_version)
--~ local f_name = "common.check_mod_version_le"
--~ common.dprint("Entered function " .. f_name .. "(" .. tostring(mod_name) ..
--~ ", " .. tostring(target_version) .. ")")
if not (mod_name and target_version) then
error("Missing arguments!")
end
local mod_version = script and script.active_mods[mod_name] or
game and game.active_mods[mod_name]
local ret = false
-- Only continue check if mod is active
mod_version = split_number(mod_version)
if mod_version then
target_version = split_number(target_version)
if mod_version[1] < target_version[1] then
ret = true
elseif mod_version[1] == target_version[1] then
if mod_version[2] < target_version[2] then
ret = true
elseif (
mod_version[2] == target_version[2] and
mod_version[3] <= target_version[3]
) then
ret = true
end
end
end
--~ common.dprint("End of function " .. f_name .. "(" .. tostring(mod_name) ..
--~ ", " .. tostring(target_version) .. ")")
return ret
end
------------------------------------------------------------------------------------
-- Check if a mod has a version less than this number! --
------------------------------------------------------------------------------------
common.check_mod_version_less = function(mod_name, target_version)
--~ local f_name = "common.check_mod_version_less"
--~ common.dprint("Entered function " .. f_name .. "(" .. tostring(mod_name) ..
--~ ", " .. tostring(target_version) .. ")")
if not (mod_name and target_version) then
error("Missing arguments!")
end
local mod_version = script and script.active_mods[mod_name] or
game and game.active_mods[mod_name]
local ret = false
-- Same version isn't less!
if mod_version ~= target_version and common.check_mod_version_le(mod_name, target_version) then
ret = true
end
--~ common.dprint("End of function " .. f_name .. "(" .. tostring(mod_name) ..
--~ ", " .. tostring(target_version) .. ")")
return ret
end
------------------------------------------------------------------------------------
-- Check if a mod has a version greater than this number! --
------------------------------------------------------------------------------------
common.check_mod_version_greater = function(mod_name, target_version)
--~ local f_name = "common.check_mod_version_greater"
--~ common.dprint("Entered function " .. f_name .. "(" .. tostring(mod_name) ..
--~ ", " .. tostring(target_version) .. ")")
if not (mod_name and target_version) then
error("Missing arguments!")
end
local mod_version = script and script.active_mods[mod_name] or
game and game.active_mods[mod_name]
local ret = false
-- Same version isn't greater!
if mod_version ~= target_version and common.check_mod_version_ge(mod_name, target_version) then
ret = true
end
--~ common.dprint("End of function " .. f_name .. "(" .. tostring(mod_name) ..
--~ ", " .. tostring(target_version) .. ")")
return ret
end
------------------------------------------------------------------------------------
-- Copy character settings! --
------------------------------------------------------------------------------------
common.copy_character = function(src, dst)
local f_name = "common.copy_character_settings"
common.dprint("Entered function " .. f_name .. "(" .. tostring(src and src.name) .. ", " ..
tostring(dst and dst.name) .. ")")
if not (src and src.valid and src.type == "character") then
error(serpent.block(src) .. " is not a valid character!")
elseif not (dst and dst.valid and dst.type == "character") then
error(serpent.block(dst) .. " is not a valid character!")
end
-- Transfer inventories
--~ local inventory_list = { "armor", "ammo", "guns", "main", "trash" }
local inventory_list = common.inventory_list
local inventory
for i, inv in ipairs(inventory_list) do
common.dprint(i .. ": Transferring items from inventory " .. serpent.line(inv))
inventory = defines.inventory["character_" .. inv]
common.transfer_inventory(src.get_inventory(inventory), dst.get_inventory(inventory))
end
-- Copy settings/filters from Personal logistic slots
-- local slots = src.character_logistic_slot_count
-- dst.character_logistic_slot_count = slots
-- for i = 1, slots do
-- dst.set_personal_logistic_slot(i, src.get_personal_logistic_slot(i))
-- end
-- common.dprint("Copied ".. slots .. " personal logistic slots from " ..
-- serpent.line(common.loc_name(src)) .. " to " .. serpent.line(common.loc_name(dst)) .. ".")
-- Copy status of switch for personal logistic requests
dst.character_personal_logistic_requests_enabled = src.character_personal_logistic_requests_enabled
common.dprint("Personal logistic requests are " ..
tostring(src.character_personal_logistic_requests_enabled and "enabled." or "disabled."))
-- Copy status of switch for personal roboport
dst.allow_dispatching_robots = src.allow_dispatching_robots
common.dprint("Personal bots are " ..
tostring(src.allow_dispatching_robots and "enabled." or "disabled."))
-- Copy status of flashlight
if src.is_flashlight_enabled() then
dst.enable_flashlight()
common.dprint("Flashlight is enabled.")
else
dst.disable_flashlight()
common.dprint("Flashlight is disabled.")
end
common.dprint("End of function " .. f_name .. "(" .. tostring(src and src.name) .. ", " ..
tostring(dst and dst.name) .. ")")
end
------------------------------------------------------------------------------------
-- Create a dummy character
common.make_dummy = function(p)
local f_name = "make_dummy"
common.dprint("Entered function " .. f_name .. "(" .. serpent.line(p) .. ").")
p = p and (type(p) == "number") and game.players[p] or p
if not (p and p.valid and p.is_player()) then
error(serpent.line(p) .. " is not a valid player!")
end
local dummy = game.surfaces[common.dummy_surface].create_entity{
--~ name = "character",
name = common.dummy_character_name,
position = {0, 0}
}
common.dprint("Created dummy character for player " .. p.name .. ".")
-- Add a generous amount of trash slots
dummy.character_trash_slot_count_bonus = common.character_trash_slot_count_bonus
-- Check if we have an old dummy that we need to migrate
local p_data = global.player_data[p.index]
if p_data and p_data.dummy and (p_data.dummy.name ~= common.dummy_character_name) then
--~ common.copy_character(global.player_data[p].dummy, dummy)
common.copy_character(p_data.dummy, dummy)
end
common.dprint("End of function " .. f_name .. "(" .. serpent.line(p) .. ").")
return dummy
end
------------------------------------------------------------------------------------
-- Transfer inventory! --
------------------------------------------------------------------------------------
common.transfer_inventory = function(src, dst)
local f_name = "transfer_inventory"
common.dprint("Entered function " .. f_name .. "(" .. tostring(src) .. ", " .. tostring(dst) .. ")")
for _, i in pairs({ src, dst }) do
if not (i and i.valid) then
error(serpent.line(i) .. " is not a valid inventory!")
end
end
common.dprint("SRC: " .. serpent.block(src))
common.dprint("SRC slots: " .. #src)
common.dprint("DST slots: " .. #dst)
local limit = (#src > #dst) and #dst or #src
-- Transfer inventory contents if inventory isn't empty
if src.is_empty() then
-- Shouldn't be really necessary, but just let's play it safe!
dst.clear()
else
for i = 1, limit do
local test_d = dst[i].valid_for_read
local test_s = src[i].valid_for_read
common.dprint("src[" .. i .. "]: " .. serpent.line(test_s and src[i].name) .. " (" .. serpent.line(test_s and src[i].count) .. ")\tdst[" .. i .. "]:" .. serpent.line(test_d and dst[i].name) .. " (" .. serpent.line(test_d and dst[i].count) .. ")")
--~ dst[i].transfer_stack(src[i]) -- Doesn't work, it moves items.
dst[i].set_stack(src[i]) -- Much better, this copies them!
test_d = dst[i].valid_for_read
common.dprint("dst[" .. i .. "]: " .. serpent.line(test_d and dst[i].name) .. " (" .. serpent.line(test_d and dst[i].count) .. ")")
end
common.dprint("Transferred " .. limit .. tostring(limit == 1 and " stack." or " stacks."))
end
-- Copy filters if at least one slot is filtered
if src.is_filtered() then
for i = 1, limit do
dst.set_filter(i, src.get_filter(i))
end
common.dprint("Set filters")
end
common.dprint("End of function " .. f_name .. "(" .. tostring(src) .. ", " .. tostring(dst) .. ")")
end
--~ log("End of common.lua!")
return common
end