Compare commits

...

13 Commits

Author SHA1 Message Date
kno10 6e1e84c33b try to fix chest minecarts, at least for 5.9 2024-10-27 15:45:55 +01:00
Mikita Wiśniewski 41b188caea Remove "double drop" mechanics for bamboo (fixes #4514) (#4642)
Reviewed-on: VoxeLibre/VoxeLibre#4642
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-committed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
2024-10-27 14:16:06 +01:00
kno10 ae7995d195 Fix axolotl attacking water mobs (#4675)
Also avoid jumping out of the water closes #4644

Reviewed-on: VoxeLibre/VoxeLibre#4675
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <kno10@noreply.git.minetest.land>
Co-committed-by: kno10 <kno10@noreply.git.minetest.land>
2024-10-27 14:10:11 +01:00
kno10 e293cbe631 Better handling of touching_ground for bouncing on beds (#4689)
Reviewed-on: VoxeLibre/VoxeLibre#4689
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
2024-10-27 14:03:50 +01:00
the-real-herowl fd6cac5f0c Merge pull request 'Fix fog tint in overworld, apply memory leak fix, fix rain->clear clouds' (#4669) from weather-fixes into master
Reviewed-on: VoxeLibre/VoxeLibre#4669
Reviewed-by: kno10 <kno10@noreply.git.minetest.land>
2024-10-11 07:14:01 +02:00
teknomunk e864cc19ed Make fog_tint_type = "default" when weather is present to match behavior at 0.87.2 2024-10-09 01:05:20 +02:00
teknomunk 66c3c014a1 Make sure fog tints are preserved during weather is present 2024-10-09 01:05:20 +02:00
teknomunk 7807093b50 Another correction to color interpolation, change day color from layer position 0.15 to 0.50 2024-10-09 01:05:20 +02:00
teknomunk f6c3f4bd16 Correct value clamping 2024-10-09 01:05:20 +02:00
teknomunk 96a03b1923 Remove posibility of nil sky colors in overworld, add line break 2024-10-09 01:05:20 +02:00
teknomunk 2145470f63 Fix clouds during rain->clear weather transition 2024-10-09 01:05:20 +02:00
teknomunk 2ca0ccd8fe Fix fog tint in overworld, apply memory leak fix from rain.lua to snow.lua and thunder.lua 2024-10-09 01:05:20 +02:00
teknomunk 614518c6cd Revert minetest.add_entity() -> mcl_mobs.spawn() from #4445 (#4679)
Reviewed-on: VoxeLibre/VoxeLibre#4679
Reviewed-by: kno10 <kno10@noreply.git.minetest.land>
Co-authored-by: teknomunk <teknomunk@protonmail.com>
Co-committed-by: teknomunk <teknomunk@protonmail.com>
2024-10-08 15:34:30 +02:00
14 changed files with 109 additions and 97 deletions

View File

@ -105,7 +105,7 @@ end
-- Spawn a child -- Spawn a child
function mcl_mobs.spawn_child(pos, mob_type) function mcl_mobs.spawn_child(pos, mob_type)
local child = mcl_mobs.spawn(pos, mob_type) local child = minetest.add_entity(pos, mob_type)
if not child then if not child then
return return
end end

View File

@ -928,8 +928,6 @@ end
-- falling and fall damage -- falling and fall damage
-- returns true if mob died -- returns true if mob died
function mob_class:falling(pos, moveresult) function mob_class:falling(pos, moveresult)
if moveresult and moveresult.touching_ground then return false end
if self.fly and self.state ~= "die" then if self.fly and self.state ~= "die" then
return return
end end
@ -952,7 +950,13 @@ function mob_class:falling(pos, moveresult)
new_acceleration = vector.new(0, DEFAULT_FALL_SPEED, 0) new_acceleration = vector.new(0, DEFAULT_FALL_SPEED, 0)
elseif v.y <= 0 and v.y > self.fall_speed then elseif v.y <= 0 and v.y > self.fall_speed then
-- fall downwards at set speed -- fall downwards at set speed
new_acceleration = vector.new(0, self.fall_speed, 0) if moveresult and moveresult.touching_ground then
-- when touching ground, retain a minimal gravity to keep the touching_ground flag
-- but also to not get upwards acceleration with large dtime when on bouncy ground
new_acceleration = vector.new(0, self.fall_speed * 0.01, 0)
else
new_acceleration = vector.new(0, self.fall_speed, 0)
end
else else
-- stop accelerating once max fall speed hit -- stop accelerating once max fall speed hit
new_acceleration =vector.zero() new_acceleration =vector.zero()

View File

@ -72,18 +72,24 @@ local axolotl = {
fly = true, fly = true,
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" }, fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
breathes_in_water = true, breathes_in_water = true,
jump = true, jump = false, -- would get them out of the water too often
damage = 2, damage = 2,
reach = 2, reach = 2,
attack_type = "dogfight", attack_type = "dogfight",
attack_animals = true, attack_animals = true,
specific_attack = { specific_attack = {
"extra_mobs_cod", "mobs_mc:cod",
"extra_mobs_glow_squid", "mobs_mc:glow_squid",
"extra_mobs_salmon", "mobs_mc:salmon",
"extra_mobs_tropical_fish", "mobs_mc:tropical_fish",
"mobs_mc_squid" "mobs_mc:squid",
}, "mobs_mc:zombie", -- todo: only drowned?
"mobs_mc:baby_zombie",
"mobs_mc:husk",
"mobs_mc:baby_husk",
"mobs_mc:guardian_elder",
"mobs_mc:guardian",
},
runaway = true, runaway = true,
} }

View File

@ -157,6 +157,7 @@ function mcl_weather.rain.clear()
mcl_weather.rain.remove_sound(player) mcl_weather.rain.remove_sound(player)
mcl_weather.rain.remove_player(player) mcl_weather.rain.remove_player(player)
mcl_weather.remove_spawners_player(player) mcl_weather.remove_spawners_player(player)
player:set_clouds({color="#FFF0EF"})
end end
end end

View File

@ -2,6 +2,7 @@
local modname = minetest.get_current_modname() local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname) local modpath = minetest.get_modpath(modname)
local NIGHT_VISION_RATIO = 0.45 local NIGHT_VISION_RATIO = 0.45
local DEBUG = false
-- Settings -- Settings
local minimum_update_interval = { 250e3 } local minimum_update_interval = { 250e3 }
@ -190,8 +191,8 @@ end
function skycolor_utils.convert_to_rgb(minval, maxval, current_val, colors) function skycolor_utils.convert_to_rgb(minval, maxval, current_val, colors)
-- Clamp current_val to valid range -- Clamp current_val to valid range
current_val = math.min(minval, current_val) current_val = math.max(minval, current_val)
current_val = math.max(maxval, current_val) current_val = math.min(maxval, current_val)
-- Rescale current_val from a number between minval and maxval to a number between 1 and #colors -- Rescale current_val from a number between minval and maxval to a number between 1 and #colors
local scaled_value = (current_val - minval) / (maxval - minval) * (#colors - 1) + 1.0 local scaled_value = (current_val - minval) / (maxval - minval) * (#colors - 1) + 1.0
@ -199,7 +200,7 @@ function skycolor_utils.convert_to_rgb(minval, maxval, current_val, colors)
-- Get the first color's values -- Get the first color's values
local index1 = math.floor(scaled_value) local index1 = math.floor(scaled_value)
local color1 = colors[index1] local color1 = colors[index1]
local frac1 = scaled_value - index1 local frac1 = 1.0 - (scaled_value - index1)
-- Get the second color's values -- Get the second color's values
local index2 = math.min(index1 + 1, #colors) -- clamp to maximum color index (will occur if index1 == #colors) local index2 = math.min(index1 + 1, #colors) -- clamp to maximum color index (will occur if index1 == #colors)
@ -207,11 +208,32 @@ function skycolor_utils.convert_to_rgb(minval, maxval, current_val, colors)
local color2 = colors[index2] local color2 = colors[index2]
-- Interpolate between color1 and color2 -- Interpolate between color1 and color2
return { local res = {
r = math.floor(frac1 * color1.r + frac2 * color2.r), r = math.floor(frac1 * color1.r + frac2 * color2.r),
g = math.floor(frac1 * color1.g + frac2 * color2.g), g = math.floor(frac1 * color1.g + frac2 * color2.g),
b = math.floor(frac1 * color1.b + frac2 * color2.b), b = math.floor(frac1 * color1.b + frac2 * color2.b),
} }
if DEBUG then
minetest.log(dump({
minval = minval,
maxval = maxval,
current_val = current_val,
colors = colors,
res = res,
scaled_value = scaled_value,
frac1 = frac1,
index1 = index1,
color1 = color1,
frac2 = frac2,
index2 = index2,
color2 = color2,
}))
end
return res
end end
-- Simple getter. Either returns user given players list or get all connected players if none provided -- Simple getter. Either returns user given players list or get all connected players if none provided

View File

@ -40,18 +40,21 @@ function dimension_handlers.overworld(player, sky_data)
end end
-- Use overworld defaults -- Use overworld defaults
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.15) local day_color = mcl_weather.skycolor.get_sky_layer_color(0.5)
local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.27) local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.27)
local night_color = mcl_weather.skycolor.get_sky_layer_color(0.1) local night_color = mcl_weather.skycolor.get_sky_layer_color(0.1)
sky_data.sky = { sky_data.sky = {
type = "regular", type = "regular",
sky_color = { sky_color = {
day_sky = day_color, day_sky = day_color or "#7BA4FF",
day_horizon = day_color, day_horizon = day_color or "#C0D8FF",
dawn_sky = dawn_color, dawn_sky = dawn_color or "7BA4FF",
dawn_horizon = dawn_color, dawn_horizon = dawn_color or "#C0D8FF",
night_sky = night_color, night_sky = night_color or "000000",
night_horizon = night_color, night_horizon = night_color or "4A6790",
fog_sun_tint = "#ff5f33",
fog_moon_tint = nil,
fog_tint_type = "custom",
}, },
clouds = true, clouds = true,
} }
@ -75,18 +78,15 @@ function dimension_handlers.overworld(player, sky_data)
local day_color = mcl_weather.skycolor.get_sky_layer_color(0.5) local day_color = mcl_weather.skycolor.get_sky_layer_color(0.5)
local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.75) local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.75)
local night_color = mcl_weather.skycolor.get_sky_layer_color(0) local night_color = mcl_weather.skycolor.get_sky_layer_color(0)
sky_data.sky = { table.update(sky_data.sky.sky_color,{
type = "regular", day_sky = day_color or "#7BA4FF",
sky_color = { day_horizon = day_color or "#C0D8FF",
day_sky = day_color, dawn_sky = dawn_color or "7BA4FF",
day_horizon = day_color, dawn_horizon = dawn_color or "#C0D8FF",
dawn_sky = dawn_color, night_sky = night_color or "000000",
dawn_horizon = dawn_color, night_horizon = night_color or "4A6790",
night_sky = night_color, fog_tint_type = "default",
night_horizon = night_color, })
},
clouds = true,
}
sky_data.sun = {visible = false, sunrise_visible = false} sky_data.sun = {visible = false, sunrise_visible = false}
sky_data.moon = {visible = false} sky_data.moon = {visible = false}
sky_data.stars = {visible = false} sky_data.stars = {visible = false}
@ -164,7 +164,8 @@ function dimension_handlers.nether(player, sky_data)
end end
function dimension_handlers.void(player, sky_data) function dimension_handlers.void(player, sky_data)
sky_data.sky = { type = "plain", sky_data.sky = {
type = "plain",
base_color = "#000000", base_color = "#000000",
clouds = false, clouds = false,
} }

