150 lines
5.0 KiB
Lua
150 lines
5.0 KiB
Lua
--[[
|
|
|
|
Minecart
|
|
========
|
|
|
|
Copyright (C) 2019-2021 Joachim Stolberg
|
|
|
|
MIT
|
|
See license.txt for more information
|
|
|
|
]]--
|
|
|
|
-- for lazy programmers
|
|
local M = minetest.get_meta
|
|
local S = minecart.S
|
|
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
|
local S2P = minetest.string_to_pos
|
|
|
|
function minecart.get_nodecart_nearby(pos, param2, radius)
|
|
local pos2 = param2 and vector.add(pos, minecart.param2_to_dir(param2)) or pos
|
|
local pos3 = minetest.find_node_near(pos2, radius or 0.5, minecart.lCartNodeNames, true)
|
|
if pos3 then
|
|
return pos3, minetest.get_node(pos3)
|
|
end
|
|
end
|
|
|
|
-- Convert node to entity and start cart
|
|
function minecart.start_nodecart(pos, node_name, puncher, punch_dir)
|
|
local owner = M(pos):get_string("owner")
|
|
local userID = M(pos):get_int("userID")
|
|
-- check if valid cart
|
|
if not minecart.monitoring_valid_cart(owner, userID, pos, node_name) then
|
|
--print("Lost cart", owner, userID, P2S(pos), node_name)
|
|
local entity_name = minecart.tNodeNames[node_name]
|
|
if owner ~= "" and userID ~= "" and entity_name then
|
|
minecart.monitoring_add_cart(owner, userID, pos, node_name, entity_name)
|
|
else
|
|
M(pos):set_string("infotext",
|
|
minetest.get_color_escape_sequence("#FFFF00") .. owner .. ": 0")
|
|
return
|
|
end
|
|
end
|
|
-- Only the owner or a noplayer can start the cart, but owner has to be online
|
|
if minecart.is_owner(puncher, owner) and minetest.get_player_by_name(owner) and
|
|
userID ~= 0 then
|
|
local entity_name = minecart.tNodeNames[node_name]
|
|
local obj = minecart.node_to_entity(pos, node_name, entity_name)
|
|
if obj then
|
|
local entity = obj:get_luaentity()
|
|
local facedir
|
|
|
|
if puncher then
|
|
local yaw = puncher:get_look_horizontal()
|
|
entity.object:set_rotation({x = 0, y = yaw, z = 0})
|
|
local dir = minetest.yaw_to_dir(yaw)
|
|
facedir = minetest.dir_to_facedir(dir)
|
|
elseif punch_dir then
|
|
local yaw = minetest.dir_to_yaw(punch_dir)
|
|
entity.object:set_rotation({x = 0, y = yaw, z = 0})
|
|
facedir = minetest.dir_to_facedir(punch_dir)
|
|
end
|
|
minecart.start_entitycart(entity, pos, facedir or 0)
|
|
end
|
|
end
|
|
end
|
|
|
|
function minecart.show_formspec(pos, clicker)
|
|
local owner = M(pos):get_string("owner")
|
|
if minecart.is_owner(clicker, owner) then
|
|
clicker:get_meta():set_string("cart_pos", P2S(pos))
|
|
minetest.show_formspec(owner, "minecart:userID_node",
|
|
"size[4,3]" ..
|
|
"label[0,0;" .. S("Enter cart number") .. ":]" ..
|
|
"field[1,1;3,1;userID;;]" ..
|
|
"button_exit[1,2;2,1;exit;" .. S("Save") .. "]")
|
|
end
|
|
end
|
|
|
|
-- Player places the node
|
|
function minecart.on_nodecart_place(itemstack, placer, pointed_thing)
|
|
local node_name = itemstack:get_name()
|
|
local param2 = minetest.dir_to_facedir(placer:get_look_dir())
|
|
local owner = placer:get_player_name()
|
|
|
|
-- Add node
|
|
if minecart.is_rail(pointed_thing.under) then
|
|
minecart.add_nodecart(pointed_thing.under, node_name, param2, {}, owner, 0)
|
|
placer:get_meta():set_string("cart_pos", P2S(pointed_thing.under))
|
|
minecart.show_formspec(pointed_thing.under, placer)
|
|
elseif minecart.is_rail(pointed_thing.above) then
|
|
minecart.add_nodecart(pointed_thing.above, node_name, param2, {}, owner, 0)
|
|
placer:get_meta():set_string("cart_pos", P2S(pointed_thing.above))
|
|
minecart.show_formspec(pointed_thing.above, placer)
|
|
else
|
|
return itemstack
|
|
end
|
|
|
|
minetest.sound_play({name = "default_place_node_metal", gain = 0.5},
|
|
{pos = pointed_thing.above})
|
|
|
|
if not (creative and creative.is_enabled_for
|
|
and creative.is_enabled_for(placer:get_player_name())) then
|
|
itemstack:take_item()
|
|
end
|
|
|
|
return itemstack
|
|
end
|
|
|
|
-- Start the node cart (or dig by shift+leftclick)
|
|
function minecart.on_nodecart_punch(pos, node, puncher, pointed_thing)
|
|
--print("on_nodecart_punch")
|
|
local owner = M(pos):get_string("owner")
|
|
local userID = M(pos):get_int("userID")
|
|
if minecart.is_owner(puncher, owner) then
|
|
if puncher:get_player_control().sneak then
|
|
local ndef = minetest.registered_nodes[node.name]
|
|
if not ndef.has_cargo or not ndef.has_cargo(pos) then
|
|
minecart.remove_nodecart(pos)
|
|
minecart.add_node_to_player_inventory(pos, puncher, node.name)
|
|
minecart.monitoring_remove_cart(owner, userID)
|
|
end
|
|
else
|
|
minecart.start_nodecart(pos, node.name, puncher)
|
|
end
|
|
end
|
|
end
|
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname == "minecart:userID_node" then
|
|
if fields.exit or fields.key_enter == "true" then
|
|
local cart_pos = S2P(player:get_meta():get_string("cart_pos"))
|
|
local owner = M(cart_pos):get_string("owner")
|
|
if minecart.is_owner(player, owner) then
|
|
local userID = tonumber(fields.userID) or 0
|
|
if minecart.userID_available(owner, userID) then
|
|
M(cart_pos):set_int("userID", userID)
|
|
M(cart_pos):set_string("infotext",
|
|
minetest.get_color_escape_sequence("#FFFF00") ..
|
|
player:get_player_name() .. ": " .. userID)
|
|
local node = minetest.get_node(cart_pos)
|
|
local entity_name = minecart.tNodeNames[node.name]
|
|
minecart.monitoring_add_cart(owner, userID, cart_pos, node.name, entity_name)
|
|
end
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
return false
|
|
end)
|