Accept mincart carts for the move controller

This commit is contained in:
Joachim Stolberg 2023-02-05 18:14:01 +01:00
parent 39cbeea15e
commit 46d2ae91aa
2 changed files with 49 additions and 31 deletions

View File

@ -37,7 +37,8 @@ local function rotate(v, yaw)
return {x = v.x * cosyaw - v.z * sinyaw, y = v.y, z = v.x * sinyaw + v.z * cosyaw} return {x = v.x * cosyaw - v.z * sinyaw, y = v.y, z = v.x * sinyaw + v.z * cosyaw}
end end
local function set_node(item) -- playername is needed for carts, to attach the player to the cart entity
local function set_node(item, playername)
local dest_pos = item.dest_pos local dest_pos = item.dest_pos
local name = item.name or "air" local name = item.name or "air"
local param2 = item.param2 or 0 local param2 = item.param2 or 0
@ -49,7 +50,11 @@ local function set_node(item)
nvm.running = false nvm.running = false
M(item.base_pos):set_string("status", S("Stopped")) M(item.base_pos):set_string("status", S("Stopped"))
if ndef1 and ndef2 then if ndef1 and ndef2 then
if ndef2.buildable_to then if minecart.is_cart(name) then
local player = playername and minetest.get_player_by_name(playername)
minecart.place_and_start_cart(dest_pos, {name = name, param2 = param2}, item.cartdef, player)
return
elseif ndef2.buildable_to then
local meta = M(dest_pos) local meta = M(dest_pos)
minetest.set_node(dest_pos, {name=name, param2=param2}) minetest.set_node(dest_pos, {name=name, param2=param2})
meta:from_table(item.metadata or {}) meta:from_table(item.metadata or {})
@ -294,7 +299,7 @@ local function detach_player(player)
end end
-- Attach player/mob to given parent object (block) -- Attach player/mob to given parent object (block)
local function attach_single_object(parent, obj, dir) local function attach_single_object(parent, obj, distance)
local self = parent:get_luaentity() local self = parent:get_luaentity()
local res = obj:get_attach() local res = obj:get_attach()
if not res then -- not already attached if not res then -- not already attached
@ -305,20 +310,20 @@ local function attach_single_object(parent, obj, dir)
yaw = obj:get_rotation().y yaw = obj:get_rotation().y
end end
-- store for later use -- store for later use
local offs = table.copy(dir) local offs = table.copy(distance)
-- Calc entity rotation, which is relative to the parent's rotation -- Calc entity rotation, which is relative to the parent's rotation
local rot = parent:get_rotation() local rot = parent:get_rotation()
if self.param2 >= 20 then if self.param2 >= 20 then
dir = rotate(dir, 2 * math.pi - rot.y) distance = rotate(distance, 2 * math.pi - rot.y)
dir.y = -dir.y distance.y = -distance.y
dir.x = -dir.x distance.x = -distance.x
rot.y = rot.y - yaw rot.y = rot.y - yaw
elseif self.param2 < 4 then elseif self.param2 < 4 then
dir = rotate(dir, 2 * math.pi - rot.y) distance = rotate(distance, 2 * math.pi - rot.y)
rot.y = rot.y - yaw rot.y = rot.y - yaw
end end
dir = vector.multiply(dir, 29) distance = vector.multiply(distance, 29)
obj:set_attach(parent, "", dir, vector.multiply(rot, 180 / math.pi)) obj:set_attach(parent, "", distance, vector.multiply(rot, 180 / math.pi))
obj:set_properties({visual_size = {x=2.9, y=2.9}}) obj:set_properties({visual_size = {x=2.9, y=2.9}})
if obj:is_player() then if obj:is_player() then
if lock_player(obj) then if lock_player(obj) then
@ -332,19 +337,21 @@ end
-- Attach all objects around to the parent object -- Attach all objects around to the parent object
-- offs is the search/attach position offset -- offs is the search/attach position offset
local function attach_objects(pos, offs, parent, yoffs) -- distance (optional) is the attach distance to the center of the entity
local function attach_objects(pos, offs, parent, yoffs, distance)
local pos1 = vector.add(pos, offs) local pos1 = vector.add(pos, offs)
for _, obj in pairs(minetest.get_objects_inside_radius(pos1, 0.9)) do for _, obj in pairs(minetest.get_objects_inside_radius(pos1, 0.9)) do
local dir = vector.subtract(obj:get_pos(), pos) -- keep relative object position
distance = distance or vector.subtract(obj:get_pos(), pos)
local entity = obj:get_luaentity() local entity = obj:get_luaentity()
if entity then if entity then
local mod = entity.name:gmatch("(.-):")() local mod = entity.name:gmatch("(.-):")()
if techage.RegisteredMobsMods[mod] then if techage.RegisteredMobsMods[mod] then
dir.y = dir.y + yoffs distance.y = distance.y + yoffs
attach_single_object(parent, obj, dir) attach_single_object(parent, obj, distance)
end end
elseif obj:is_player() then elseif obj:is_player() then
attach_single_object(parent, obj, dir) attach_single_object(parent, obj, distance)
end end
end end
end end
@ -380,10 +387,11 @@ end
local function entity_to_node(pos, obj) local function entity_to_node(pos, obj)
local self = obj:get_luaentity() local self = obj:get_luaentity()
if self and self.item then if self and self.item then
local playername = self.players and self.players[1] and self.players[1].name
detach_objects(pos, self) detach_objects(pos, self)
monitoring_del_entity(self.item) monitoring_del_entity(self.item)
minetest.after(0.1, obj.remove, obj) minetest.after(0.1, obj.remove, obj)
set_node(self.item) set_node(self.item, playername)
end end
end end
@ -392,9 +400,12 @@ end
-- * start_pos and dest_pos are entity positions -- * start_pos and dest_pos are entity positions
local function node_to_entity(base_pos, start_pos, dest_pos) local function node_to_entity(base_pos, start_pos, dest_pos)
local meta = M(start_pos) local meta = M(start_pos)
local node, metadata local node, metadata, cartdef
if meta:contains("ta_move_block") then node = techage.get_node_lvm(start_pos)
if minecart.is_cart(node.name) then
cartdef = minecart.remove_cart(start_pos)
elseif meta:contains("ta_move_block") then
-- Move-block stored as metadata -- Move-block stored as metadata
node = minetest.deserialize(meta:get_string("ta_move_block")) node = minetest.deserialize(meta:get_string("ta_move_block"))
metadata = {} metadata = {}
@ -424,6 +435,7 @@ local function node_to_entity(base_pos, start_pos, dest_pos)
metadata = metadata or {}, metadata = metadata or {},
dest_pos = dest_pos, dest_pos = dest_pos,
base_pos = base_pos, base_pos = base_pos,
cartdef = cartdef,
} }
monitoring_add_entity(self.item) monitoring_add_entity(self.item)
@ -432,7 +444,7 @@ local function node_to_entity(base_pos, start_pos, dest_pos)
self.entities = {} self.entities = {}
-- Prepare for path walk -- Prepare for path walk
self.path_idx = 1 self.path_idx = 1
return obj return obj, self.item.cartdef ~= nil
end end
end end
@ -543,9 +555,11 @@ local function is_valid_dest(pos)
end end
local function is_simple_node(pos) local function is_simple_node(pos)
local node =techage.get_node_lvm(pos) local node = techage.get_node_lvm(pos)
local ndef = minetest.registered_nodes[node.name] if not minecart.is_rail(pos, node) then
return not techage.is_air_like(node.name) and techage.can_dig_node(node.name, ndef) local ndef = minetest.registered_nodes[node.name]
return not techage.is_air_like(node.name) and techage.can_dig_node(node.name, ndef) or minecart.is_cart(node.name)
end
end end
-- Move node from 'pos1' to the destination, calculated by means of 'lmove' -- Move node from 'pos1' to the destination, calculated by means of 'lmove'
@ -562,14 +576,18 @@ local function move_node(pos, meta, pos1, lmove, max_speed, height)
if pos2 then if pos2 then
local dir = determine_dir(pos1, pos2) local dir = determine_dir(pos1, pos2)
local obj = node_to_entity(pos, pos1, dest_pos) local obj, is_cart = node_to_entity(pos, pos1, dest_pos)
if obj then if obj then
local offs = {x=0, y=height or 1, z=0} if is_cart then
attach_objects(pos1, offs, obj, yoffs) attach_objects(pos1, 0, obj, yoffs, {x = 0, y = -0.2, z = 0})
if dir.y == 0 then else
if (dir.x ~= 0 and dir.z == 0) or (dir.x == 0 and dir.z ~= 0) then local offs = {x=0, y=height or 1, z=0}
attach_objects(pos1, dir, obj, yoffs) attach_objects(pos1, offs, obj, yoffs)
if dir.y == 0 then
if (dir.x ~= 0 and dir.z == 0) or (dir.x == 0 and dir.z ~= 0) then
attach_objects(pos1, dir, obj, yoffs)
end
end end
end end
local self = obj:get_luaentity() local self = obj:get_luaentity()