View File

@ -75,13 +75,15 @@ function mcl_weather.has_snow(pos)
end end
function mcl_weather.snow.set_sky_box() function mcl_weather.snow.set_sky_box()
mcl_weather.skycolor.add_layer( if mcl_weather.skycolor.current_layer_name() ~= "weather-pack-snow-sky" then
"weather-pack-snow-sky", mcl_weather.skycolor.add_layer(
{{r=0, g=0, b=0}, "weather-pack-snow-sky",
{r=85, g=86, b=86}, {{r=0, g=0, b=0},
{r=135, g=135, b=135}, {r=85, g=86, b=86},
{r=85, g=86, b=86}, {r=135, g=135, b=135},
{r=0, g=0, b=0}}) {r=85, g=86, b=86},
{r=0, g=0, b=0}})
end
mcl_weather.skycolor.active = true mcl_weather.skycolor.active = true
for _, player in pairs(get_connected_players()) do for _, player in pairs(get_connected_players()) do
player:set_clouds({color="#ADADADE8"}) player:set_clouds({color="#ADADADE8"})

View File

@ -23,13 +23,15 @@ minetest.register_globalstep(function(dtime)
mcl_weather.rain.make_weather() mcl_weather.rain.make_weather()
if mcl_weather.thunder.init_done == false then if mcl_weather.thunder.init_done == false then
mcl_weather.skycolor.add_layer("weather-pack-thunder-sky", { if mcl_weather.skycolor.current_layer_name() ~= "weather-pack-thunder-sky" then
{r=0, g=0, b=0}, mcl_weather.skycolor.add_layer("weather-pack-thunder-sky", {
{r=40, g=40, b=40}, {r=0, g=0, b=0},
{r=85, g=86, b=86}, {r=40, g=40, b=40},
{r=40, g=40, b=40}, {r=85, g=86, b=86},
{r=0, g=0, b=0}, {r=40, g=40, b=40},
}) {r=0, g=0, b=0},
})
end
mcl_weather.skycolor.active = true mcl_weather.skycolor.active = true
for _, player in pairs(get_connected_players()) do for _, player in pairs(get_connected_players()) do
player:set_clouds({color="#3D3D3FE8"}) player:set_clouds({color="#3D3D3FE8"})

View File

@ -5,9 +5,6 @@
--- Copyright (C) 2022 - 2023, Michieal. See License.txt --- Copyright (C) 2022 - 2023, Michieal. See License.txt
-- CONSTS -- CONSTS
local DOUBLE_DROP_CHANCE = 8
-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it...
-- "BAMBOO" goes here.
local BAMBOO = "mcl_bamboo:bamboo" local BAMBOO = "mcl_bamboo:bamboo"
local BAMBOO_ENDCAP_NAME = "mcl_bamboo:bamboo_endcap" local BAMBOO_ENDCAP_NAME = "mcl_bamboo:bamboo_endcap"
local BAMBOO_PLANK = BAMBOO .. "_plank" local BAMBOO_PLANK = BAMBOO .. "_plank"
@ -16,7 +13,7 @@ local BAMBOO_PLANK = BAMBOO .. "_plank"
local modname = minetest.get_current_modname() local modname = minetest.get_current_modname()
local S = minetest.get_translator(modname) local S = minetest.get_translator(modname)
local node_sound = mcl_sounds.node_sound_wood_defaults() local node_sound = mcl_sounds.node_sound_wood_defaults()
local pr = PseudoRandom((os.time() + 15766) * 12) -- switched from math.random() to PseudoRandom because the random wasn't very random. local pr = PseudoRandom((os.time() + 15766) * 12)
local on_rotate local on_rotate
if minetest.get_modpath("screwdriver") then if minetest.get_modpath("screwdriver") then
@ -31,33 +28,7 @@ local bamboo_def = {
paramtype = "light", paramtype = "light",
groups = {handy = 1, axey = 1, choppy = 1, dig_by_piston = 1, plant = 1, non_mycelium_plant = 1, flammable = 3}, groups = {handy = 1, axey = 1, choppy = 1, dig_by_piston = 1, plant = 1, non_mycelium_plant = 1, flammable = 3},
sounds = node_sound, sounds = node_sound,
drop = BAMBOO,
drop = {
max_items = 1,
-- From the API:
-- max_items: Maximum number of item lists to drop.
-- The entries in 'items' are processed in order. For each:
-- Item filtering is applied, chance of drop is applied, if both are
-- successful the entire item list is dropped.
-- Entry processing continues until the number of dropped item lists
-- equals 'max_items'.
-- Therefore, entries should progress from low to high drop chance.
items = {
-- Examples:
{
-- 1 in DOUBLE_DROP_CHANCE chance of dropping.
-- Default rarity is '1'.
rarity = DOUBLE_DROP_CHANCE,
items = {BAMBOO .. " 2"},
},
{
-- 1 in 1 chance of dropping. (Note: this means that it will drop 100% of the time.)
-- Default rarity is '1'.
rarity = 1,
items = {BAMBOO},
},
},
},
inventory_image = "mcl_bamboo_bamboo_shoot.png", inventory_image = "mcl_bamboo_bamboo_shoot.png",
wield_image = "mcl_bamboo_bamboo_shoot.png", wield_image = "mcl_bamboo_bamboo_shoot.png",
@ -86,7 +57,6 @@ local bamboo_def = {
on_rotate = on_rotate, on_rotate = on_rotate,
on_place = function(itemstack, placer, pointed_thing) on_place = function(itemstack, placer, pointed_thing)
if not pointed_thing then if not pointed_thing then
return itemstack return itemstack
end end
@ -241,9 +211,6 @@ local bamboo_def = {
if node_above and ((bamboo_node and bamboo_node > 0) or node_above.name == BAMBOO_ENDCAP_NAME) then if node_above and ((bamboo_node and bamboo_node > 0) or node_above.name == BAMBOO_ENDCAP_NAME) then
minetest.remove_node(new_pos) minetest.remove_node(new_pos)
minetest.sound_play(node_sound.dug, sound_params, true) minetest.sound_play(node_sound.dug, sound_params, true)
if pr:next(1, DOUBLE_DROP_CHANCE) == 1 then
minetest.add_item(new_pos, istack)
end
minetest.add_item(new_pos, istack) minetest.add_item(new_pos, istack)
end end
end, end,

View File

@ -9,8 +9,6 @@ local SIDE_SCAFFOLDING = false
local SIDE_SCAFFOLD_NAME = "mcl_bamboo:scaffolding_horizontal" local SIDE_SCAFFOLD_NAME = "mcl_bamboo:scaffolding_horizontal"
-- --------------------------------------------------------------------------- -- ---------------------------------------------------------------------------
local SCAFFOLDING_NAME = "mcl_bamboo:scaffolding" local SCAFFOLDING_NAME = "mcl_bamboo:scaffolding"
-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it...
-- "BAMBOO" goes here.
local BAMBOO = "mcl_bamboo:bamboo" local BAMBOO = "mcl_bamboo:bamboo"
local BAMBOO_PLANK = BAMBOO .. "_plank" local BAMBOO_PLANK = BAMBOO .. "_plank"

View File

@ -7,8 +7,6 @@
-- LOCALS -- LOCALS
local modname = minetest.get_current_modname() local modname = minetest.get_current_modname()
-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it...
-- "BAMBOO" goes here.
local BAMBOO = "mcl_bamboo:bamboo" local BAMBOO = "mcl_bamboo:bamboo"
mcl_bamboo = {} mcl_bamboo = {}

View File

@ -5,8 +5,6 @@
--- These are all of the fuel recipes and all of the crafting recipes, consolidated into one place. --- These are all of the fuel recipes and all of the crafting recipes, consolidated into one place.
--- Copyright (C) 2022 - 2023, Michieal. See License.txt --- Copyright (C) 2022 - 2023, Michieal. See License.txt
-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it...
-- "BAMBOO" goes here.
local BAMBOO = "mcl_bamboo:bamboo" local BAMBOO = "mcl_bamboo:bamboo"
local BAMBOO_PLANK = BAMBOO .. "_plank" local BAMBOO_PLANK = BAMBOO .. "_plank"
-- Craftings -- Craftings

View File

@ -36,7 +36,11 @@ else
end end
end end
tsm_railcorridors.carts = { "mcl_minecarts:chest_minecart" } tsm_railcorridors.carts = {
"mcl_minecarts:minecart", "mcl_minecarts:minecart",
"mcl_minecarts:chest_minecart", "mcl_minecarts:chest_minecart",
"mcl_minecarts:tnt_minecart"
}
-- This is called after a spawner has been placed by the game. -- This is called after a spawner has been placed by the game.
-- Use this to properly set up the metadata and stuff. -- Use this to properly set up the metadata and stuff.
@ -54,9 +58,11 @@ end
function tsm_railcorridors.on_construct_cart(_, cart, pr_carts) function tsm_railcorridors.on_construct_cart(_, cart, pr_carts)
local l = cart:get_luaentity() local l = cart:get_luaentity()
local inv = mcl_entity_invs.load_inv(l,27) local inv = mcl_entity_invs.load_inv(l,27)
local items = tsm_railcorridors.get_treasures(pr_carts) if inv then -- otherwise probably not a chest minecart
mcl_loot.fill_inventory(inv, "main", items, pr_carts) local items = tsm_railcorridors.get_treasures(pr_carts)
mcl_entity_invs.save_inv(l) mcl_loot.fill_inventory(inv, "main", items, pr_carts)
mcl_entity_invs.save_inv(l)
end
end end
-- Fallback function. Returns a random treasure. This function is called for chests -- Fallback function. Returns a random treasure. This function is called for chests

View File

@ -397,7 +397,9 @@ end
-- This is a workaround thanks to the fact that minetest.add_entity is unreliable as fuck -- This is a workaround thanks to the fact that minetest.add_entity is unreliable as fuck
-- See: https://github.com/minetest/minetest/issues/4759 -- See: https://github.com/minetest/minetest/issues/4759
-- FIXME: Kill this horrible hack with fire as soon you can. -- FIXME: Kill this horrible hack with fire as soon you can.
local function RecheckCartHack(params) local RecheckCartHack = nil
if not minetest.features.random_state_restore then -- proxy for minetest > 5.9.0, this feature will not be removed
RecheckCartHack = function(params)
local pos = params[1] local pos = params[1]
local cart_id = params[2] local cart_id = params[2]
-- Find cart -- Find cart
@ -412,6 +414,7 @@ local function RecheckCartHack(params)
end end
minetest.log("info", "[tsm_railcorridors] Cart spawn FAILED: "..minetest.pos_to_string(pos)) minetest.log("info", "[tsm_railcorridors] Cart spawn FAILED: "..minetest.pos_to_string(pos))
end end
end
-- Try to place a cobweb. -- Try to place a cobweb.
-- pos: Position of cobweb -- pos: Position of cobweb
@ -935,13 +938,17 @@ local function spawn_carts()
-- See <https://github.com/minetest/minetest/issues/4759> -- See <https://github.com/minetest/minetest/issues/4759>
local cart_id = tsm_railcorridors.carts[cart_type] local cart_id = tsm_railcorridors.carts[cart_type]
minetest.log("info", "[tsm_railcorridors] Cart spawn attempt: "..minetest.pos_to_string(cpos)) minetest.log("info", "[tsm_railcorridors] Cart spawn attempt: "..minetest.pos_to_string(cpos))
minetest.add_entity(cpos, cart_id) local obj = minetest.add_entity(cpos, cart_id)
-- This checks if the cart is actually spawned, it's a giant hack! -- This checks if the cart is actually spawned, it's a giant hack!
-- Note that the callback function is also called there. -- Note that the callback function is also called there.
-- TODO: Move callback function to this position when the -- TODO: Move callback function to this position when the
-- minetest.add_entity bug has been fixed (supposedly in 5.9.0?) -- minetest.add_entity bug has been fixed (supposedly in 5.9.0?)
minetest.after(3, RecheckCartHack, {cpos, cart_id}) if RecheckCartHack then
minetest.after(3, RecheckCartHack, {cpos, cart_id})
else
tsm_railcorridors.on_construct_cart(cpos, obj, pr_carts)
end
end end
end end
carts_table = {} carts_table = {}