Update railcorridors, enable chest minecarts (#4620)

Minecart chests seem to work by now.

Reviewed-on: https://git.minetest.land/VoxeLibre/VoxeLibre/pulls/4620
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
Co-authored-by: kno10 <erich.schubert@gmail.com>
Co-committed-by: kno10 <erich.schubert@gmail.com>
This commit is contained in:
kno10 2024-08-31 19:36:18 +02:00 committed by the-real-herowl
parent 2dadfda76b
commit ecfa42d51d
6 changed files with 63 additions and 63 deletions

@ -0,0 +1,9 @@
Copyright © 2023 Wuzzy, joz
The MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -1,7 +1,7 @@
# Railway corridors [`tsm_railcorridors`] # Railway corridors [`tsm_railcorridors`]
VoxeLibre adaption. NO TREASURER SUPPORT! VoxeLibre adaption. NO TREASURER SUPPORT!
* Current version 0.14.0 * Current version 0.14.5
Minetest mod for adding underground corridors with rails and wood constructions with a few treasure chests now and then. Minetest mod for adding underground corridors with rails and wood constructions with a few treasure chests now and then.
Optional support for the Treasurer mod is available for adding treasures from various mods. Optional support for the Treasurer mod is available for adding treasures from various mods.
@ -10,7 +10,7 @@ Cobwebs are added if the `mobs_monster` mod is found.
Use the advanced settings to finetune the railway corridors. Use the advanced settings to finetune the railway corridors.
* Forum thread: https://forum.minetest.net/viewtopic.php?t=10339 * Forum thread: https://forum.minetest.net/viewtopic.php?t=10339
* License: MIT License. * License: MIT License (see `LICENSE.txt`).
## Info for game makers ## Info for game makers
Want to include this mod in a game, but you have problems with the dependencies? Want to include this mod in a game, but you have problems with the dependencies?

@ -27,7 +27,7 @@ if mg_name == "v6" then
} }
else else
-- This generates dark oak wood in mesa biomes and oak wood everywhere else. -- This generates dark oak wood in mesa biomes and oak wood everywhere else.
function tsm_railcorridors.nodes.corridor_woods_function(pos, node) function tsm_railcorridors.nodes.corridor_woods_function(_, node)
if minetest.get_item_group(node.name, "hardened_clay") ~= 0 then if minetest.get_item_group(node.name, "hardened_clay") ~= 0 then
return "mcl_core:darkwood", "mcl_fences:dark_oak_fence" return "mcl_core:darkwood", "mcl_fences:dark_oak_fence"
else else
@ -36,34 +36,36 @@ else
end end
end end
tsm_railcorridors.carts = { "mcl_minecarts:chest_minecart" }
-- TODO: Use minecart with chest instead of normal minecart -- This is called after a spawner has been placed by the game.
tsm_railcorridors.carts = { "mcl_minecarts:minecart" } -- Use this to properly set up the metadata and stuff.
-- This is needed for games if they include mob spawners.
-- All spawners spawn cave spiders
function tsm_railcorridors.on_construct_spawner(pos)
mcl_mobspawners.setup_spawner(pos, "mobs_mc:cave_spider", 0, 7)
end
function tsm_railcorridors.on_construct_cart(pos, cart)
-- TODO: Fill cart with treasures
-- This is it? There's this giant hack announced in -- This is called after a cart has been placed by the game.
-- the other file and I grep for the function and it's -- Use this to properly set up entity metadata and stuff.
-- a stub? :) -- * pos: Position of cart
-- * cart: Cart entity
-- The path here using some minetest.after hackery was function tsm_railcorridors.on_construct_cart(_, cart, pr_carts)
-- deactivated in init.lua - reactivate when this does local l = cart:get_luaentity()
-- something the function is called RecheckCartHack. local inv = mcl_entity_invs.load_inv(l,27)
local items = tsm_railcorridors.get_treasures(pr_carts)
mcl_loot.fill_inventory(inv, "main", items, pr_carts)
mcl_entity_invs.save_inv(l)
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
-- only if the Treasurer mod is not found. -- only if the Treasurer mod is not found.
-- pr: A PseudoRandom object -- pr: A PseudoRandom object
function tsm_railcorridors.get_default_treasure(pr) function tsm_railcorridors.get_default_treasure(_)
-- UNUSED IN MINECLONE 2! -- UNUSED IN MINECLONE 2!
end end
-- All spawners spawn cave spiders
function tsm_railcorridors.on_construct_spawner(pos)
mcl_mobspawners.setup_spawner(pos, "mobs_mc:cave_spider", 0, 7)
end
-- MineClone 2's treasure function. Gets all treasures for a single chest. -- MineClone 2's treasure function. Gets all treasures for a single chest.
-- Based on information from Minecraft Wiki. -- Based on information from Minecraft Wiki.
function tsm_railcorridors.get_treasures(pr) function tsm_railcorridors.get_treasures(pr)

