Complete rewrite of minecart movement that resolves MineClone2/MineClone2#2446 and MineClone2/MineClone2#247 (comment) but has a bug where carts will synchronize movements that I am still investigating
This commit is contained in:
parent
960309462f
commit
6de06945c1
|
@ -141,5 +141,5 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
|
||||||
return cur
|
return cur
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return vector.new(0,0,0) --{x=0, y=0, z=0}
|
return vector.new(0,0,0)
|
||||||
end
|
end
|
||||||
|
|
|
@ -207,9 +207,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
_old_pos = nil,
|
_old_pos = nil,
|
||||||
_old_vel = {x=0, y=0, z=0},
|
_old_vel = {x=0, y=0, z=0},
|
||||||
_old_switch = 0,
|
_old_switch = 0,
|
||||||
_staticdata = {
|
_staticdata = nil,
|
||||||
railtype = nil,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function cart:on_activate(staticdata, dtime_s)
|
function cart:on_activate(staticdata, dtime_s)
|
||||||
|
@ -221,6 +219,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
data.railtype = data._railtype
|
data.railtype = data._railtype
|
||||||
data._railtype = nil
|
data._railtype = nil
|
||||||
end
|
end
|
||||||
|
-- Fix up types
|
||||||
|
data.dir = vector.new(data.dir)
|
||||||
|
|
||||||
self._staticdata = data
|
self._staticdata = data
|
||||||
end
|
end
|
||||||
|
@ -237,18 +237,28 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
end
|
end
|
||||||
|
|
||||||
function cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
function cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
||||||
local pos = self.object:get_pos()
|
local staticdata = self._staticdata
|
||||||
if not self._staticdata.railtype then
|
local pos = staticdata.connected_at
|
||||||
local node = minetest.get_node(vector.floor(pos)).name
|
if not pos then
|
||||||
self._staticdata.railtype = minetest.get_item_group(node, "connect_to_raillike")
|
print("TODO: handle detached cart behavior")
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Fix railtype field
|
||||||
|
if not staticdata.railtype then
|
||||||
|
local node = minetest.get_node(vector.floor(pos)).name
|
||||||
|
staticdata.railtype = minetest.get_item_group(node, "connect_to_raillike")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Handle punches by something other than the player
|
||||||
if not puncher or not puncher:is_player() then
|
if not puncher or not puncher:is_player() then
|
||||||
local cart_dir = mcl_minecarts:get_rail_direction(pos, {x=1, y=0, z=0}, nil, nil, self._staticdata.railtype)
|
local cart_dir = mcl_minecarts:get_rail_direction(pos, {x=1, y=0, z=0}, nil, nil, staticdata.railtype)
|
||||||
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
|
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
mcl_minecarts:set_velocity(self, cart_dir)
|
|
||||||
|
staticdata.dir = cart_dir
|
||||||
|
self._punched = true
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -288,6 +298,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Handle player punches
|
||||||
local vel = self.object:get_velocity()
|
local vel = self.object:get_velocity()
|
||||||
if puncher:get_player_name() == self._driver then
|
if puncher:get_player_name() == self._driver then
|
||||||
if math.abs(vel.x + vel.z) > 7 then
|
if math.abs(vel.x + vel.z) > 7 then
|
||||||
|
@ -297,206 +308,168 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
|
|
||||||
local punch_dir = mcl_minecarts:velocity_to_dir(puncher:get_look_dir())
|
local punch_dir = mcl_minecarts:velocity_to_dir(puncher:get_look_dir())
|
||||||
punch_dir.y = 0
|
punch_dir.y = 0
|
||||||
|
|
||||||
local cart_dir = mcl_minecarts:get_rail_direction(pos, punch_dir, nil, nil, self._staticdata.railtype)
|
local cart_dir = mcl_minecarts:get_rail_direction(pos, punch_dir, nil, nil, self._staticdata.railtype)
|
||||||
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
|
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
staticdata.dir = cart_dir
|
||||||
|
|
||||||
time_from_last_punch = math.min(time_from_last_punch, tool_capabilities.full_punch_interval)
|
time_from_last_punch = math.min(time_from_last_punch, tool_capabilities.full_punch_interval)
|
||||||
local f = 3 * (time_from_last_punch / tool_capabilities.full_punch_interval)
|
local f = 3 * (time_from_last_punch / tool_capabilities.full_punch_interval)
|
||||||
|
|
||||||
mcl_minecarts:set_velocity(self, cart_dir, f)
|
-- Perform acceleration here
|
||||||
|
staticdata.velocity = (staticdata.velocity or 0 ) + f
|
||||||
|
local max_vel = mcl_minecarts.speed_max
|
||||||
|
if staticdata.velocity > max_vel then
|
||||||
|
staticdata.velocity = max_vel
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
cart.on_activate_by_rail = on_activate_by_rail
|
cart.on_activate_by_rail = on_activate_by_rail
|
||||||
|
|
||||||
local passenger_attach_position = vector.new(0, -1.75, 0)
|
local passenger_attach_position = vector.new(0, -1.75, 0)
|
||||||
|
|
||||||
local function do_movement_step( self )
|
local function do_movement_step(self, distance)
|
||||||
local vel = self.object:get_velocity()
|
local staticdata = self._staticdata
|
||||||
local pos, rou_pos, node = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
local update = {}
|
local dir = staticdata.dir or vector.new(1,0,0)
|
||||||
|
dir = vector.new(dir)
|
||||||
|
|
||||||
local dir, last_switch = nil, nil
|
-- Calculate raw location
|
||||||
if not pos then
|
local next_dir,last_switch = mcl_minecarts:get_rail_direction(pos, dir, nil, nil, staticdata.railtype)
|
||||||
pos = self.object:get_pos()
|
next_dir = vector.new(next_dir) -- Needed to isolate the carts from one another
|
||||||
|
local next_pos = vector.new(pos + next_dir * distance)
|
||||||
|
|
||||||
|
-- Fix up position
|
||||||
|
if next_dir.x == 0 then next_pos.x = math.floor(next_pos.x+0.5) end
|
||||||
|
if next_dir.y == 0 then next_pos.y = math.floor(next_pos.y+0.5) end
|
||||||
|
if next_dir.z == 0 then next_pos.z = math.floor(next_pos.z+0.5) end
|
||||||
|
|
||||||
|
-- Direction flipped, stop
|
||||||
|
if next_dir == dir * -1 then
|
||||||
|
print("Stopping cart")
|
||||||
|
-- TODO: detach the cart if there isn't a stop after the rail
|
||||||
|
staticdata.velocity = 0
|
||||||
|
next_pos = vector.round(next_pos + dir)
|
||||||
end
|
end
|
||||||
if self._old_pos and not self._punched then
|
|
||||||
local flo_pos = vector.floor(pos)
|
-- Update cart orientation
|
||||||
local flo_old = vector.floor(self._old_pos)
|
local yaw = 0
|
||||||
if vector.equals(flo_pos, flo_old) and (not has_fuel) then
|
if next_dir.x < 0 then
|
||||||
return
|
yaw = 0.5
|
||||||
-- Prevent querying the same node over and over again
|
elseif next_dir.x > 0 then
|
||||||
|
yaw = 1.5
|
||||||
|
elseif dir.z < 0 then
|
||||||
|
yaw = 1
|
||||||
|
end
|
||||||
|
self.object:set_yaw( yaw * math.pi )
|
||||||
|
|
||||||
|
-- Update cart position
|
||||||
|
local next_pos_rounded = vector.round(next_pos)
|
||||||
|
staticdata.connected_at = next_pos_rounded
|
||||||
|
staticdata.dir = next_dir
|
||||||
|
self.object:move_to(next_pos)
|
||||||
|
|
||||||
|
-- Handle track interactions
|
||||||
|
local pos_rounded = vector.round(pos)
|
||||||
|
if pos_rounded ~= next_pos_rounded then
|
||||||
|
local old_node_name = minetest.get_node(pos_rounded).name
|
||||||
|
local old_node_def = minetest.registered_nodes[old_node_name]
|
||||||
|
if old_node_def._mcl_minecarts_on_leave then
|
||||||
|
old_node_def._mcl_minecarts_on_leave( pos_rounded, self )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not rou_pos then
|
local new_node_name = minetest.get_node(next_pos_rounded).name
|
||||||
rou_pos = vector.round(pos)
|
local new_node_def = minetest.registered_nodes[new_node_name]
|
||||||
end
|
if new_node_def._mcl_minecarts_on_enter then
|
||||||
local rou_old = vector.round(self._old_pos)
|
new_node_def._mcl_minecarts_on_enter( next_pos_rounded, self )
|
||||||
if not node then
|
|
||||||
node = minetest.get_node(rou_pos)
|
|
||||||
end
|
|
||||||
local node_old = minetest.get_node(rou_old)
|
|
||||||
|
|
||||||
-- Update detector rails
|
|
||||||
if node.name == "mcl_minecarts:detector_rail" then
|
|
||||||
local newnode = {name="mcl_minecarts:detector_rail_on", param2 = node.param2}
|
|
||||||
minetest.swap_node(rou_pos, newnode)
|
|
||||||
mesecon.receptor_on(rou_pos)
|
|
||||||
end
|
|
||||||
if node_old.name == "mcl_minecarts:detector_rail_on" then
|
|
||||||
local newnode = {name="mcl_minecarts:detector_rail", param2 = node_old.param2}
|
|
||||||
minetest.swap_node(rou_old, newnode)
|
|
||||||
mesecon.receptor_off(rou_old)
|
|
||||||
end
|
|
||||||
-- Activate minecart if on activator rail
|
|
||||||
if node_old.name == "mcl_minecarts:activator_rail_on" and self.on_activate_by_rail then
|
|
||||||
self:on_activate_by_rail()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Stop cart if velocity vector flips
|
--print("pos="..tostring(next_pos)..",dir="..tostring(next_dir)..",staticdata="..tostring(staticdata))
|
||||||
if self._old_vel and self._old_vel.y == 0 and
|
end
|
||||||
(self._old_vel.x * vel.x < 0 or self._old_vel.z * vel.z < 0) then
|
|
||||||
self._old_vel = {x = 0, y = 0, z = 0}
|
|
||||||
self._old_pos = pos
|
|
||||||
self.object:set_velocity(vector.new())
|
|
||||||
self.object:set_acceleration(vector.new())
|
|
||||||
return
|
|
||||||
end
|
|
||||||
self._old_vel = vector.new(vel)
|
|
||||||
|
|
||||||
if self._old_pos then
|
local function process_acceleration(self, timestep)
|
||||||
local diff = vector.subtract(self._old_pos, pos)
|
local staticdata = self._staticdata
|
||||||
for _,v in ipairs({"x","y","z"}) do
|
|
||||||
if math.abs(diff[v]) > 1.1 then
|
|
||||||
local expected_pos = vector.add(self._old_pos, self._old_dir)
|
|
||||||
dir, last_switch = mcl_minecarts:get_rail_direction(pos, self._old_dir, ctrl, self._old_switch, self._staticdata.railtype)
|
|
||||||
|
|
||||||
if vector.equals(dir, {x=0, y=0, z=0}) then
|
local pos = self.object:get_pos()
|
||||||
dir = false
|
local node_name = minetest.get_node(pos).name
|
||||||
pos = vector.new(expected_pos)
|
local node_def = minetest.registered_nodes[node_name]
|
||||||
update.pos = true
|
|
||||||
end
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if vel.y == 0 then
|
if self._go_forward then
|
||||||
for _,v in ipairs({"x", "z"}) do
|
self._acceleration = 2
|
||||||
if vel[v] ~= 0 and math.abs(vel[v]) < 0.9 then
|
elseif self._brake then
|
||||||
vel[v] = 0
|
self._acceleration = -1.5
|
||||||
update.vel = true
|
elseif self._punched then
|
||||||
end
|
self._acceleration = 2
|
||||||
end
|
elseif self._fueltime and self._fueltime > 0 then
|
||||||
end
|
self._acceleration = 0.6
|
||||||
|
|
||||||
local cart_dir = mcl_minecarts:velocity_to_dir(vel)
|
|
||||||
local max_vel = mcl_minecarts.speed_max
|
|
||||||
if not dir then
|
|
||||||
dir, last_switch = mcl_minecarts:get_rail_direction(pos, cart_dir, ctrl, self._old_switch, self._staticdata.railtype)
|
|
||||||
end
|
|
||||||
|
|
||||||
local new_acc = {x=0, y=0, z=0}
|
|
||||||
if vector.equals(dir, {x=0, y=0, z=0}) and not has_fuel then
|
|
||||||
vel = {x=0, y=0, z=0}
|
|
||||||
update.vel = true
|
|
||||||
else
|
else
|
||||||
-- If the direction changed
|
self._acceleration = node_def._rail_acceleration or -0.4
|
||||||
if dir.x ~= 0 and self._old_dir.z ~= 0 then
|
|
||||||
vel.x = dir.x * math.abs(vel.z)
|
|
||||||
vel.z = 0
|
|
||||||
pos.z = math.floor(pos.z + 0.5)
|
|
||||||
update.pos = true
|
|
||||||
end
|
|
||||||
if dir.z ~= 0 and self._old_dir.x ~= 0 then
|
|
||||||
vel.z = dir.z * math.abs(vel.x)
|
|
||||||
vel.x = 0
|
|
||||||
pos.x = math.floor(pos.x + 0.5)
|
|
||||||
update.pos = true
|
|
||||||
end
|
|
||||||
-- Up, down?
|
|
||||||
if dir.y ~= self._old_dir.y then
|
|
||||||
vel.y = dir.y * math.abs(vel.x + vel.z)
|
|
||||||
pos = vector.round(pos)
|
|
||||||
update.pos = true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Slow down or speed up
|
|
||||||
local acc = dir.y * -1.8
|
|
||||||
local friction = 0.4
|
|
||||||
local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
|
|
||||||
local speed_mod = ndef and ndef._rail_acceleration
|
|
||||||
|
|
||||||
acc = acc - friction
|
|
||||||
|
|
||||||
if has_fuel then
|
|
||||||
acc = acc + 0.6
|
|
||||||
end
|
|
||||||
|
|
||||||
if speed_mod and speed_mod ~= 0 then
|
|
||||||
acc = acc + speed_mod + friction
|
|
||||||
end
|
|
||||||
|
|
||||||
new_acc = vector.multiply(dir, acc)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self.object:set_acceleration(new_acc)
|
if self._acceleration > 0 and staticdata.velocity < 0.1 then
|
||||||
self._old_pos = vector.new(pos)
|
staticdata.velocity = 0.1
|
||||||
self._old_dir = vector.new(dir)
|
end
|
||||||
self._old_switch = last_switch
|
|
||||||
|
|
||||||
-- Limits
|
if math.abs(self._acceleration) > 0.1 then
|
||||||
for _,v in ipairs({"x","y","z"}) do
|
staticdata.velocity = ( staticdata.velocity or 0 ) + self._acceleration * timestep
|
||||||
if math.abs(vel[v]) > max_vel then
|
local max_vel = mcl_minecarts.speed_max
|
||||||
vel[v] = mcl_minecarts:get_sign(vel[v]) * max_vel
|
if staticdata.velocity > max_vel then
|
||||||
new_acc[v] = 0
|
staticdata.velocity = max_vel
|
||||||
update.vel = true
|
elseif staticdata.velocity < 0.1 then
|
||||||
|
staticdata.velocity = 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if false and staticdata.velocity > 0 then
|
||||||
|
print( "acceleration="..tostring(self._acceleration)..",velocity="..tostring(staticdata.velocity)..
|
||||||
|
",timestep="..tostring(timestep))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if update.pos or self._punched then
|
|
||||||
local yaw = 0
|
local function do_movement( self, dtime )
|
||||||
if dir.x < 0 then
|
local staticdata = self._staticdata
|
||||||
yaw = 0.5
|
|
||||||
elseif dir.x > 0 then
|
local total_distance = dtime * ( staticdata.velocity or 0 )
|
||||||
yaw = 1.5
|
local remaining_distance = total_distance
|
||||||
elseif dir.z < 0 then
|
local max_step_distance = 0.5
|
||||||
yaw = 1
|
local steps = math.ceil(total_distance / max_step_distance )
|
||||||
|
|
||||||
|
process_acceleration(self,dtime)
|
||||||
|
|
||||||
|
for i = 1,steps do
|
||||||
|
local step_distance = max_step_distance
|
||||||
|
if remaining_distance < max_step_distance then
|
||||||
|
step_distance = remaining_distance
|
||||||
|
remaining_distance = 0
|
||||||
|
else
|
||||||
|
remaining_distance = remaining_distance - max_step_distance
|
||||||
end
|
end
|
||||||
self.object:set_yaw(yaw * math.pi)
|
|
||||||
|
if i ~= 1 then
|
||||||
|
-- Go faster/slower
|
||||||
|
local timestep = dtime * step_distance / total_distance
|
||||||
|
process_acceleration(self, timestep)
|
||||||
|
end
|
||||||
|
|
||||||
|
do_movement_step(self,step_distance)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self._punched then
|
-- Clear punched flag now that movement for this step has been completed
|
||||||
self._punched = false
|
self._punched = false
|
||||||
end
|
|
||||||
|
|
||||||
if not (update.vel or update.pos) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local anim = {x=0, y=0}
|
|
||||||
if dir.y == -1 then
|
|
||||||
anim = {x=1, y=1}
|
|
||||||
elseif dir.y == 1 then
|
|
||||||
anim = {x=2, y=2}
|
|
||||||
end
|
|
||||||
self.object:set_animation(anim, 1, 0)
|
|
||||||
|
|
||||||
self.object:set_velocity(vel)
|
|
||||||
if update.pos then
|
|
||||||
self.object:set_pos(pos)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function cart:on_step(dtime)
|
function cart:on_step(dtime)
|
||||||
hopper_take_item(self, dtime)
|
hopper_take_item(self, dtime)
|
||||||
|
local staticdata = self._staticdata
|
||||||
|
|
||||||
local vel = self.object:get_velocity()
|
|
||||||
local pos, rou_pos, node = self.object:get_pos()
|
local pos, rou_pos, node = self.object:get_pos()
|
||||||
local update = {}
|
local update = {}
|
||||||
|
local acceleration = 0
|
||||||
|
|
||||||
-- Controls
|
-- Controls
|
||||||
local ctrl, player = nil, nil
|
local ctrl, player = nil, nil
|
||||||
|
@ -509,6 +482,10 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
detach_driver(self)
|
detach_driver(self)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Experimental controls
|
||||||
|
self._go_forward = ctrl.up
|
||||||
|
self._brake = ctrl.down
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Give achievement when player reached a distance of 1000 nodes from the start position
|
-- Give achievement when player reached a distance of 1000 nodes from the start position
|
||||||
|
@ -517,15 +494,9 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Go faster when punched
|
do_movement(self, dtime)
|
||||||
if self._punched then
|
|
||||||
vel = vector.add(vel, self._velocity)
|
|
||||||
self.object:set_velocity(vel)
|
|
||||||
self._old_dir.y = 0
|
|
||||||
elseif vector.equals(vel, {x=0, y=0, z=0}) and (not has_fuel) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
|
-- TODO: move this into do_movement_step
|
||||||
-- Drop minecart if it collides with a cactus node
|
-- Drop minecart if it collides with a cactus node
|
||||||
local r = 0.6
|
local r = 0.6
|
||||||
for _, node_pos in pairs({{r, 0}, {0, r}, {-r, 0}, {0, -r}}) do
|
for _, node_pos in pairs({{r, 0}, {0, r}, {-r, 0}, {0, -r}}) do
|
||||||
|
@ -539,20 +510,6 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Debug
|
|
||||||
if false then
|
|
||||||
local node = minetest.get_node(pos).name
|
|
||||||
local dist = 0
|
|
||||||
if pos and self._old_pos then
|
|
||||||
dist = vector.distance(pos,self._old_pos)
|
|
||||||
end
|
|
||||||
if dist > 1.5 then
|
|
||||||
print("pos="..tostring(pos)..",dist="..tostring(dist)..",node="..tostring(node)..",old_pos="..
|
|
||||||
tostring(self._old_pos)..",vel="..tostring(vel))
|
|
||||||
end
|
|
||||||
-- Rail jumps can occur when dist > 1.5, because the cart can skip over a gap in track
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Grab mob
|
-- Grab mob
|
||||||
if math.random(1,20) > 15 and not self._passenger then
|
if math.random(1,20) > 15 and not self._passenger then
|
||||||
if self.name == "mcl_minecarts:minecart" then
|
if self.name == "mcl_minecarts:minecart" then
|
||||||
|
@ -673,8 +630,6 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
self._blinktimer = tnt.BLINKTIMER
|
self._blinktimer = tnt.BLINKTIMER
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
do_movement_step(self)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function cart:get_staticdata()
|
function cart:get_staticdata()
|
||||||
|
@ -701,30 +656,28 @@ function mcl_minecarts.place_minecart(itemstack, pointed_thing, placer)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Activate detector rail
|
|
||||||
if node.name == "mcl_minecarts:detector_rail" then
|
|
||||||
local newnode = {name="mcl_minecarts:detector_rail_on", param2 = node.param2}
|
|
||||||
minetest.swap_node(railpos, newnode)
|
|
||||||
mesecon.receptor_on(railpos)
|
|
||||||
end
|
|
||||||
|
|
||||||
local entity_id = entity_mapping[itemstack:get_name()]
|
local entity_id = entity_mapping[itemstack:get_name()]
|
||||||
local cart = minetest.add_entity(railpos, entity_id)
|
local cart = minetest.add_entity(railpos, entity_id)
|
||||||
local railtype = minetest.get_item_group(node.name, "connect_to_raillike")
|
local railtype = minetest.get_item_group(node.name, "connect_to_raillike")
|
||||||
|
local cart_dir = mcl_minecarts:get_rail_direction(railpos, {x=1, y=0, z=0}, nil, nil, railtype)
|
||||||
|
cart:set_yaw(minetest.dir_to_yaw(cart_dir))
|
||||||
|
|
||||||
|
-- Update static data
|
||||||
local le = cart:get_luaentity()
|
local le = cart:get_luaentity()
|
||||||
if le then
|
if le then
|
||||||
le._staticdata.railtype = railtype
|
le._staticdata = {
|
||||||
|
railtype = railtype,
|
||||||
|
connected_at = railpos,
|
||||||
|
dir = vector.new(cart_dir),
|
||||||
|
velocity = 0,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
local cart_dir
|
|
||||||
if node.name == "mcl_minecarts:golden_rail_on" then
|
-- Handle track behaviors
|
||||||
cart_dir = mcl_minecarts:get_start_direction(railpos)
|
local node_def = minetest.registered_nodes[node.name]
|
||||||
|
if node_def._mcl_minecarts_on_enter then
|
||||||
|
node_def._mcl_minecarts_on_enter(railpos, cart)
|
||||||
end
|
end
|
||||||
if cart_dir then
|
|
||||||
mcl_minecarts:set_velocity(le, cart_dir)
|
|
||||||
else
|
|
||||||
cart_dir = mcl_minecarts:get_rail_direction(railpos, {x=1, y=0, z=0}, nil, nil, railtype)
|
|
||||||
end
|
|
||||||
cart:set_yaw(minetest.dir_to_yaw(cart_dir))
|
|
||||||
|
|
||||||
local pname = ""
|
local pname = ""
|
||||||
if placer then
|
if placer then
|
||||||
|
|
|
@ -181,6 +181,11 @@ register_rail("mcl_minecarts:activator_rail_on",
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
|
_mcl_minecarts_on_enter = function(pos, cart)
|
||||||
|
if cart.on_activate_by_rail then
|
||||||
|
cart:on_activate_by_rail()
|
||||||
|
end
|
||||||
|
end,
|
||||||
drop = "mcl_minecarts:activator_rail",
|
drop = "mcl_minecarts:activator_rail",
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
|
@ -200,6 +205,16 @@ register_rail("mcl_minecarts:detector_rail",
|
||||||
rules = rail_rules_short,
|
rules = rail_rules_short,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
_mcl_minecarts_on_enter = function(pos, cart)
|
||||||
|
local node = minetest.get_node(pos)
|
||||||
|
|
||||||
|
local newnode = {
|
||||||
|
name = "mcl_minecarts:detector_rail_on",
|
||||||
|
param2 = node.param2
|
||||||
|
}
|
||||||
|
minetest.swap_node( pos, newnode )
|
||||||
|
mesecon.receptor_on(pos)
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -214,6 +229,16 @@ register_rail("mcl_minecarts:detector_rail_on",
|
||||||
rules = rail_rules_short,
|
rules = rail_rules_short,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
_mcl_minecarts_on_leave = function(pos, cart)
|
||||||
|
local node = minetest.get_node(pos)
|
||||||
|
|
||||||
|
local newnode = {
|
||||||
|
name = "mcl_minecarts:detector_rail",
|
||||||
|
param2 = node.param2
|
||||||
|
}
|
||||||
|
minetest.swap_node( pos, newnode )
|
||||||
|
mesecon.receptor_off(pos)
|
||||||
|
end,
|
||||||
drop = "mcl_minecarts:detector_rail",
|
drop = "mcl_minecarts:detector_rail",
|
||||||
},
|
},
|
||||||
false
|
false
|
||||||
|
|
Loading…
Reference in New Issue