Carts: Increase performance overall
authorSmallJoker <mk939@ymail.com>
Sat, 26 Nov 2016 08:48:24 +0000 (09:48 +0100)
committerparamat <mat.gregory@virginmedia.com>
Sun, 27 Nov 2016 03:27:53 +0000 (03:27 +0000)
mods/carts/cart_entity.lua
mods/carts/functions.lua

index ea5f4bca341fa1d3bfc3e711656f07ef755aa3ce..4301b852b1da01144a0f3bb416b5bbbbe90957f3 100644 (file)
@@ -158,13 +158,13 @@ local function rail_sound(self, dtime)
        end
 end
 
-local function rail_on_step(self, dtime)
-       local pos = self.object:getpos()
+local function get_railparams(pos)
        local node = minetest.get_node(pos)
-       local railparams = carts.railparams[node.name] or {}
+       return carts.railparams[node.name] or {}
+end
 
+local function rail_on_step(self, dtime)
        local vel = self.object:getvelocity()
-       local update = {}
        if self.punched then
                vel = vector.add(vel, self.velocity)
                self.object:setvelocity(vel)
@@ -173,17 +173,17 @@ local function rail_on_step(self, dtime)
                return
        end
 
+       local pos = self.object:getpos()
+       local update = {}
+
        -- stop cart if velocity vector flips
-       if self.old_vel and (((self.old_vel.x * vel.x) < 0) or
-                       ((self.old_vel.z * vel.z) < 0)) and
-                       (self.old_vel.y == 0) then
-               self.old_dir = {x = 0, y = 0, z = 0}
+       if self.old_vel and self.old_vel.y == 0 and
+                       (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.velocity = {x = 0, y = 0, z = 0}
                self.old_pos = pos
                self.object:setvelocity(vector.new())
                self.object:setacceleration(vector.new())
-               rail_on_step_event(railparams.on_step, self, dtime)
+               rail_on_step_event(get_railparams(pos).on_step, self, dtime)
                return
        end
        self.old_vel = vector.new(vel)
@@ -193,7 +193,6 @@ local function rail_on_step(self, dtime)
                local flo_old = vector.round(self.old_pos)
                if vector.equals(flo_pos, flo_old) then
                        -- Do not check one node multiple times
-                       rail_on_step_event(railparams.on_step, self, dtime)
                        return
                end
        end
@@ -210,9 +209,8 @@ local function rail_on_step(self, dtime)
 
        if self.old_pos then
                -- Detection for "skipping" nodes
-               local expected_pos = vector.add(self.old_pos, self.old_dir)
                local found_path = carts:pathfinder(
-                       pos, expected_pos, self.old_dir, ctrl, self.old_switch, self.railtype
+                       pos, self.old_pos, self.old_dir, ctrl, self.old_switch, self.railtype
                )
 
                if not found_path then
@@ -223,6 +221,7 @@ local function rail_on_step(self, dtime)
        end
 
        local cart_dir = carts:velocity_to_dir(vel)
+       local railparams
 
        -- dir:         New moving direction of the cart
        -- switch_keys: Currently pressed L/R key, used to ignore the key on the next rail node
@@ -232,34 +231,36 @@ local function rail_on_step(self, dtime)
 
        local new_acc = {x=0, y=0, z=0}
        if vector.equals(dir, {x=0, y=0, z=0}) then
-               vel = {x=0, y=0, z=0}
+               vel = {x = 0, y = 0, z = 0}
                pos = vector.round(pos)
                update.pos = true
                update.vel = true
        else
-               -- If the direction changed
-               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
+               -- Direction change detected
+               if not vector.equals(dir, self.old_dir) then
+                       vel = vector.multiply(dir, math.abs(vel.x + vel.z))
+                       update.vel = true
+                       if dir.y ~= self.old_dir.y then
+                               pos = vector.round(pos)
+                               update.pos = true
+                       end
                end
-               if dir.z ~= 0 and self.old_dir.x ~= 0 then
-                       vel.z = dir.z * math.abs(vel.x)
-                       vel.x = 0
+               -- Center on the rail
+               if dir.z ~= 0 and math.floor(pos.x + 0.5) ~= pos.x then
                        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)
+               if dir.x ~= 0 and math.floor(pos.z + 0.5) ~= pos.z then
+                       pos.z = math.floor(pos.z + 0.5)
                        update.pos = true
                end
 
                -- Slow down or speed up..
                local acc = dir.y * -4.0
 
+               -- Get rail for corrected position
+               railparams = get_railparams(pos)
+
                -- no need to check for railparams == nil since we always make it exist.
                local speed_mod = railparams.acceleration
                if speed_mod and speed_mod ~= 0 then
@@ -279,7 +280,7 @@ local function rail_on_step(self, dtime)
 
        -- Limits
        local max_vel = carts.speed_max
-       for _,v in ipairs({"x","y","z"}) do
+       for _, v in pairs({"x","y","z"}) do
                if math.abs(vel[v]) > max_vel then
                        vel[v] = carts:get_sign(vel[v]) * max_vel
                        new_acc[v] = 0
@@ -296,7 +297,7 @@ local function rail_on_step(self, dtime)
 
        if self.punched then
                -- Collect dropped items
-               for _,obj_ in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
+               for _, obj_ in pairs(minetest.get_objects_inside_radius(pos, 1)) do
                        if not obj_:is_player() and
                                        obj_:get_luaentity() and
                                        not obj_:get_luaentity().physical_state and
@@ -310,6 +311,8 @@ local function rail_on_step(self, dtime)
                update.vel = true
        end
 
+       railparams = railparams or get_railparams(pos)
+
        if not (update.vel or update.pos) then
                rail_on_step_event(railparams.on_step, self, dtime)
                return
index f255fef56628adb38fa9f3903ad567c8c8d640cc..beda58496bd2b73a78f4a9bf1b6a0c0e35d0b2eb 100644 (file)
@@ -158,9 +158,9 @@ function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
        return {x=0, y=0, z=0}
 end
 
-function carts:pathfinder(pos_, expected_pos, old_dir, ctrl, pf_switch, railtype)
+function carts:pathfinder(pos_, old_pos, old_dir, ctrl, pf_switch, railtype)
        local pos = vector.round(pos_)
-       local pf_pos = vector.round(expected_pos)
+       local pf_pos = vector.round(old_pos)
        local pf_dir = vector.new(old_dir)
 
        for i = 1, 3 do