From c695f2c14b40768031379e7a0e3a047582f28d40 Mon Sep 17 00:00:00 2001 From: TenPlus1 Date: Tue, 10 Jul 2018 11:34:42 +0100 Subject: [PATCH] keep up to date with 0.5 changes --- cart_entity.lua | 60 ++++++++--- detector.lua | 100 +++--------------- functions.lua | 66 ++++++++---- init.lua | 2 + ...il_dtc.png => carts_rail_straight_dtc.png} | Bin ..._on.png => carts_rail_straight_dtc_on.png} | Bin 6 files changed, 106 insertions(+), 122 deletions(-) rename textures/{carts_rail_dtc.png => carts_rail_straight_dtc.png} (100%) rename textures/{carts_rail_dtc_on.png => carts_rail_straight_dtc_on.png} (100%) diff --git a/cart_entity.lua b/cart_entity.lua index 18f0329..6fb0a3f 100644 --- a/cart_entity.lua +++ b/cart_entity.lua @@ -1,3 +1,5 @@ + +-- is mesecons enabled ? local HAVE_MESECONS_ENABLED = minetest.get_modpath("mesecons") if HAVE_MESECONS_ENABLED then dofile(minetest.get_modpath("carts") .. "/detector.lua") @@ -32,6 +34,12 @@ function cart_entity:on_rightclick(clicker) elseif not self.driver then self.driver = player_name carts:manage_attachment(clicker, self.object) + + if default.player_set_animation then + -- player_api(/default) does not update the animation + -- when the player is attached, reset to default animation + default.player_set_animation(clicker, "stand") + end end end @@ -42,7 +50,7 @@ function cart_entity:on_activate(staticdata, dtime_s) return end local data = minetest.deserialize(staticdata) - if not data or type(data) ~= "table" then + if type(data) ~= "table" then return end self.railtype = data.railtype @@ -58,6 +66,13 @@ function cart_entity:get_staticdata() }) end +-- 0.5.x and later: When the driver leaves +function cart_entity:on_detach_child(child) + if child and child:get_player_name() == self.driver then + self.driver = nil + end +end + function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction) local pos = self.object:get_pos() local vel = self.object:get_velocity() @@ -88,7 +103,7 @@ function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities, local player = minetest.get_player_by_name(self.driver) carts:manage_attachment(player, nil) end - for _,obj_ in ipairs(self.attached_items) do + for _, obj_ in ipairs(self.attached_items) do if obj_ then obj_:set_detach() end @@ -226,17 +241,23 @@ local function rail_on_step(self, dtime) local stop_wiggle = false if self.old_pos and same_dir then - -- Detection for "skipping" nodes - local found_path = carts:pathfinder( - pos, self.old_pos, self.old_dir, ctrl, self.old_switch, self.railtype + -- Detection for "skipping" nodes (perhaps use average dtime?) + -- It's sophisticated enough to take the acceleration in account + local acc = self.object:get_acceleration() + local distance = dtime * (v3_len(vel) + 0.5 * dtime * v3_len(acc)) + + local new_pos, new_dir = carts:pathfinder( + pos, self.old_pos, self.old_dir, distance, ctrl, + self.old_switch, self.railtype ) - if not found_path then - -- No rail found: reset back to the expected position - pos = vector.new(self.old_pos) + if new_pos then + -- No rail found: set to the expected position + pos = new_pos update.pos = true + cart_dir = new_dir end - elseif self.old_pos and cart_dir.y ~= -1 and not self.punched then + elseif self.old_pos and self.old_dir.y ~= 1 and not self.punched then -- Stop wiggle stop_wiggle = true end @@ -248,12 +269,14 @@ local function rail_on_step(self, dtime) local dir, switch_keys = carts:get_rail_direction( pos, cart_dir, ctrl, self.old_switch, self.railtype ) + local dir_changed = not vector.equals(dir, self.old_dir) local new_acc = {x=0, y=0, z=0} if stop_wiggle or vector.equals(dir, {x=0, y=0, z=0}) then vel = {x = 0, y = 0, z = 0} local pos_r = vector.round(pos) - if not carts:is_rail(pos_r, self.railtype) then + if not carts:is_rail(pos_r, self.railtype) + and self.old_pos then pos = self.old_pos elseif not stop_wiggle then pos = pos_r @@ -264,7 +287,7 @@ local function rail_on_step(self, dtime) update.vel = true else -- Direction change detected - if not vector.equals(dir, self.old_dir) then + if dir_changed then vel = vector.multiply(dir, math.abs(vel.x + vel.z)) update.vel = true if dir.y ~= self.old_dir.y then @@ -321,7 +344,7 @@ local function rail_on_step(self, dtime) end self.object:set_acceleration(new_acc) - self.old_pos = vector.new(pos) + self.old_pos = vector.round(pos) if not vector.equals(dir, {x=0, y=0, z=0}) and not stop_wiggle then self.old_dir = vector.new(dir) end @@ -368,9 +391,15 @@ local function rail_on_step(self, dtime) end self.object:set_animation(anim, 1, 0) - self.object:set_velocity(vel) + if update.vel then + self.object:set_velocity(vel) + end if update.pos then - self.object:set_pos(pos) + if dir_changed then + self.object:set_pos(pos) + else + self.object:move_to(pos) + end end -- call event handler @@ -393,7 +422,8 @@ minetest.register_craftitem("carts:cart", { local node = minetest.get_node(under) local udef = minetest.registered_nodes[node.name] if udef and udef.on_rightclick and - not (placer and placer:get_player_control().sneak) then + not (placer and placer:is_player() and + placer:get_player_control().sneak) then return udef.on_rightclick(under, node, placer, itemstack, pointed_thing) or itemstack end diff --git a/detector.lua b/detector.lua index 0f973c9..e73aad4 100644 --- a/detector.lua +++ b/detector.lua @@ -15,6 +15,7 @@ function carts:turnoff_detector_rail(pos) end end + function carts:signal_detector_rail(pos) local node = minetest.get_node(pos) @@ -23,7 +24,6 @@ function carts:signal_detector_rail(pos) return end - --minetest.log("action", "Signaling detector at " .. minetest.pos_to_string(pos)) if node.name == "carts:detectorrail" then minetest.swap_node(pos, {name = "carts:detectorrail_on", param2 = node.param2}) end @@ -33,106 +33,38 @@ function carts:signal_detector_rail(pos) minetest.after(0.5, carts.turnoff_detector_rail, carts, pos) end -minetest.register_node("carts:detectorrail", { - description = "Detector Rail", - drawtype = "raillike", - paramtype = "light", - sunlight_propagates = true, - is_ground_content = true, - walkable = false, - selection_box = { - type = "fixed", - fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, - }, + +carts:register_rail("carts:detectorrail", { + description = "Detector rail", tiles = { - "carts_rail_dtc.png", "carts_rail_curved_dtc.png", + "carts_rail_straight_dtc.png", "carts_rail_curved_dtc.png", "carts_rail_t_junction_dtc.png", "carts_rail_crossing_dtc.png" }, - wield_image = "carts_rail_dtc.png", - inventory_image = "carts_rail_dtc.png", - groups = { - dig_immediate = 2, attached_node = 1, rail = 1, connect_to_raillike = 1, - detector_rail = 1 - }, - mesecons = { - receptor = { - state = "off", rules = mesecons_rules - } - }, + groups = carts:get_rail_groups({detector_rail = 1}), + + mesecons = {receptor = {state = "off", rules = mesecons_rules}}, }) minetest.register_alias("boost_cart:detectorrail", "carts:detectorrail") ---[[ -boost_cart:register_rail("boost_cart:detectorrail", { - description = "Detector rail", - tiles = { - "carts_rail_dtc.png", "carts_rail_curved_dtc.png", - "carts_rail_t_junction_dtc.png", "carts_rail_crossing_dtc.png" - }, - groups = { - dig_immediate = 2, attached_node = 1, rail = 1, connect_to_raillike = 1, - detector_rail = 1, mesecon_effector_off = 1 - }, - mesecons = {effector = { - action_on = function (pos, node) - minetest.swap_node(pos, {name = "boost_cart:detectorrail_on", param2 = node.param2}) - end - }}, -},{}) -]] -minetest.register_node("carts:detectorrail_on", { - description = "Detector Rail ON (you hacker you)", - drawtype = "raillike", - paramtype = "light", - sunlight_propagates = true, - is_ground_content = true, - walkable = false, - selection_box = { - type = "fixed", - fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, - }, +carts:register_rail("carts:detectorrail_on", { + description = "Detector rail ON (you hacker you)", tiles = { - "carts_rail_dtc_on.png", "carts_rail_curved_dtc_on.png", + "carts_rail_straight_dtc_on.png", "carts_rail_curved_dtc_on.png", "carts_rail_t_junction_dtc_on.png", "carts_rail_crossing_dtc_on.png" }, - wield_image = "carts_rail_dtc_on.png", - inventory_image = "carts_rail_dtc_on.png", - groups = { - dig_immediate = 2, attached_node = 1, rail = 1, connect_to_raillike = 1, + groups = carts:get_rail_groups({ detector_rail = 1, not_in_creative_inventory = 1 - }, + }), drop = "carts:detectorrail", - mesecons = { - receptor = { - state = "on", rules = mesecons_rules - } - }, + + mesecons = {receptor = {state = "on", rules = mesecons_rules}}, }) -carts.railparams["carts:detectorrail_on"] = {acceleration = 0} -- 0 was 0.5 minetest.register_alias("boost_cart:detectorrail_on", "carts:detectorrail_on") ---[[ -boost_cart:register_rail("boost_cart:detectorrail_on", { - description = "Detector rail ON (you hacker you)", - tiles = { - "carts_rail_dtc_on.png", "carts_rail_curved_dtc_on.png", - "carts_rail_t_junction_dtc_on.png", "carts_rail_crossing_dtc_on.png" - }, - groups = { - dig_immediate = 2, attached_node = 1, rail = 1, connect_to_raillike = 1, - detector_rail = 1, not_in_creative_inventory = 1, mesecon_effector_on = 1 - }, - drop = "boost_cart:detectorrail", - mesecons = {effector = { - action_off = function (pos, node) - minetest.swap_node(pos, {name = "boost_cart:detectorrail", param2 = node.param2}) - end - }}, -}, {acceleration = 0.5}) -]] + minetest.register_craft({ output = "boost_cart:detectorrail 6", recipe = { diff --git a/functions.lua b/functions.lua index 0ed754d..0ac80a9 100644 --- a/functions.lua +++ b/functions.lua @@ -12,19 +12,21 @@ function carts:manage_attachment(player, obj) end local status = obj ~= nil local player_name = player:get_player_name() +-- if player_api.player_attached[player_name] == status then if default.player_attached[player_name] == status then return end +-- player_api.player_attached[player_name] = status default.player_attached[player_name] = status if status then - -- player_api came after the new model. Check for it. - local y_pos = player_api and -4.5 or 6 - player:set_attach(obj, "", {x=0, y=y_pos, z=0}, {x=0, y=0, z=0}) + player:set_attach(obj, "", {x=0, y=6, z=0}, {x=0, y=0, z=0}) player:set_eye_offset({x=0, y=-4, z=0},{x=0, y=-4, z=0}) else player:set_detach() player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) + -- HACK in effect! Force updating the attachment rotation + player:set_properties({}) end end @@ -101,6 +103,16 @@ function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) right.z = -dir.x end + local straight_priority = ctrl and dir.y ~= 0 + + -- Normal, to disallow rail switching up- & downhill + if straight_priority then + cur = self:check_front_up_down(pos, dir, true, railtype) + if cur then + return cur + end + end + if ctrl then if old_switch == 1 then left_check = false @@ -108,14 +120,14 @@ function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) right_check = false end if ctrl.left and left_check then - cur = carts:check_front_up_down(pos, left, false, railtype) + cur = self:check_front_up_down(pos, left, false, railtype) if cur then return cur, 1 end left_check = false end if ctrl.right and right_check then - cur = carts:check_front_up_down(pos, right, false, railtype) + cur = self:check_front_up_down(pos, right, false, railtype) if cur then return cur, 2 end @@ -124,9 +136,11 @@ function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) end -- Normal - cur = carts:check_front_up_down(pos, dir, true, railtype) - if cur then - return cur + if not straight_priority then + cur = self:check_front_up_down(pos, dir, true, railtype) + if cur then + return cur + end end -- Left, if not already checked @@ -160,38 +174,40 @@ function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) return {x=0, y=0, z=0} end -function carts:pathfinder(pos_, old_pos, old_dir, ctrl, pf_switch, railtype) - if vector.equals(old_pos, pos_) then - return true - end +function carts:pathfinder(pos_, old_pos, old_dir, distance, ctrl, + pf_switch, railtype) local pos = vector.round(pos_) + if vector.equals(old_pos, pos) then + return + end + local pf_pos = vector.round(old_pos) local pf_dir = vector.new(old_dir) + distance = math.min(carts.path_distance_max, + math.floor(distance + 1)) - for i = 1, 3 do - pf_dir, pf_switch = carts:get_rail_direction( - pf_pos, pf_dir, ctrl, pf_switch, railtype) + for i = 1, distance do + pf_dir, pf_switch = self:get_rail_direction( + pf_pos, pf_dir, ctrl, pf_switch or 0, railtype) if vector.equals(pf_dir, {x=0, y=0, z=0}) then -- No way forwards - return false + return pf_pos, pf_dir end pf_pos = vector.add(pf_pos, pf_dir) if vector.equals(pf_pos, pos) then -- Success! Cart moved on correctly - return true + return end end - -- Cart not found - return false + -- Not found. Put cart to predicted position + return pf_pos, pf_dir end ---function carts:register_rail(name, def, railparams) function carts:register_rail(name, def_overwrite, railparams) - --local def_default = { local def = { drawtype = "raillike", paramtype = "light", @@ -204,7 +220,6 @@ function carts:register_rail(name, def_overwrite, railparams) }, sounds = default.node_sound_metal_defaults() } - --for k, v in pairs(def_default) do for k, v in pairs(def_overwrite) do def[k] = v end @@ -222,7 +237,12 @@ end function carts:get_rail_groups(additional_groups) -- Get the default rail groups and add more when a table is given - local groups = {dig_immediate = 2, attached_node = 1, rail = 1, connect_to_raillike = 1} + local groups = { + dig_immediate = 2, + attached_node = 1, + rail = 1, + connect_to_raillike = minetest.raillike_group("rail") + } if type(additional_groups) == "table" then for k, v in pairs(additional_groups) do groups[k] = v diff --git a/init.lua b/init.lua index 53b33cc..f4f50f2 100644 --- a/init.lua +++ b/init.lua @@ -7,6 +7,8 @@ carts.railparams = {} carts.speed_max = 7 -- Set to -1 to disable punching the cart from inside (min = -1) carts.punch_speed_max = 5 +-- Maximal distance for the path correction (for dtime peaks) +carts.path_distance_max = 3 dofile(carts.modpath.."/functions.lua") diff --git a/textures/carts_rail_dtc.png b/textures/carts_rail_straight_dtc.png similarity index 100% rename from textures/carts_rail_dtc.png rename to textures/carts_rail_straight_dtc.png diff --git a/textures/carts_rail_dtc_on.png b/textures/carts_rail_straight_dtc_on.png similarity index 100% rename from textures/carts_rail_dtc_on.png rename to textures/carts_rail_straight_dtc_on.png