Slightly tweak minecarts to be more MC-like

This commit is contained in:
kay27 2021-03-01 01:43:00 +04:00
parent 961e5a249f
commit 8af76f835d

View file

@ -12,15 +12,14 @@ local function detach_driver(self)
if not self._driver then if not self._driver then
return return
end end
mcl_player.player_attached[self._driver] = nil if self._driver:is_player() then
local player = minetest.get_player_by_name(self._driver) 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
self._driver = nil self._driver = nil
self._start_pos = 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 end
local function activate_tnt_minecart(self, timer) local function activate_tnt_minecart(self, timer)
@ -62,7 +61,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
on_rightclick = on_rightclick, on_rightclick = on_rightclick,
_driver = nil, -- player who sits in and controls the minecart (only for minecart!) _driver = nil, -- player (or mob) who sits in and controls the minecart (only for minecart!)
_punched = false, -- used to re-send _velocity and position _punched = false, -- used to re-send _velocity and position
_velocity = {x=0, y=0, z=0}, -- only used on punch _velocity = {x=0, y=0, z=0}, -- only used on punch
_start_pos = nil, -- Used to calculate distance for “On A Rail” achievement _start_pos = nil, -- Used to calculate distance for “On A Rail” achievement
@ -97,111 +96,101 @@ 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)
-- 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() local pos = self.object:get_pos()
if not self._railtype then
local node = minetest.get_node(vector.floor(pos)).name -- Disable detector rail
self._railtype = minetest.get_item_group(node, "connect_to_raillike") 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 end
if not puncher or not puncher:is_player() then -- Drop items and remove cart entity
local cart_dir = mcl_minecarts:get_rail_direction(pos, {x=1, y=0, z=0}, nil, nil, self._railtype) if not minetest.is_creative_enabled(puncher:get_player_name()) then
if vector.equals(cart_dir, {x=0, y=0, z=0}) then for d=1, #drop do
return minetest.add_item(self.object:get_pos(), drop[d])
end end
self._velocity = vector.multiply(cart_dir, 3) elseif puncher and puncher:is_player() then
self._old_pos = nil local inv = puncher:get_inventory()
self._punched = true for d=1, #drop do
return if not inv:contains_item("main", drop[d]) then
end inv:add_item("main", drop[d])
-- 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
end end
self.object:remove()
return
end end
local vel = self.object:get_velocity() self.object:remove()
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 end
cart.on_activate_by_rail = on_activate_by_rail cart.on_activate_by_rail = on_activate_by_rail
function cart:on_step(dtime) function cart:on_step(dtime)
local ctrl, player = nil, nil local ctrl, player = nil, nil
if self._driver then local update = {}
player = minetest.get_player_by_name(self._driver) local vel = self.object:get_velocity()
if player then local pos, rou_pos, node
ctrl = player:get_player_control() pos = self.object:get_pos()
-- player detach rou_pos = vector.round(pos)
if ctrl.sneak then node = minetest.get_node(rou_pos)
detach_driver(self) local g = minetest.get_item_group(node.name, "connect_to_raillike")
return 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}))
end end
end end
end end
local vel = self.object:get_velocity()
local update = {}
if self._last_float_check == nil then if self._last_float_check == nil then
self._last_float_check = 0 self._last_float_check = 0
else else
self._last_float_check = self._last_float_check + dtime self._last_float_check = self._last_float_check + dtime
end end
local pos, rou_pos, node
-- Drop minecart if it isn't on a rail anymore -- Drop minecart if it isn't on a rail anymore
if self._last_float_check >= mcl_minecarts.check_float_time then if self._last_float_check >= mcl_minecarts.check_float_time then
pos = self.object:get_pos()
rou_pos = vector.round(pos)
node = minetest.get_node(rou_pos) for _,object in pairs(minetest.get_objects_inside_radius(pos, 1.3)) do
local g = minetest.get_item_group(node.name, "connect_to_raillike") 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
if g ~= self._railtype and self._railtype ~= nil then if g ~= self._railtype and self._railtype ~= nil then
-- Detach driver -- Detach driver
if player then if player then
@ -300,8 +289,12 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
end end
end end
if self._punched then if update.vel then
vel = vector.add(vel, self._velocity) 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.object:set_velocity(vel)
self._old_dir.y = 0 self._old_dir.y = 0
elseif vector.equals(vel, {x=0, y=0, z=0}) and (not has_fuel) then elseif vector.equals(vel, {x=0, y=0, z=0}) and (not has_fuel) then
@ -626,17 +619,14 @@ register_minecart(
"mcl_minecarts_minecart_normal.png", "mcl_minecarts_minecart_normal.png",
{"mcl_minecarts:minecart"}, {"mcl_minecarts:minecart"},
function(self, clicker) function(self, clicker)
local name = clicker:get_player_name() if not clicker or not clicker:is_player() then return end
if not clicker or not clicker:is_player() then if clicker == self._driver then
return
end
local player_name = clicker:get_player_name()
if self._driver and player_name == self._driver then
detach_driver(self) detach_driver(self)
elseif not self._driver then else
self._driver = player_name local name = clicker:get_player_name()
self._driver = clicker
self._start_pos = self.object:get_pos() self._start_pos = self.object:get_pos()
mcl_player.player_attached[player_name] = true mcl_player.player_attached[name] = true
clicker:set_attach(self.object, "", {x=0, y=-1.75, z=-2}, {x=0, y=0, z=0}) clicker:set_attach(self.object, "", {x=0, y=-1.75, z=-2}, {x=0, y=0, z=0})
mcl_player.player_attached[name] = true mcl_player.player_attached[name] = true
minetest.after(0.2, function(name) minetest.after(0.2, function(name)
@ -647,6 +637,7 @@ register_minecart(
mcl_tmp_message.message(clicker, S("Sneak to dismount")) mcl_tmp_message.message(clicker, S("Sneak to dismount"))
end end
end, name) end, name)
clicker:set_look_horizontal(self.object:get_yaw())
end end
end, activate_normal_minecart end, activate_normal_minecart
) )