@ -10,8 +10,7 @@ dofile(minetest.get_modpath(minetest.get_current_modname()).."/gameconfig.lua")
local setting local setting
-- Probability function -- Probability function
-- TODO: Check if this is correct local P = function (float)
local function P(float)
return math.floor(32767 * float) return math.floor(32767 * float)
end end
@ -27,8 +26,8 @@ elseif setting then
end end
-- Minimal and maximal value of path length (forks don't look up this value) -- Minimal and maximal value of path length (forks don't look up this value)
local way_min = 4; local way_min = 4
local way_max = 7; local way_max = 7
setting = tonumber(minetest.settings:get("tsm_railcorridors_way_min")) setting = tonumber(minetest.settings:get("tsm_railcorridors_way_min"))
if setting then if setting then
way_min = setting way_min = setting
@ -74,7 +73,7 @@ if setting then
end end
-- Probability for a rail corridor system to be damaged -- Probability for a rail corridor system to be damaged
local probability_damage = P(1.0) local probability_damage = P(0.55)
setting = tonumber(minetest.settings:get("tsm_railcorridors_probability_damage")) setting = tonumber(minetest.settings:get("tsm_railcorridors_probability_damage"))
if setting then if setting then
probability_damage = P(setting) probability_damage = P(setting)
@ -83,14 +82,14 @@ end
-- Enable cobwebs -- Enable cobwebs
local place_cobwebs = true local place_cobwebs = true
setting = minetest.settings:get_bool("tsm_railcorridors_place_cobwebs") setting = minetest.settings:get_bool("tsm_railcorridors_place_cobwebs")
if setting then if setting ~= nil then
place_cobwebs = setting place_cobwebs = setting
end end
-- Enable mob spawners -- Enable mob spawners
local place_mob_spawners = true local place_mob_spawners = true
setting = minetest.settings:get_bool("tsm_railcorridors_place_mob_spawners") setting = minetest.settings:get_bool("tsm_railcorridors_place_mob_spawners")
if setting then if setting ~= nil then
place_mob_spawners = setting place_mob_spawners = setting
end end
@ -153,17 +152,17 @@ local function SetNodeIfCanBuild(pos, node, check_above, can_replace_rail)
if check_above then if check_above then
local abovename = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}).name local abovename = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}).name
local abovedef = minetest.registered_nodes[abovename] local abovedef = minetest.registered_nodes[abovename]
if abovename == "unknown" or abovename == "ignore" or if (not abovedef) or abovename == "unknown" or abovename == "ignore" or
(abovedef and abovedef.groups and abovedef.groups.attached_node) or (abovedef.groups and abovedef.groups.attached_node) or
-- This is done because cobwebs are often fake liquids -- This is done because cobwebs are often fake liquids
(abovedef and abovedef.liquidtype ~= "none" and abovename ~= tsm_railcorridors.nodes.cobweb) then (abovedef.liquidtype ~= "none" and abovename ~= tsm_railcorridors.nodes.cobweb) then
return false return false
end end
end end
local name = minetest.get_node(pos).name local name = minetest.get_node(pos).name
local def = minetest.registered_nodes[name] local def = minetest.registered_nodes[name]
if name ~= "unknown" and name ~= "ignore" and if name ~= "unknown" and name ~= "ignore" and def and
((def and def.is_ground_content and def.liquidtype == "none") or ((def.is_ground_content and def.liquidtype == "none") or
name == tsm_railcorridors.nodes.cobweb or name == tsm_railcorridors.nodes.cobweb or
name == tsm_railcorridors.nodes.torch_wall or name == tsm_railcorridors.nodes.torch_wall or
name == tsm_railcorridors.nodes.torch_floor or name == tsm_railcorridors.nodes.torch_floor or
@ -178,7 +177,7 @@ end
-- Tries to place a rail, taking the damage chance into account -- Tries to place a rail, taking the damage chance into account
local function PlaceRail(pos, damage_chance) local function PlaceRail(pos, damage_chance)
if damage_chance and damage_chance > 0 then if damage_chance ~= nil and damage_chance > 0 then
local x = pr:next(0,100) local x = pr:next(0,100)
if x <= damage_chance then if x <= damage_chance then
return false return false
@ -211,7 +210,7 @@ local function NeedsPlatform(pos)
local falling = minetest.get_item_group(node.name, "falling_node") == 1 local falling = minetest.get_item_group(node.name, "falling_node") == 1
return return
-- Node can be replaced if ground content or rail -- Node can be replaced if ground content or rail
(node.name ~= "ignore" and node.name ~= "unknown" and nodedef and nodedef.is_ground_content) and (nodedef and node.name ~= "ignore" and node.name ~= "unknown" and nodedef.is_ground_content) and
-- Node needs platform if node below is not walkable. -- Node needs platform if node below is not walkable.
-- Unless 2 nodes below there is dirt: This is a special case for the starter cube. -- Unless 2 nodes below there is dirt: This is a special case for the starter cube.
((nodedef.walkable == false and node2.name ~= tsm_railcorridors.nodes.dirt) or ((nodedef.walkable == false and node2.name ~= tsm_railcorridors.nodes.dirt) or
@ -237,7 +236,7 @@ end
local function Cube(p, radius, node, replace_air_only, wood, post) local function Cube(p, radius, node, replace_air_only, wood, post)
local y_top = p.y+radius local y_top = p.y+radius
local nodedef = minetest.registered_nodes[node.name] local nodedef = minetest.registered_nodes[node.name]
local solid = nodedef.walkable and (nodedef.node_box == nil or nodedef.node_box.type == "regular") and nodedef.liquidtype == "none" local solid = nodedef and nodedef.walkable and (nodedef.node_box == nil or nodedef.node_box.type == "regular") and nodedef.liquidtype == "none"
-- Check if all the nodes could be set -- Check if all the nodes could be set
local built_all = true local built_all = true
@ -253,7 +252,7 @@ local function Cube(p, radius, node, replace_air_only, wood, post)
if yi == y_top then if yi == y_top then
local topnode = minetest.get_node({x=xi,y=yi+1,z=zi}) local topnode = minetest.get_node({x=xi,y=yi+1,z=zi})
local topdef = minetest.registered_nodes[topnode.name] local topdef = minetest.registered_nodes[topnode.name]
if minetest.get_item_group(topnode.name, "attached_node") ~= 1 and topdef and topdef.liquidtype == "none" then if topdef and minetest.get_item_group(topnode.name, "attached_node") ~= 1 and topdef.liquidtype == "none" then
ok = true ok = true
end end
elseif column_last_attached and yi == column_last_attached - 1 then elseif column_last_attached and yi == column_last_attached - 1 then
@ -364,8 +363,7 @@ local function Platform(p, radius, node, node2)
if not node2 then if not node2 then
node2 = { name = tsm_railcorridors.nodes.dirt } node2 = { name = tsm_railcorridors.nodes.dirt }
end end
local n1 = {} local n1, n2 = {}, {}
local n2 = {}
for zi = p.z-radius, p.z+radius do for zi = p.z-radius, p.z+radius do
for xi = p.x-radius, p.x+radius do for xi = p.x-radius, p.x+radius do
local np, np2 = NeedsPlatform({x=xi,y=p.y,z=zi}) local np, np2 = NeedsPlatform({x=xi,y=p.y,z=zi})
@ -394,33 +392,26 @@ local function PlaceChest(pos, param2)
end end
end end
-- This function checks if a cart has ACTUALLY been spawned. -- This function checks if a cart has ACTUALLY been spawned.
-- To be calld by minetest.after. -- To be calld by minetest.after.
-- 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.
-- Why did anyone activate it in the first place? It doesn't
-- have a function seeing as there are no chest minecarts yet.
--[[
local function RecheckCartHack(params) local function RecheckCartHack(params)
local pos = params[1] local pos = params[1]
local cart_id = params[2] local cart_id = params[2]
-- Find cart -- Find cart
for _, obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
if obj and obj:get_luaentity().name == cart_id then if obj ~= nil and obj:get_luaentity().name == cart_id then
-- Cart found! We can now safely call the callback func. -- Cart found! We can now safely call the callback func.
-- (calling it earlier has the danger of failing) -- (calling it earlier has the danger of failing)
minetest.log("info", "[tsm_railcorridors] Cart spawn succeeded: "..minetest.pos_to_string(pos)) minetest.log("info", "[tsm_railcorridors] Cart spawn succeeded: "..minetest.pos_to_string(pos))
tsm_railcorridors.on_construct_cart(pos, obj) tsm_railcorridors.on_construct_cart(pos, obj, pr_carts)
return return
end end
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
--]]
-- Try to place a cobweb. -- Try to place a cobweb.
-- pos: Position of cobweb -- pos: Position of cobweb
@ -627,7 +618,7 @@ local function create_corridor_section(waypoint, axis, sign, up_or_down, up_or_d
if sign then if sign then
segamount = 0-segamount segamount = 0-segamount
end end
local vek = {x=0,y=0,z=0}; local vek = {x=0,y=0,z=0}
local start = table.copy(waypoint) local start = table.copy(waypoint)
if axis == "x" then if axis == "x" then
vek.x=segamount vek.x=segamount
@ -714,7 +705,7 @@ local function create_corridor_section(waypoint, axis, sign, up_or_down, up_or_d
end end
if (minetest.get_node({x=p.x,y=p.y-1,z=p.z}).name=="air" and minetest.get_node({x=p.x,y=p.y-3,z=p.z}).name~=tsm_railcorridors.nodes.rail) then if (minetest.get_node({x=p.x,y=p.y-1,z=p.z}).name=="air" and minetest.get_node({x=p.x,y=p.y-3,z=p.z}).name~=tsm_railcorridors.nodes.rail) then
p.y = p.y - 1; p.y = p.y - 1
if i == chestplace then if i == chestplace then
chestplace = chestplace + 1 chestplace = chestplace + 1
end end
@ -840,7 +831,7 @@ local function create_corridor_line(waypoint, axis, sign, length, wood, post, da
local s = sign local s = sign
local ud = false -- Up or down local ud = false -- Up or down
local udn = false -- Up or down is next local udn = false -- Up or down is next
local udp -- Up or down was previous local udp = false -- Up or down was previous
local up = false -- true if going up local up = false -- true if going up
local upp = false -- true if was going up previously local upp = false -- true if was going up previously
for i=1,length do for i=1,length do
@ -891,7 +882,7 @@ local function create_corridor_line(waypoint, axis, sign, length, wood, post, da
wp, no_spawner = create_corridor_section(wp,a,s, ud, udn, udp, up, wood, post, first_or_final, damage, no_spawner) wp, no_spawner = create_corridor_section(wp,a,s, ud, udn, udp, up, wood, post, first_or_final, damage, no_spawner)
if wp == false then return end if wp == false then return end
-- Fork in the road? If so, starts 2-3 new corridor lines and terminates the current one. -- Fork in the road? If so, starts 2-3 new corridor lines and terminates the current one.
if pr:next() < probability_fork then if wp and pr:next() < probability_fork then
-- 75% chance to fork off in 3 directions (making a crossing) -- 75% chance to fork off in 3 directions (making a crossing)
-- 25% chance to fork off in 2 directions (making a t-junction) -- 25% chance to fork off in 2 directions (making a t-junction)
local is_crossing = pr:next(0, 3) < 3 local is_crossing = pr:next(0, 3) < 3
@ -911,7 +902,7 @@ local function create_corridor_line(waypoint, axis, sign, length, wood, post, da
{a2, not s}, -- to the other side {a2, not s}, -- to the other side
{a, s}, -- straight ahead {a, s}, -- straight ahead
} }
for f=1, forks do for _= 1, forks do
local r = pr:next(1, #fork_dirs) local r = pr:next(1, #fork_dirs)
create_corridor_line(wp, fork_dirs[r][1], fork_dirs[r][2], pr:next(way_min,way_max), wood, post, damage, no_spawner) create_corridor_line(wp, fork_dirs[r][1], fork_dirs[r][2], pr:next(way_min,way_max), wood, post, damage, no_spawner)
table.remove(fork_dirs, r) table.remove(fork_dirs, r)
@ -928,7 +919,7 @@ local function create_corridor_line(waypoint, axis, sign, length, wood, post, da
a="z" a="z"
elseif a=="z" then elseif a=="z" then
a="x" a="x"
end; end
s = pr:next(1, 2) == 1 s = pr:next(1, 2) == 1
end end
end end
@ -949,11 +940,8 @@ local function spawn_carts()
-- 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. -- minetest.add_entity bug has been fixed (supposedly in 5.9.0?)
minetest.after(3, RecheckCartHack, {cpos, cart_id})
-- minetest.after(3, RecheckCartHack, {cpos, cart_id})
-- This whole recheck logic leads to a stub right now
-- it can be reenabled when chest carts are a thing.
end end
end end
carts_table = {} carts_table = {}
@ -1115,7 +1103,7 @@ mcl_structures.register_structure("mineshaft",{
sidelen = 32, sidelen = 32,
y_max = 40, y_max = 40,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_vars.mg_overworld_min,
place_func = function(pos,def,pr,blockseed) place_func = function(pos,_,pr,blockseed)
local r = pr:next(-50,-10) local r = pr:next(-50,-10)
local p = vector.offset(pos,0,r,0) local p = vector.offset(pos,0,r,0)
if p.y < mcl_vars.mg_overworld_min + 5 then if p.y < mcl_vars.mg_overworld_min + 5 then
@ -1123,7 +1111,7 @@ mcl_structures.register_structure("mineshaft",{
end end
if p.y > -10 then return true end if p.y > -10 then return true end
InitRandomizer(blockseed) InitRandomizer(blockseed)
create_corridor_system(p, pr) create_corridor_system(p)
return true return true
end, end,

@ -1,4 +1,5 @@
name = tsm_railcorridors name = tsm_railcorridors
title = Rail Corridors
author = UgnilJoZ author = UgnilJoZ
description = Adds simple underground mines with railways and occasional treasure chests. description = Adds simple underground mines with railways and occasional treasure chests.
depends = mcl_init, mcl_worlds, mcl_core, mcl_mapgen_core, mcl_loot, mcl_tnt, mcl_farming, mcl_mobspawners, mcl_minecarts, mcl_structures depends = mcl_init, mcl_worlds, mcl_core, mcl_mapgen_core, mcl_loot, mcl_tnt, mcl_farming, mcl_mobspawners, mcl_minecarts, mcl_structures

@ -25,14 +25,14 @@ tsm_railcorridors_probability_chest (Chest probability) float 0.05 0.0 1.0
#of finding a cart in rail corridors with high rail damage will be lower. #of finding a cart in rail corridors with high rail damage will be lower.
#NOTE: Due to a bug in Minetest <https://github.com/minetest/minetest/issues/4759> #NOTE: Due to a bug in Minetest <https://github.com/minetest/minetest/issues/4759>
#carts often fail to spawn even if they should. #carts often fail to spawn even if they should.
tsm_railcorridors_probability_cart (Cart probability) float 0.0 0.0 1.0 tsm_railcorridors_probability_cart (Cart probability) float 0.05 0.0 1.0
#If enabled, cobwebs may be placed in some corridors. #If enabled, cobwebs may be placed in some corridors.
#Currently, cobwebs are only supported with the Mobs Redo mod. #Currently, cobwebs are only supported with the Mobs Redo mod.
tsm_railcorridors_place_cobwebs (Cobwebs) bool true tsm_railcorridors_place_cobwebs (Cobwebs) bool true
#Probability (0.0 to 1.0) for a rail corridor system to have damaged/incomplete railways #Probability (0.0 to 1.0) for a rail corridor system to have damaged/incomplete railways
tsm_railcorridors_probability_damage (Damaged railway probability) float 1.0 0.0 1.0 tsm_railcorridors_probability_damage (Damaged railway probability) float 0.55 0.0 1.0
#If enabled, rail corridors continue to generate through obstacles such #If enabled, rail corridors continue to generate through obstacles such
#as other rail corridors (without destroying them, mostly). This may lead #as other rail corridors (without destroying them, mostly). This may lead