View File

@ -13,7 +13,7 @@
techage = {} techage = {}
-- Version for compatibility checks, see readme.md/history -- Version for compatibility checks, see readme.md/history
techage.version = 1.10 techage.version = 1.11
if minetest.global_exists("tubelib") then if minetest.global_exists("tubelib") then
minetest.log("error", "[techage] Techage can't be used together with the mod tubelib!") minetest.log("error", "[techage] Techage can't be used together with the mod tubelib!")
@ -27,8 +27,8 @@ elseif minetest.global_exists("techpack") then
elseif minetest.global_exists("tubelib2") and tubelib2.version < 2.2 then elseif minetest.global_exists("tubelib2") and tubelib2.version < 2.2 then
minetest.log("error", "[techage] Techage requires tubelib2 version 2.2 or newer!") minetest.log("error", "[techage] Techage requires tubelib2 version 2.2 or newer!")
return return
elseif minetest.global_exists("minecart") and minecart.version < 2.03 then elseif minetest.global_exists("minecart") and minecart.version < 2.04 then
minetest.log("error", "[techage] Techage requires minecart version 2.03 or newer!") minetest.log("error", "[techage] Techage requires minecart version 2.04 or newer!")
return return
elseif minetest.global_exists("lcdlib") and lcdlib.version < 1.01 then elseif minetest.global_exists("lcdlib") and lcdlib.version < 1.01 then
minetest.log("error", "[techage] Techage requires lcdlib version 1.01 or newer!") minetest.log("error", "[techage] Techage requires lcdlib version 1.01 or newer!")