mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-30 22:41:20 +01:00
Disable punch to move minecarts, implement punch to drop minecart, enable basic cart keyboard controls (accelerate and brake)
This commit is contained in:
parent
6f7e1df002
commit
4db70fd729
1 changed files with 48 additions and 112 deletions
|
@ -9,6 +9,7 @@ mcl_minecarts.speed_max = 10
|
|||
mcl_minecarts.check_float_time = 15
|
||||
local max_step_distance = 0.5
|
||||
local friction = 0.4
|
||||
local MINECART_MAX_HP = 4
|
||||
|
||||
dofile(mcl_minecarts.modpath.."/functions.lua")
|
||||
dofile(mcl_minecarts.modpath.."/rails.lua")
|
||||
|
@ -184,11 +185,9 @@ local function calculate_acceleration(self, staticdata)
|
|||
local max_vel = mcl_minecarts.speed_max
|
||||
|
||||
if self._go_forward then
|
||||
acceleration = 2
|
||||
acceleration = 4
|
||||
elseif self._brake then
|
||||
acceleration = -1.5
|
||||
elseif self._punched then
|
||||
acceleration = 2
|
||||
elseif (staticdata.fueltime or 0) > 0 and staticdata.velocity <= 4 then
|
||||
acceleration = 0.6
|
||||
elseif staticdata.velocity >= ( node_def._max_acceleration_velocity or max_vel ) then
|
||||
|
@ -399,11 +398,6 @@ local function do_movement( self, dtime )
|
|||
staticdata.delay = 0
|
||||
end
|
||||
|
||||
local initial_velocity = 2
|
||||
if self._punched and statcdata.velocity < initial_velocity then
|
||||
staticdata.velocity = initial_velocity
|
||||
end
|
||||
|
||||
-- Break long movements at block boundaries to make it
|
||||
-- it impossible to jump across gaps due to server lag
|
||||
-- causing large timesteps
|
||||
|
@ -415,9 +409,6 @@ local function do_movement( self, dtime )
|
|||
|
||||
dtime = new_dtime
|
||||
end
|
||||
|
||||
-- Clear punched flag now that movement for this step has been completed
|
||||
self._punched = false
|
||||
end
|
||||
|
||||
local function detach_driver(self)
|
||||
|
@ -439,7 +430,6 @@ local function activate_tnt_minecart(self, timer)
|
|||
if self._boomtimer then
|
||||
return
|
||||
end
|
||||
self.object:set_armor_groups({immortal=1})
|
||||
if timer then
|
||||
self._boomtimer = timer
|
||||
else
|
||||
|
@ -461,6 +451,7 @@ end
|
|||
local function activate_normal_minecart(self)
|
||||
detach_driver(self)
|
||||
|
||||
-- Detach passenger
|
||||
if self._passenger then
|
||||
local mob = self._passenger.object
|
||||
mob:set_detach()
|
||||
|
@ -635,6 +626,8 @@ local function register_entity(entity_id, def)
|
|||
textures = def.textures,
|
||||
},
|
||||
|
||||
hp_max = MINECART_MAX_HP,
|
||||
|
||||
groups = groups,
|
||||
|
||||
on_rightclick = def.on_rightclick,
|
||||
|
@ -646,7 +639,6 @@ local function register_entity(entity_id, def)
|
|||
|
||||
_driver = nil, -- player who sits in and controls the minecart (only for minecart!)
|
||||
_passenger = nil, -- for mobs
|
||||
_punched = false, -- used to re-send _velocity and position
|
||||
_start_pos = nil, -- Used to calculate distance for “On A Rail” achievement
|
||||
_last_float_check = nil, -- timestamp of last time the cart was checked to be still on a rail
|
||||
_boomtimer = nil, -- how many seconds are left before exploding
|
||||
|
@ -673,7 +665,6 @@ local function register_entity(entity_id, def)
|
|||
|
||||
self._staticdata = data
|
||||
end
|
||||
self.object:set_armor_groups({immortal=1})
|
||||
|
||||
-- Activate cart if on activator rail
|
||||
if self.on_activate_by_rail then
|
||||
|
@ -684,111 +675,37 @@ local function register_entity(entity_id, def)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
function cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
||||
function cart:on_death(killer)
|
||||
local staticdata = self._staticdata
|
||||
if not staticdata then
|
||||
staticdata = make_staticdata()
|
||||
self._staticdata = staticdata
|
||||
end
|
||||
|
||||
local pos = staticdata.connected_at
|
||||
if not pos then
|
||||
pos = self.object:get_pos()
|
||||
-- Try to reattach
|
||||
local rounded_pos = vector.round(pos)
|
||||
if mcl_minecarts:is_rail(rounded_pos) and vector.distance(pos, rounded_pos) < 0.5 then
|
||||
-- Reattach
|
||||
staticdata.connected_at = rounded_pos
|
||||
pos = rounded_pos
|
||||
else
|
||||
minetest.log("warning","rounded_pos="..tostring(rounded_pos)..",dist="..vector.distance(pos, rounded_pos))
|
||||
minetest.log("warning","TODO: handle detached cart behavior")
|
||||
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
|
||||
local cart_dir = mcl_minecarts:get_rail_direction(pos, vector.new(1,0,0), nil, nil, staticdata.railtype)
|
||||
if vector.equals(cart_dir, vector.new(0,0,0)) then
|
||||
return
|
||||
end
|
||||
|
||||
staticdata.dir = cart_dir
|
||||
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)
|
||||
|
||||
-- Detach passenger
|
||||
if self._passenger then
|
||||
local mob = self._passenger.object
|
||||
mob:set_detach()
|
||||
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)
|
||||
-- Leave nodes
|
||||
if staticdata.attached_at then
|
||||
handle_cart_leave(self, staticdata.attached_at, staticdata.dir )
|
||||
else
|
||||
mcl_log("TODO: handle detatched minecart death")
|
||||
end
|
||||
|
||||
-- Drop items and remove cart entity
|
||||
-- Drop items
|
||||
local drop = def.drop
|
||||
if not minetest.is_creative_enabled(puncher:get_player_name()) then
|
||||
if not minetest.is_creative_enabled(killer: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()
|
||||
elseif puncher and killer:is_player() then
|
||||
local inv = killer: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
|
||||
|
||||
-- Handle player punches
|
||||
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._staticdata.railtype)
|
||||
if vector.equals(cart_dir, vector.new(0,0,0)) then
|
||||
return
|
||||
end
|
||||
|
||||
staticdata.dir = cart_dir
|
||||
|
||||
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)
|
||||
|
||||
-- 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
|
||||
|
||||
local passenger_attach_position = vector.new(0, -1.75, 0)
|
||||
|
@ -824,6 +741,25 @@ local function register_entity(entity_id, def)
|
|||
self._staticdata = staticdata
|
||||
end
|
||||
|
||||
-- Regen
|
||||
local hp = self.object:get_hp()
|
||||
if hp < MINECART_MAX_HP then
|
||||
if (staticdata.regen_timer or 0) > 0.5 then
|
||||
hp = hp + 1
|
||||
staticdata.regen_timer = staticdata.regen_timer - 1
|
||||
end
|
||||
staticdata.regen_timer = (staticdata.regen_timer or 0) + dtime
|
||||
self.object:set_hp(hp)
|
||||
else
|
||||
staticdata.regen_timer = nil
|
||||
end
|
||||
|
||||
-- Fix railtype field
|
||||
if staticdata.connected_at and not staticdata.railtype then
|
||||
local node = minetest.get_node(vector.floor(pos)).name
|
||||
staticdata.railtype = minetest.get_item_group(node, "connect_to_raillike")
|
||||
end
|
||||
|
||||
-- Cart specific behaviors
|
||||
local hook = self._mcl_minecarts_on_step
|
||||
if hook then hook(self,dtime) end
|
||||
|
@ -847,8 +783,8 @@ local function register_entity(entity_id, def)
|
|||
end
|
||||
|
||||
-- Experimental controls
|
||||
--self._go_forward = ctrl.up
|
||||
--self._brake = ctrl.down
|
||||
self._go_forward = ctrl.up
|
||||
self._brake = ctrl.down
|
||||
end
|
||||
|
||||
-- Give achievement when player reached a distance of 1000 nodes from the start position
|
||||
|
|
Loading…
Reference in a new issue