198 lines
5.6 KiB
Lua
198 lines
5.6 KiB
Lua
--[[
|
|
|
|
Minecart
|
|
========
|
|
|
|
Copyright (C) 2019-2020 Joachim Stolberg
|
|
|
|
MIT
|
|
See license.txt for more information
|
|
|
|
Cart library functions for node based carts (level 2)
|
|
|
|
]]--
|
|
|
|
-- 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
|
|
local MP = minetest.get_modpath("minecart")
|
|
|
|
local api = dofile(MP.."/cart_lib3.lua")
|
|
|
|
-- Add node, set metadata, and load carge
|
|
local function add_cart(pos, node_name, param2, owner, userID, cargo)
|
|
local ndef = minetest.registered_nodes[node_name]
|
|
local node = minetest.get_node(pos)
|
|
local meta = M(pos)
|
|
local rail = node.name
|
|
minetest.add_node(pos, {name = node_name, param2 = param2})
|
|
meta:set_string("removed_rail", rail)
|
|
meta:set_string("owner", owner)
|
|
meta:set_string("userID", userID)
|
|
meta:set_string("infotext", minetest.get_color_escape_sequence("#FFFF00")..owner..": "..userID)
|
|
if ndef.after_place_node then
|
|
ndef.after_place_node(pos)
|
|
end
|
|
if cargo and ndef.set_cargo then
|
|
ndef.set_cargo(pos, cargo)
|
|
end
|
|
end
|
|
|
|
-- called after punch cart
|
|
local function start_cart(pos, node_name, entity_name, puncher, dir)
|
|
-- Read node metadata
|
|
local ndef = minetest.registered_nodes[node_name]
|
|
if ndef then
|
|
local meta = M(pos)
|
|
local rail = meta:get_string("removed_rail")
|
|
local userID = meta:get_int("userID")
|
|
local cart_owner = meta:get_string("owner")
|
|
local cargo = ndef.get_cargo and ndef.get_cargo(pos) or {}
|
|
-- swap node to rail
|
|
minetest.remove_node(pos)
|
|
minetest.add_node(pos, {name = rail})
|
|
-- Add entity
|
|
local obj = minetest.add_entity(pos, entity_name)
|
|
-- Determine ID
|
|
local myID = api.get_object_id(obj)
|
|
if myID then
|
|
-- Copy metadata to cart entity
|
|
local entity = obj:get_luaentity()
|
|
entity.owner = cart_owner
|
|
entity.userID = userID
|
|
entity.cargo = cargo
|
|
entity.myID = myID
|
|
obj:set_nametag_attributes({color = "#ffff00", text = cart_owner..": "..userID})
|
|
minecart.add_to_monitoring(obj, myID, cart_owner, userID)
|
|
minecart.node_at_station(cart_owner, userID, nil)
|
|
-- punch cart to prevent the stopped handling
|
|
obj:punch(puncher or obj, 1, {
|
|
full_punch_interval = 1.0,
|
|
damage_groups = {fleshy = 1},
|
|
}, dir)
|
|
return myID
|
|
else
|
|
print("Entity has no ID")
|
|
end
|
|
end
|
|
end
|
|
|
|
function api.stop_cart(pos, entity, node_name, param2)
|
|
-- rail buffer reached?
|
|
if api.get_route_key(pos) then
|
|
-- Read entity data
|
|
local owner = entity.owner or ""
|
|
local userID = entity.userID or 0
|
|
local cargo = entity.cargo or {}
|
|
-- Remove entity
|
|
minecart.remove_from_monitoring(entity.myID)
|
|
minecart.node_at_station(owner, userID, pos)
|
|
entity.object:remove()
|
|
-- Add cart node
|
|
add_cart(pos, node_name, param2, owner, userID, cargo)
|
|
end
|
|
-- Stop sound
|
|
if entity.sound_handle then
|
|
minetest.sound_stop(entity.sound_handle)
|
|
entity.sound_handle = nil
|
|
end
|
|
end
|
|
|
|
-- Player adds the node
|
|
function api.add_cart(itemstack, placer, pointed_thing, node_name)
|
|
local owner = placer:get_player_name()
|
|
local meta = placer:get_meta()
|
|
local param2 = minetest.dir_to_facedir(placer:get_look_dir())
|
|
local userID = 0
|
|
local cargo = {}
|
|
|
|
-- Add node
|
|
if carts:is_rail(pointed_thing.under) then
|
|
add_cart(pointed_thing.under, node_name, param2, owner, userID, cargo)
|
|
meta:set_string("cart_pos", P2S(pointed_thing.under))
|
|
elseif carts:is_rail(pointed_thing.above) then
|
|
add_cart(pointed_thing.above, node_name, param2, owner, userID, cargo)
|
|
meta:set_string("cart_pos", P2S(pointed_thing.above))
|
|
else
|
|
return
|
|
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
|
|
|
|
minetest.show_formspec(owner, "minecart:userID_node",
|
|
"size[4,3]" ..
|
|
"label[0,0;Enter cart number:]" ..
|
|
"field[1,1;3,1;userID;;]" ..
|
|
"button_exit[1,2;2,1;exit;Save]")
|
|
|
|
return itemstack
|
|
end
|
|
|
|
function api.node_on_punch(pos, node, puncher, pointed_thing, entity_name, dir)
|
|
local ndef = minetest.registered_nodes[node.name]
|
|
-- Player digs cart by sneak-punch
|
|
if puncher and puncher:get_player_control().sneak then
|
|
api.remove_cart(nil, pos, puncher)
|
|
return
|
|
end
|
|
start_cart(pos, node.name, entity_name, puncher, dir)
|
|
end
|
|
|
|
local function add_to_player_inventory(pos, player, node_name)
|
|
local inv = player:get_inventory()
|
|
if not (creative and creative.is_enabled_for
|
|
and creative.is_enabled_for(player:get_player_name()))
|
|
or not inv:contains_item("main", node_name) then
|
|
local leftover = inv:add_item("main", node_name)
|
|
-- If no room in inventory add a replacement cart to the world
|
|
if not leftover:is_empty() then
|
|
minetest.add_item(pos, leftover)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Player removes the node
|
|
function api.remove_cart(self, pos, player)
|
|
if self then -- cart is still an entity
|
|
add_to_player_inventory(pos, player, self.node_name or "minecart:cart")
|
|
minecart.remove_from_monitoring(self.myID)
|
|
self.object:remove()
|
|
else
|
|
local node = minetest.get_node(pos)
|
|
local ndef = minetest.registered_nodes[node.name]
|
|
if ndef.can_dig and ndef.can_dig(pos, player) then
|
|
add_to_player_inventory(pos, player, node.name)
|
|
node.name = M(pos):get_string("removed_rail")
|
|
if node.name == "" then
|
|
node.name = "carts:rail"
|
|
end
|
|
minetest.remove_node(pos)
|
|
minetest.add_node(pos, node)
|
|
end
|
|
end
|
|
end
|
|
|
|
function api.load_cargo()
|
|
-- nothing to load
|
|
end
|
|
|
|
function api.unload_cargo()
|
|
-- nothing to unload
|
|
end
|
|
|
|
function api.add_cargo_to_player_inv()
|
|
-- nothing to do
|
|
end
|
|
|
|
-- needed by minecart.punch_cart and node carts
|
|
minecart.node_on_punch = api.node_on_punch
|
|
|
|
return api |