techage_modpack/autobahn/init.lua
2023-11-05 13:18:27 +01:00

456 lines
13 KiB
Lua

--[[
Autobahn
Copyright (C) 2017-2021 Joachim Stolberg
GPL v3
See LICENSE.txt for more information
History:
2017-11-11 v0.01 first version
2019-09-13 v0.02 adapted to 5.0.0
2020-03-19 v0.03 recipe added for techage bitumen
2020-07-02 v0.04 further slope nodes added
]]--
local S = minetest.get_translator("autobahn")
local mod_player_monoids = minetest.get_modpath("player_monoids")
autobahn = {}
-- Test for MT 5.4 new string mode
autobahn.CLIP = minetest.features.use_texture_alpha_string_modes and "clip" or true
local Facedir2Dir = {[0] =
{x=0, y=0, z=1},
{x=1, y=0, z=0},
{x=0, y=0, z=-1},
{x=-1, y=0, z=0},
}
-- To prevent race condition crashes
local Currently_left_the_game = {}
local function is_active(player)
local pl_meta = player:get_meta()
if not pl_meta or pl_meta:get_int("autobahn_isactive") ~= 1 then
return false
end
return true
end
local function set_player_privs(player)
local meta = player:get_meta()
-- Check access conflicts with other mods
if meta:get_int("player_physics_locked") == 0 then
meta:set_int("player_physics_locked", 1)
if mod_player_monoids then
player_monoids.speed:add_change(player, 3.5, "autobahn:speed")
else
local physics = player:get_physics_override()
-- store the player privs default values
meta:set_float("autobahn_speed", physics.speed)
physics.speed = 3.5
-- write back
player:set_physics_override(physics)
end
-- set operator privs
meta:set_int("autobahn_isactive", 1)
minetest.sound_play("autobahn_motor", {
pos = player:get_pos(),
gain = 0.5,
max_hear_distance = 5,
})
end
end
local function reset_player_privs(player)
local meta = player:get_meta()
-- restore the player privs default values
meta:set_int("autobahn_isactive", 0)
if mod_player_monoids then
player_monoids.speed:del_change(player, "autobahn:speed")
else
local physics = player:get_physics_override()
physics.speed = meta:get_float("autobahn_speed")
if physics.speed == 0 then physics.speed = 1 end
-- delete stored default values
meta:set_string("autobahn_speed", "")
-- write back
player:set_physics_override(physics)
end
meta:set_int("player_physics_locked", 0)
end
minetest.register_on_joinplayer(function(player)
if is_active(player) then
reset_player_privs(player)
end
end)
minetest.register_on_leaveplayer(function(player)
if is_active(player) then
Currently_left_the_game[player:get_player_name()] = true
end
end)
minetest.register_on_respawnplayer(function(player)
if is_active(player) then
reset_player_privs(player)
end
end)
local function control_player(player_name)
if Currently_left_the_game[player_name] then
Currently_left_the_game[player_name] = nil
return
end
local player = minetest.get_player_by_name(player_name)
if player then
local pos = player:get_pos()
if pos then
pos.y = math.floor(pos.y)
local node = minetest.get_node(pos)
if string.sub(node.name,1,13) == "autobahn:node" then
minetest.after(0.5, control_player, player_name)
else
pos.y = pos.y - 1
node = minetest.get_node(pos)
if string.sub(node.name,1,13) == "autobahn:node" then
minetest.after(0.5, control_player, player_name)
else
pos.y = pos.y + 2
node = minetest.get_node(pos)
if string.sub(node.name,1,13) == "autobahn:node" then
minetest.after(0.5, control_player, player_name)
else
reset_player_privs(player)
end
end
end
end
end
end
local NodeTbl1 = {
["autobahn:node1"] = true,
["autobahn:node2"] = true,
["autobahn:node3"] = true,
["autobahn:node4"] = true,
["autobahn:node5"] = true,
["autobahn:node6"] = true,
["autobahn:node12"] = true,
["autobahn:node22"] = true,
["autobahn:node32"] = true,
["autobahn:node42"] = true,
["autobahn:node52"] = true,
["autobahn:node62"] = true,
}
local NodeTbl2 = {
["autobahn:node11"] = true,
["autobahn:node21"] = true,
["autobahn:node31"] = true,
["autobahn:node41"] = true,
["autobahn:node51"] = true,
["autobahn:node61"] = true,
}
local NodeTbl3 = {
["autobahn:node1"] = true,
["autobahn:node2"] = true,
["autobahn:node3"] = true,
["autobahn:node4"] = true,
["autobahn:node5"] = true,
["autobahn:node6"] = true,
}
-- 1) _o_
-- /\ [?] ==> 1
-- [T][T][S][S][S] T..tar
-- [S][S][S][S][S] S..sand
--
--
-- 2) _o_
-- /\ [1][?] ==> 2
-- [T][T][S][S][S]
-- [S][S][S][S][S]
--
--
-- 3) _o_
-- /\ [?] ==> 1
-- [S][S][S][T][T]
-- [S][S][S][S][S]
--
--
-- 4) _o_
-- /\ [?][1] ==> 2
-- [S][S][S][T][T]
-- [S][S][S][S][S]
local function update_node(pos)
local node = minetest.get_node(pos)
local nnode
local npos
-- check case 1
local facedir = (2 + node.param2) % 4
npos = vector.add(pos, Facedir2Dir[facedir])
npos.y = npos.y - 1
nnode = minetest.get_node(npos)
if NodeTbl1[nnode.name] and NodeTbl3[node.name] then
node.name = node.name .. "1"
if minetest.registered_nodes[node.name] then
minetest.swap_node(pos, node)
end
return
end
-- check case 2
npos.y = npos.y + 1
nnode = minetest.get_node(npos)
if NodeTbl2[nnode.name] then
node.name = string.sub(node.name,1,-1) .. "2"
if minetest.registered_nodes[node.name] then
minetest.swap_node(pos, node)
end
return
end
-- check case 3
facedir = (0 + node.param2) % 4
npos = vector.add(pos, Facedir2Dir[facedir])
npos.y = npos.y - 1
nnode = minetest.get_node(npos)
if NodeTbl1[nnode.name] and NodeTbl3[node.name] then
node.name = node.name .. "1"
node.param2 = 3
if minetest.registered_nodes[node.name] then
minetest.swap_node(pos, node)
end
return
end
-- check case 4
npos.y = npos.y + 1
nnode = minetest.get_node(npos)
if NodeTbl2[nnode.name] then
node.name = string.sub(node.name,1,-1) .. "2"
node.param2 = 3
if minetest.registered_nodes[node.name] then
minetest.swap_node(pos, node)
end
return
end
end
local function register_node(name, tiles, drawtype, mesh, box, drop)
minetest.register_node("autobahn:"..name, {
description = S("Autobahn"),
tiles = tiles,
drawtype = drawtype,
mesh = mesh,
selection_box = box,
collision_box = box,
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
use_texture_alpha = autobahn.CLIP,
sounds = default.node_sound_stone_defaults(),
is_ground_content = false,
groups = {cracky=2, crumbly=2,
fall_damage_add_percent = -80,
not_in_creative_inventory=(mesh==nil) and 0 or 1},
drop = "autobahn:"..drop,
after_place_node = function(pos, placer, itemstack, pointed_thing)
update_node(pos)
end,
on_rightclick = function(pos, node, clicker)
if is_active(clicker) then
reset_player_privs(clicker)
else
set_player_privs(clicker)
local player_name = clicker:get_player_name()
minetest.after(0.5, control_player, player_name)
end
end,
})
end
local sb1 = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, -0.375, 0.5},
{-0.5, -0.375, -0.25, 0.5, -0.25, 0.5},
{-0.5, -0.25, 0, 0.5, -0.125, 0.5},
{-0.5, -0.125, 0.25, 0.5, 0, 0.5},
}
}
local sb2 = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0.125, 0.5},
{-0.5, 0.125, -0.25, 0.5, 0.25, 0.5},
{-0.5, 0.25, 0, 0.5, 0.375, 0.5},
{-0.5, 0.375, 0.25, 0.5, 0.5, 0.5},
}
}
local Nodes = {
{name="node1", tiles={"autobahn1.png"}, drawtype="normal", mesh=nil, box=nil, drop="node1"},
{name="node2", tiles={"autobahn2.png","autobahn1.png"}, drawtype="normal", mesh=nil, box=nil, drop="node2"},
{name="node3", tiles={"autobahn3.png","autobahn1.png"}, drawtype="normal", mesh=nil, box=nil, drop="node3"},
{name="node4", tiles={"autobahn2.png^[transformR180]","autobahn1.png"}, drawtype="normal", mesh=nil, box=nil, drop="node4"},
{name="node5", tiles={"autobahn4.png^[transformR90]","autobahn1.png"}, drawtype="normal", mesh=nil, box=nil, drop="node5"},
{name="node6", tiles={"autobahn5.png^[transformR90]","autobahn1.png"}, drawtype="normal", mesh=nil, box=nil, drop="node6"},
{name="node11", tiles={"autobahn1.png"}, drawtype="mesh", mesh="autobahn_ramp1.obj", box=sb1, drop="node1"},
{name="node21", tiles={"autobahn2.png","autobahn1.png"}, drawtype="mesh", mesh="autobahn_ramp1.obj", box=sb1, drop="node2"},
{name="node31", tiles={"autobahn3.png","autobahn1.png"}, drawtype="mesh", mesh="autobahn_ramp1.obj", box=sb1, drop="node3"},
{name="node41", tiles={"autobahn2.png^[transformR180]","autobahn1.png"}, drawtype="mesh", mesh="autobahn_ramp1.obj", box=sb1, drop="node4"},
{name="node51", tiles={"autobahn4.png^[transformR90]","autobahn1.png"}, drawtype="mesh", mesh="autobahn_ramp1.obj", box=sb1, drop="node5"},
{name="node61", tiles={"autobahn5.png^[transformR90]","autobahn1.png"}, drawtype="mesh", mesh="autobahn_ramp1.obj", box=sb1, drop="node6"},
{name="node12", tiles={"autobahn1.png"}, drawtype="mesh", mesh="autobahn_ramp2.obj", box=sb2, drop="node1"},
{name="node22", tiles={"autobahn2.png","autobahn1.png"}, drawtype="mesh", mesh="autobahn_ramp2.obj", box=sb2, drop="node2"},
{name="node32", tiles={"autobahn3.png","autobahn1.png"}, drawtype="mesh", mesh="autobahn_ramp2.obj", box=sb2, drop="node3"},
{name="node42", tiles={"autobahn2.png^[transformR180]","autobahn1.png"}, drawtype="mesh", mesh="autobahn_ramp2.obj", box=sb2, drop="node4"},
{name="node52", tiles={"autobahn4.png^[transformR90]","autobahn1.png"}, drawtype="mesh", mesh="autobahn_ramp2.obj", box=sb2, drop="node5"},
{name="node62", tiles={"autobahn5.png^[transformR90]","autobahn1.png"}, drawtype="mesh", mesh="autobahn_ramp2.obj", box=sb2, drop="node6"},
}
for _,item in ipairs(Nodes) do
register_node(item.name, item.tiles, item.drawtype, item.mesh, item.box, item.drop)
end
minetest.register_craftitem("autobahn:stripes", {
description = S("Autobahn Stripe"),
inventory_image = 'autobahn_stripes.png',
})
if minetest.global_exists("techage") then
minetest.register_craft({
output = "autobahn:node1 12",
recipe = {
{"techage:sieved_basalt_gravel", "techage:sieved_basalt_gravel", "techage:sieved_basalt_gravel"},
{"techage:sieved_basalt_gravel", "techage:ta3_barrel_bitumen", "techage:sieved_basalt_gravel"},
{"techage:sieved_basalt_gravel", "techage:sieved_basalt_gravel", "techage:sieved_basalt_gravel"},
},
replacements = {{"techage:ta3_barrel_bitumen", "techage:ta3_barrel_empty"}},
})
minetest.register_craft({
output = "autobahn:node1 12",
recipe = {
{"techage:sieved_gravel", "techage:sieved_gravel", "techage:sieved_gravel"},
{"techage:sieved_gravel", "techage:ta3_barrel_bitumen", "techage:sieved_gravel"},
{"techage:sieved_gravel", "techage:sieved_gravel", "techage:sieved_gravel"},
},
replacements = {{"techage:ta3_barrel_bitumen", "techage:ta3_barrel_empty"}},
})
elseif minetest.global_exists("moreblocks") then
minetest.register_craft({
output = "autobahn:node1 4",
recipe = {
{"moreblocks:tar", "moreblocks:tar"},
{"default:cobble", "default:cobble"},
},
})
else
minetest.register_craft({
output = "autobahn:node1 4",
recipe = {
{"autobahn:tar", "autobahn:tar"},
{"default:cobble", "default:cobble"},
},
})
minetest.register_craft({
type = "cooking",
output = "autobahn:tar",
recipe = "default:pine_tree",
})
minetest.register_node("autobahn:tar", {
description = S("Tar"),
tiles = {"autobahn1.png^[colorize:#000000:80"},
is_ground_content = false,
groups = {cracky = 2},
sounds = default.node_sound_stone_defaults(),
})
end
minetest.register_craft({
output = "autobahn:stripes 8",
recipe = {
{"dye:white"},
}
})
minetest.register_craft({
output = "autobahn:node2",
recipe = {
{"", "", "autobahn:stripes"},
{"", "autobahn:node1", ""},
}
})
minetest.register_craft({
output = "autobahn:node3",
recipe = {
{"", "autobahn:stripes", ""},
{"", "autobahn:node1", ""},
}
})
minetest.register_craft({
output = "autobahn:node4",
recipe = {
{"autobahn:stripes", "", ""},
{"", "autobahn:node1", ""},
}
})
minetest.register_craft({
output = "autobahn:node5",
recipe = {
{"", "", ""},
{"autobahn:stripes", "autobahn:node1", ""},
}
})
minetest.register_craft({
output = "autobahn:node6",
recipe = {
{"", "autobahn:stripes", ""},
{"autobahn:stripes", "autobahn:node1", ""},
}
})
if minetest.global_exists("minecart") then
minecart.register_protected_node("autobahn:node1")
minecart.register_protected_node("autobahn:node2")
minecart.register_protected_node("autobahn:node3")
minecart.register_protected_node("autobahn:node4")
minecart.register_protected_node("autobahn:node5")
minecart.register_protected_node("autobahn:node6")
minecart.register_protected_node("autobahn:node11")
minecart.register_protected_node("autobahn:node21")
minecart.register_protected_node("autobahn:node31")
minecart.register_protected_node("autobahn:node41")
minecart.register_protected_node("autobahn:node51")
minecart.register_protected_node("autobahn:node61")
minecart.register_protected_node("autobahn:node12")
minecart.register_protected_node("autobahn:node22")
minecart.register_protected_node("autobahn:node32")
minecart.register_protected_node("autobahn:node42")
minecart.register_protected_node("autobahn:node52")
minecart.register_protected_node("autobahn:node62")
end
-------------------------------------------------------------------------------
-- External API functions
-------------------------------------------------------------------------------
-- Returns true if player is "driving" on the autobahn
-- func autobahn.is_driving(player)
autobahn.is_driving = is_active