322 lines
8.5 KiB
Lua
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 |