forked from Mineclonia/Mineclonia
Merge pull request 'Revert broken minecart change' (#4) from minecart into master
Reviewed-on: Mineclonia/Mineclonia#4 This code fixes annoying minecart bugs that were introduced with Mineclone2 0.71.0: • Minecarts going off the rails (#9) • Minecarts being unable to go back on the rails (#10) • TNT minecarts being broken (#11) • Minecarts not being pushed by mobs (#12) I have verified that it does not break the following features present in Mineclone2 0.70: • Minecart teleporters • Minecarts stop at the end of the rail • Going uphill in a minecart • Going downhill in a minecart • Going around curves in a minecart • Going left at intersections in a minecart with both left and right rail connections • Going straight ahead at intersections with both right and straight ahead rail connections • Pushing minecarts • Powered golden rails make minecarts go faster • Unpowered golden rails make minecarts stop • Detector rails activate Redstone circuits • Minecarts going in circles at maximum speed without glitching off the rails • Dispensers placing minecarts on top of rail blocks on top of the dispenser • Going to the Nether in a minecart • Powered activator rails drop players from minecarts • Unpowered activator rails do not drop players from minecarts • Track switching using pistons pushing a Minecart from one track to another • Minecarts stay on powered rails going up a spiral staircase • Minecarts can activate note blocks through sensor blocks • Minecarts can activate Redstone lamps through sensor blocks
This commit is contained in:
commit
b041666c18
|
@ -12,14 +12,15 @@ local function detach_driver(self)
|
|||
if not self._driver then
|
||||
return
|
||||
end
|
||||
if self._driver:is_player() then
|
||||
mcl_player.player_attached[self._driver:get_player_name()] = nil
|
||||
self._driver:set_detach()
|
||||
self._driver:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
|
||||
mcl_player.player_set_animation(self._driver, "stand" , 30)
|
||||
end
|
||||
mcl_player.player_attached[self._driver] = nil
|
||||
local player = minetest.get_player_by_name(self._driver)
|
||||
self._driver = nil
|
||||
self._start_pos = nil
|
||||
if player then
|
||||
player:set_detach()
|
||||
player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
|
||||
mcl_player.player_set_animation(player, "stand" , 30)
|
||||
end
|
||||
end
|
||||
|
||||
local function activate_tnt_minecart(self, timer)
|
||||
|
@ -61,7 +62,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
|||
|
||||
on_rightclick = on_rightclick,
|
||||
|
||||
_driver = nil, -- player (or mob) who sits in and controls the minecart (only for minecart!)
|
||||
_driver = nil, -- player who sits in and controls the minecart (only for minecart!)
|
||||
_punched = false, -- used to re-send _velocity and position
|
||||
_velocity = {x=0, y=0, z=0}, -- only used on punch
|
||||
_start_pos = nil, -- Used to calculate distance for “On A Rail” achievement
|
||||
|
@ -96,101 +97,111 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
|||
end
|
||||
|
||||
function cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
||||
-- Punch: Pick up minecart (unless TNT was ignited)
|
||||
if self._boomtimer then return end
|
||||
if self._driver then
|
||||
detach_driver(self)
|
||||
end
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
-- Disable detector rail
|
||||
local rou_pos = vector.round(pos)
|
||||
local node = minetest.get_node(rou_pos)
|
||||
if node.name == "mcl_minecarts:detector_rail_on" then
|
||||
local newnode = {name="mcl_minecarts:detector_rail", param2 = node.param2}
|
||||
minetest.swap_node(rou_pos, newnode)
|
||||
mesecon.receptor_off(rou_pos)
|
||||
if not self._railtype then
|
||||
local node = minetest.get_node(vector.floor(pos)).name
|
||||
self._railtype = minetest.get_item_group(node, "connect_to_raillike")
|
||||
end
|
||||
|
||||
-- Drop items and remove cart entity
|
||||
if not minetest.is_creative_enabled(puncher:get_player_name()) then
|
||||
for d=1, #drop do
|
||||
minetest.add_item(self.object:get_pos(), drop[d])
|
||||
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._railtype)
|
||||
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
|
||||
return
|
||||
end
|
||||
elseif puncher and puncher:is_player() then
|
||||
local inv = puncher:get_inventory()
|
||||
for d=1, #drop do
|
||||
if not inv:contains_item("main", drop[d]) then
|
||||
inv:add_item("main", drop[d])
|
||||
self._velocity = vector.multiply(cart_dir, 3)
|
||||
self._old_pos = nil
|
||||
self._punched = true
|
||||
return
|
||||
end
|
||||
|
||||
-- Punch+sneak: Pick up minecart (unless TNT was ignited)
|
||||
if puncher:get_player_control().sneak and not self._boomtimer then
|
||||
if self._driver then
|
||||
if self._old_pos then
|
||||
self.object:set_pos(self._old_pos)
|
||||
end
|
||||
detach_driver(self)
|
||||
end
|
||||
|
||||
-- Disable detector rail
|
||||
local rou_pos = vector.round(pos)
|
||||
local node = minetest.get_node(rou_pos)
|
||||
if node.name == "mcl_minecarts:detector_rail_on" then
|
||||
local newnode = {name="mcl_minecarts:detector_rail", param2 = node.param2}
|
||||
minetest.swap_node(rou_pos, newnode)
|
||||
mesecon.receptor_off(rou_pos)
|
||||
end
|
||||
|
||||
-- Drop items and remove cart entity
|
||||
if not minetest.is_creative_enabled(puncher:get_player_name()) then
|
||||
for d=1, #drop do
|
||||
minetest.add_item(self.object:get_pos(), drop[d])
|
||||
end
|
||||
elseif puncher and puncher:is_player() then
|
||||
local inv = puncher:get_inventory()
|
||||
for d=1, #drop do
|
||||
if not inv:contains_item("main", drop[d]) then
|
||||
inv:add_item("main", drop[d])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
|
||||
self.object:remove()
|
||||
local vel = self.object:get_velocity()
|
||||
if puncher:get_player_name() == self._driver then
|
||||
if math.abs(vel.x + vel.z) > 7 then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local punch_dir = mcl_minecarts:velocity_to_dir(puncher:get_look_dir())
|
||||
punch_dir.y = 0
|
||||
local cart_dir = mcl_minecarts:get_rail_direction(pos, punch_dir, nil, nil, self._railtype)
|
||||
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
|
||||
return
|
||||
end
|
||||
|
||||
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)
|
||||
|
||||
self._velocity = vector.multiply(cart_dir, f)
|
||||
self._old_pos = nil
|
||||
self._punched = true
|
||||
end
|
||||
|
||||
cart.on_activate_by_rail = on_activate_by_rail
|
||||
|
||||
function cart:on_step(dtime)
|
||||
local ctrl, player = nil, nil
|
||||
local update = {}
|
||||
local vel = self.object:get_velocity()
|
||||
local pos, rou_pos, node
|
||||
pos = self.object:get_pos()
|
||||
rou_pos = vector.round(pos)
|
||||
node = minetest.get_node(rou_pos)
|
||||
local g = minetest.get_item_group(node.name, "connect_to_raillike")
|
||||
if self._driver and self._driver:is_player() then
|
||||
player = self._driver
|
||||
ctrl = player:get_player_control()
|
||||
-- player detach
|
||||
if ctrl.sneak then
|
||||
detach_driver(self)
|
||||
return
|
||||
end
|
||||
if g == self._railtype then
|
||||
if ctrl.right then
|
||||
local c = vector.multiply(minetest.yaw_to_dir(self._driver:get_look_horizontal()-1.57), 0.2)
|
||||
self.object:set_velocity(vector.add(vel, {x=c.x, y=0, z=c.z}))
|
||||
end
|
||||
if ctrl.left then
|
||||
local c = vector.multiply(minetest.yaw_to_dir(self._driver:get_look_horizontal()+1.57), 0.2)
|
||||
self.object:set_velocity(vector.add(vel, {x=c.x, y=0, z=c.z}))
|
||||
end
|
||||
if ctrl.up then
|
||||
local c = vector.multiply(self._driver:get_look_dir(), 0.2)
|
||||
self.object:set_velocity(vector.add(vel, {x=c.x, y=0, z=c.z}))
|
||||
end
|
||||
if ctrl.down then
|
||||
local c = vector.multiply(self._driver:get_look_dir(), 0.2)
|
||||
self.object:set_velocity(vector.subtract(vel, {x=c.x, y=0, z=c.z}))
|
||||
if self._driver then
|
||||
player = minetest.get_player_by_name(self._driver)
|
||||
if player then
|
||||
ctrl = player:get_player_control()
|
||||
-- player detach
|
||||
if ctrl.sneak then
|
||||
detach_driver(self)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local vel = self.object:get_velocity()
|
||||
local update = {}
|
||||
if self._last_float_check == nil then
|
||||
self._last_float_check = 0
|
||||
else
|
||||
self._last_float_check = self._last_float_check + dtime
|
||||
end
|
||||
local pos, rou_pos, node
|
||||
-- Drop minecart if it isn't on a rail anymore
|
||||
if self._last_float_check >= mcl_minecarts.check_float_time then
|
||||
|
||||
|
||||
for _,object in pairs(minetest.get_objects_inside_radius(pos, 1.3)) do
|
||||
if object ~= self.object then
|
||||
local mob = object:get_luaentity()
|
||||
if mob then mob = mob._cmi_is_mob == true end
|
||||
if mob and (not self._driver) and not object:get_attach() then
|
||||
self._driver = object
|
||||
object:set_attach(self.object, "", {x=0, y=-1.75, z=-2}, {x=0, y=0, z=0})
|
||||
mobs:set_animation(self.object, "stand")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
pos = self.object:get_pos()
|
||||
rou_pos = vector.round(pos)
|
||||
node = minetest.get_node(rou_pos)
|
||||
local g = minetest.get_item_group(node.name, "connect_to_raillike")
|
||||
if g ~= self._railtype and self._railtype ~= nil then
|
||||
-- Detach driver
|
||||
if player then
|
||||
|
@ -289,12 +300,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
|||
end
|
||||
end
|
||||
|
||||
if update.vel then
|
||||
if self._punched then
|
||||
vel = vector.add(vel, self._velocity)
|
||||
if vel.x>8 then vel.x = 8 end
|
||||
if vel.x<-8 then vel.x = -8 end
|
||||
if vel.z>8 then vel.z = 8 end
|
||||
if vel.z<-8 then vel.z = -8 end
|
||||
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
|
||||
|
@ -619,14 +626,17 @@ register_minecart(
|
|||
"mcl_minecarts_minecart_normal.png",
|
||||
{"mcl_minecarts:minecart"},
|
||||
function(self, clicker)
|
||||
if not clicker or not clicker:is_player() then return end
|
||||
if clicker == self._driver then
|
||||
local name = clicker:get_player_name()
|
||||
if not clicker or not clicker:is_player() then
|
||||
return
|
||||
end
|
||||
local player_name = clicker:get_player_name()
|
||||
if self._driver and player_name == self._driver then
|
||||
detach_driver(self)
|
||||
else
|
||||
local name = clicker:get_player_name()
|
||||
self._driver = clicker
|
||||
elseif not self._driver then
|
||||
self._driver = player_name
|
||||
self._start_pos = self.object:get_pos()
|
||||
mcl_player.player_attached[name] = true
|
||||
mcl_player.player_attached[player_name] = true
|
||||
clicker:set_attach(self.object, "", {x=0, y=-1.75, z=-2}, {x=0, y=0, z=0})
|
||||
mcl_player.player_attached[name] = true
|
||||
minetest.after(0.2, function(name)
|
||||
|
@ -637,7 +647,6 @@ register_minecart(
|
|||
mcl_tmp_message.message(clicker, S("Sneak to dismount"))
|
||||
end
|
||||
end, name)
|
||||
clicker:set_look_horizontal(self.object:get_yaw())
|
||||
end
|
||||
end, activate_normal_minecart
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue