322 lines
8.5 KiB
Lua

local TPlib = {}
local showlog = false -- Debug log message toggle
local showprint = false -- Debug game print toggle
function TPlib.debuglog(msg)
if showlog then log(msg) end
return showlog
end
function TPlib.debugprint(msg)
if showprint and game then game.print(msg) end
return showprint
end
function TPlib.format_number(x, n)
return string.format("%."..n.."f", x)
end
function TPlib.floor_float(x)
return x>=0 and math.floor(x) or math.ceil(x)
end
function TPlib.round(x)
return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5)
end
function TPlib.round(x, n)
n = math.pow(10, n or 0)
x = x * n
if x >= 0 then x = math.floor(x+0.5) else x = math.ceil(x-0.5) end
return x / n
end
function TPlib.format_position(p)
return string.format("%.0f,%.0f", p.x, p.y )
end
function TPlib.format_position_gps(p)
return string.format("[gps=%.0f,%.0f]", p.x, p.y )
end
function TPlib.string_split(str, sep)
local rt = {}
string.gsub(str, "[^"..sep.."]+", function(w) table.insert(rt, w) end)
return rt
end
function TPlib.vector_multiply(vector, scale)
if not (vector and scale) then
return vector
end
return {vector[1] * scale, vector[2] * scale}
end
function TPlib.table_multiply(t, scale)
if not (t and scale) then
return t
end
for k, v in pairs(t) do
t[k] = v * scale
end
return t
end
function TPlib.table_recursive_multiply(t, scale)
if not (t and scale) then
return t
end
for k, v in pairs(t) do
if type(v) == "table" then
TPlib.table_recursive_multiply(v, scale)
elseif type(v) == "number" then
t[k] = v * scale
end
end
return t
end
function TPlib.table_merge_unique(tables)
-- Different from core util.merge, a siimple function NOT dealing with subtables.
-- Will NOT override/replace earlier tables, but create a unique table.
-- New entries are inserted at the end.
local rt = {}
local tdict = {}
for i, tab in ipairs(tables) do
for _, v in pairs(tab) do
if not tdict[v] then
table.insert(rt, v)
tdict[v] = true
end
end
end
return rt
end
function TPlib.sprite_rescale_recursive(layer, linescale, animscale, spritesspec)
if not layer or type(layer) ~= "table" then return nil end
local spec = spritesspec or {}
if layer.width then
local isanim = layer.animation_speed or layer.frame_count
layer.shift = TPlib.vector_multiply(layer.shift, linescale)
if not spec.skipscale then
layer.scale = (layer.scale or 1) * linescale * (spec.scalemul or 1)
end
if isanim and not spec.skipanimscale and not spec.constant_speed then
layer.animation_speed = (layer.animation_speed or 1) * animscale
end
if layer.hr_version then
layer.hr_version.shift = TPlib.vector_multiply(layer.hr_version.shift, linescale)
if not spec.skipscale then
layer.hr_version.scale = (layer.hr_version.scale or 1) * linescale * (spec.scalemul or 1)
end
if isanim and not spec.skipanimscale and not spec.constant_speed then
layer.hr_version.animation_speed = (layer.hr_version.animation_speed or 1) * animscale
end
end
else
if layer.constant_speed then
spec = table.deepcopy(spec)
spec.skipanimscale = true
end
for k, v in pairs(layer) do
if type(k) == "string" and k:match("_position$") then
layer[k] = TPlib.vector_multiply(v, linescale)
else
TPlib.sprite_rescale_recursive(v, linescale, animscale, spec)
end
end
end
return layer
end
function TPlib.sprite_tint_recursive(layer, tint)
if not layer or type(layer) ~= "table" then return nil end
if layer.width then
layer.tint = tint
if layer.hr_version then
layer.hr_version.tint = tint
end
else
for k, v in pairs(layer) do
TPlib.sprite_tint_recursive(v, tint)
end
end
return layer
end
function TPlib.check_set_value(entry, prop, val)
if entry then
if type(prop) == "table" then
if #prop > 1 then
TPlib.debuglog(" At lv "..#prop.. ": "..prop[1])
return TPlib.check_set_value(entry[prop[1]], {table.unpack(prop,2)}, val)
else
TPlib.debuglog(" Set "..prop[1].. " = `"..tostring(val).."`")
entry[prop[1]] = val
return true
end
else
TPlib.debuglog(" Set "..prop.. " = `"..tostring(val).."`")
entry[prop] = val
return true
end
else
if type(prop) == "table" then
log("Failed to set prop `"..prop[1].."` = `"..tostring(val).."`")
else
log("Failed to set prop `"..prop.."` = `"..tostring(val).."`")
end
return false
end
end
function TPlib.create_flying_text_item(surface, position, itempt, amountadd, source)
local sign = ""
local counts = source.get_item_count(itempt.name)
local text
if amountadd > 0 then
sign = "+"
end
if counts == 0 then
color = {r=1, g=0.14, b=0}
end
surface.create_entity{ name = "flying-text", position = position, color = color, text = {"description.Schall-flying-text-item", itempt.localised_name, sign, amountadd, counts} }
end
function TPlib.create_flying_text_insert_failed(surface, position, itempt)
surface.create_entity{ name = "flying-text", position = position, text = {"description.Schall-flying-text-insert-failed", itempt.localised_name} }
end
local soft_limit = {75, 80, 90, 95, 98, 100}
local hard_limit = 100
-- function TPlib.aymptotic_100(x)
-- for _, v in pairs(soft_limit) do
-- if x<=v then
-- return math.ceil(x)
-- else
-- x = v + (x-v) * 0.5
-- end
-- end
-- return math.min(x, hard_limit)
-- end
function TPlib.aymptotic_100(base, add)
local x = base + add
for _, v in pairs(soft_limit) do
if x <= v then
return math.ceil(x)
elseif base >= v then
-- Skip checking if base is already higher than soft limit
else
x = v + (x-v) * 0.5
end
end
return math.min(x, hard_limit)
end
function TPlib.resistances(base, add)
local rt = {}
local decbase, perbase
local decadd, peradd
for k, v in pairs(base) do
decbase = v.decrease
perbase = v.percent
if add[k] then
decadd = add[k].decrease
peradd = add[k].percent
else
decadd = 0
peradd = 0
end
if dec ~= 0 or per ~= 0 then
table.insert(rt, { type = k, decrease = decbase+decadd, percent = TPlib.aymptotic_100(perbase, peradd) } )
end
end
return rt
end
local mk1_icon_layer = {icon = "__SchallTankPlatoon__/graphics/icons/mk1.png", icon_size = 128, icon_mipmaps = 3}
local mk2_icon_layer = {icon = "__SchallTankPlatoon__/graphics/icons/mk2.png", icon_size = 128, icon_mipmaps = 3}
local mk3_icon_layer = {icon = "__SchallAlienTech__/graphics/icons/mk3.png", icon_size = 128, icon_mipmaps = 3}
local tier_layer = {
[0] = nil,
[1] = mk1_icon_layer,
[2] = mk2_icon_layer,
[3] = mk3_icon_layer,
}
function TPlib.tier_icon_layer(tier)
return tier_layer[tier]
end
TPlib.tankeqp_icon_layer = {icon = "__SchallTankPlatoon__/graphics/icons/tank-equipment.png", icon_size = 128, icon_mipmaps = 3}
TPlib.caliber_H1_icon_layer = {icon = "__SchallTankPlatoon__/graphics/icons/H1.png", icon_size = 128, icon_mipmaps = 3}
TPlib.caliber_H2_icon_layer = {icon = "__SchallTankPlatoon__/graphics/icons/H2.png", icon_size = 128, icon_mipmaps = 3}
TPlib.tankeqp_techicon_layer = {icon = "__SchallTankPlatoon__/graphics/technology/tank-equipment.png"}
TPlib.traineqp_techicon_layer = {icon = "__SchallTankPlatoon__/graphics/technology/train-equipment.png"}
TPlib.burner_tank_smoke =
{
{
name = "tank-smoke",
deviation = {0.25, 0.25},
frequency = 50,
position = {0, 1.5},
starting_frame = 0,
starting_frame_deviation = 60
}
}
function TPlib.energy_source(oript, category, spec, smoke)
if not spec then return oript end
local rt = table.deepcopy(oript)
for k, v in pairs(spec) do
rt[k] = v
end
if category == "nuclear" then
rt.type = "burner"
rt.fuel_category = category
rt.fuel_inventory_size = 1
rt.burnt_inventory_size = 1
if smoke then rt.smoke = smoke end
elseif category == "chemical" then
rt.type = "burner"
rt.fuel_category = category
rt.fuel_inventory_size = rt.fuel_inventory_size or 1
if smoke then rt.smoke = smoke end
elseif category == "void" then
rt = { type = "void" }
end
return rt
end
local function scale_volume(pt, scale)
for _, v in pairs(pt) do
if v.volume then v.volume = v.volume * scale end
end
end
function TPlib.scale_sound_volume(pt, scale)
if pt.variations then
scale_volume(pt.variations, scale)
else
scale_volume(pt, scale)
end
end
return TPlib