From: oilboi <47129783+oilboi@users.noreply.github.com> Date: Sat, 4 Jul 2020 18:03:46 +0000 (-0400) Subject: Create custom dtime related move_to velocity api X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=c370af13497394d9859ebc99610d696e8990d688;p=Crafter.git Create custom dtime related move_to velocity api --- diff --git a/mods/minecart/init.lua b/mods/minecart/init.lua index bea16f3..c42862a 100644 --- a/mods/minecart/init.lua +++ b/mods/minecart/init.lua @@ -51,15 +51,16 @@ local function collision_detect(self) if object:is_player() then local pos2 = object:get_pos() if self.axis_lock == "x" then - local velocity = 1-vector.distance(vector.new(pos.x,0,0),vector.new(pos2.x,0,0)) - print(velocity) + local velocity = (1-vector.distance(vector.new(pos.x,0,0),vector.new(pos2.x,0,0)))/10 local dir = vector.direction(vector.new(pos2.x,0,0),vector.new(pos.x,0,0)) - self.object:add_velocity(vector.multiply(dir,velocity)) + --self.object:add_velocity(vector.multiply(dir,velocity)) + self.velocity = vector.multiply(dir,velocity) self.dir = dir elseif self.axis_lock == "z" then - local velocity = 1-vector.distance(vector.new(0,0,pos.z),vector.new(0,0,pos2.z)) + local velocity = (1-vector.distance(vector.new(0,0,pos.z),vector.new(0,0,pos2.z)))/10 local dir = vector.direction(vector.new(0,0,pos2.z),vector.new(0,0,pos.z)) - self.object:add_velocity(vector.multiply(dir,velocity)) + --self.object:add_velocity(vector.multiply(dir,velocity)) + self.velocity = vector.multiply(dir,velocity) self.dir = dir end return @@ -73,6 +74,34 @@ local function direction_snap(self) self.object:set_rotation(vector.new(0,yaw,0)) end +local function turn_snap(pos,self,dir,dir2) + if dir.x ~= 0 and dir2.z ~= 0 then + --local inertia = math.abs(self.object:get_velocity().x) + local inertia = math.abs(self.velocity.x) + --self.object:set_velocity(vector.multiply(dir2,inertia)) + + self.velocity = vector.multiply(dir2,inertia) + self.dir = dir2 + self.axis_lock = "z" + self.object:set_pos(pos) + direction_snap(self) + return(true) + elseif dir.z ~= 0 and dir2.x ~= 0 then + --local inertia = math.abs(self.object:get_velocity().z) + --print(dump(self.velocity)) + local inertia = math.abs(self.velocity.z) + --self.object:set_velocity(vector.multiply(dir2,inertia)) + + self.velocity = vector.multiply(dir2,inertia) + + self.dir = dir2 + self.axis_lock = "x" + self.object:set_pos(pos) + direction_snap(self) + return(true) + end +end + local function rail_brain(self,pos) if not self.dir then return end @@ -98,25 +127,12 @@ local function rail_brain(self,pos) if triggered and not pool[minetest.hash_node_position(vector.add(pos,dir))] then local possible_dirs = create_axis(pos) if table.getn(possible_dirs) == 0 then + --print("train fails") --stop slow down become physical, something else for _,dir2 in pairs(possible_dirs) do - if dir.x ~= 0 and dir2.z ~= 0 then - local intertia = math.abs(self.object:get_velocity().x) - self.object:set_velocity(vector.multiply(dir2,intertia)) - self.dir = dir2 - self.axis_lock = "z" - self.object:set_pos(pos) - direction_snap(self) - break - elseif dir.z ~= 0 and dir2.x ~= 0 then - local intertia = math.abs(self.object:get_velocity().z) - self.object:set_velocity(vector.multiply(dir2,intertia)) - self.dir = dir2 - self.axis_lock = "x" - self.object:set_pos(pos) - direction_snap(self) - break + if turn_snap(pos,self,dir,dir2) then + return end end end @@ -129,7 +145,22 @@ end local minecart = {} minecart.on_step = function(self,dtime) - local pos = vector.round(self.object:get_pos()) + local float_pos = self.object:get_pos() + local pos = vector.round(float_pos) + + if self.velocity then + local new_vel = dtime/0.01 + print(new_vel) + self.object:move_to(vector.add(float_pos,vector.multiply(self.velocity,new_vel))) + end + + --stop minecarts from derailing when going super fast + if self.old_pos and vector.distance(float_pos,self.old_pos) > 0.5 then + self.object:move_to(self.old_pos) + float_pos = self.object:get_pos() + pos = vector.round(self.old_pos) + end + if not self.axis_lock then local possible_dirs = create_axis(pos) for _,dir in pairs(possible_dirs) do @@ -145,6 +176,7 @@ minecart.on_step = function(self,dtime) collision_detect(self) rail_brain(self,pos) end + self.old_pos = float_pos end minecart.on_rightclick = function(self,clicker) @@ -160,7 +192,8 @@ minecart.on_activate = function(self,staticdata, dtime_s) if type(data) ~= "table" then return end - + self.old_pos = self.object:get_pos() + self.velocity = vector.new(0,0,0) end minecart.get_staticdata = function(self) diff --git a/mods/minecart/oldcode.txt b/mods/minecart/oldcode.txt deleted file mode 100644 index bdbad79..0000000 --- a/mods/minecart/oldcode.txt +++ /dev/null @@ -1,463 +0,0 @@ -local path = minetest.get_modpath("minecart") -dofile(path.."/rail.lua") - - ---get if rail -local function rail(pos) - return(minetest.get_node_group(minetest.get_node(pos).name,"rail")>0) -end - ---check if on rail -local function on_rail(self,pos) - if not rail(pos) and not self.slope then - self.axis = nil - return(false) - else - return(true) - end -end - ---set physical state -local function physical(self,pos) - if on_rail(self,pos) then - self.object:set_properties({physical = false}) - self.object:setacceleration(vector.new(0,0,0)) - elseif not self.slope then - self.object:set_properties({physical = true}) - self.object:setacceleration(vector.new(0,-9.81,0)) - end -end - ---get if node in minecarts direction -local function node_ahead(self,pos) - local vel = self.object:getvelocity() - local dir = vector.normalize(vel) - return(rail(vector.add(pos,dir))) -end - ---get current axis (prefers x) -local function axis(pos) - if rail(pos) then - if rail(vector.new(pos.x-1,pos.y,pos.z)) or rail(vector.new(pos.x+1,pos.y,pos.z)) then return("x") end - if rail(vector.new(pos.x,pos.y,pos.z-1)) or rail(vector.new(pos.x,pos.y,pos.z+1)) then return("z") end - end -end - ---snap object to rail -local function snap_rail(self,pos) - local slopy = self.slope - if not slopy then print("the slope is nil") else - print("the slope is ".. slopy) - end - local railpos = vector.floor(vector.add(pos, 0.5)) - local vel = self.object:getvelocity() - if self.axis == "x" and pos.x ~= railpos.x then - self.object:moveto(vector.new(pos.x,railpos.y,railpos.z)) - self.object:setvelocity(vector.new(vel.x,0,0)) - print("snapped to x") - return - end - if self.axis == "z" and pos.z ~= railpos.z then - self.object:moveto(vector.new(railpos.x,railpos.y,pos.z)) - self.object:setvelocity(vector.new(0,0,vel.z)) - print("snapped to z") - return - end -end - ---check if entering new position -local function newnode(self,pos) - local pos = vector.floor(vector.add(pos,0.5)) - - pos.y = 0 - - local equals = false - - - if self.oldpos then - equals = vector.equals(pos,self.oldpos) - end - - self.oldpos = pos - return(not equals) -end - ---check if past center - used for turning -local function pastcenter(self,pos) - - local center = vector.floor(vector.add(pos,0.5)) - center.y = 0 - local pos2d = vector.new(pos.x,0,pos.z) - - local vel = self.object:getvelocity() - local dir = vector.normalize(vel) - dir.y = 0 - local checker = vector.round(vector.normalize(vector.subtract(pos2d,center))) - checker.y = 0 - local past = vector.equals(checker, dir) - return(past) -end - ---check if node ahead -local function node_forward(self,pos) - local vel = self.object:getvelocity() - local dir = vector.normalize(vel) - return(rail(vector.add(pos,dir))) -end - ---check if node above or below -local function check_hill(self,pos) - local vel = self.object:getvelocity() - local dirup = vector.normalize(vel) - - dirup.y = dirup.y + 1 - - print(dump(dirup)) - - minetest.add_particlespawner({ - amount = 5, - time = 0, - minpos = vector.add(pos,dirup), - maxpos = vector.add(pos,dirup), - minvel = vector.new(0,0,0), - maxvel = vector.new(0,0,0), - minacc = {x=0, y=0, z=0}, - maxacc = {x=0, y=0, z=0}, - minexptime = 5, - maxexptime = 5, - minsize = 1, - maxsize = 1, - attached = player, - collisiondetection = true, - vertical = false, - texture = "treecapitator.png" - }) - - local dirdown = vector.new(0,-0.5,0) - - if rail(vector.add(pos,dirup)) then - self.slope = "up" - return("up") - elseif rail(vector.add(pos,dirdown)) then - self.slope = "down" - return("down") - else - self.slope = nil - return(nil) - end -end - -local function gravity(self,pos) - - if self.slope == up then - local vel = vector.multiply(self.object:getvelocity(), 0.95) - self.object:set_velocity(vel) - end - if self.slope == up then - local vel = vector.multiply(self.object:getvelocity(), 1.05) - self.object:set_velocity(vel) - end - -end - ---make the minecart go up and down hills -local function navigate_hill(self) - if self.slope then - local vel = self.object:getvelocity() - if self.slope == "up" then - - local yvel = 0 - if self.axis == "x" then - yvel = math.abs(vel.x)*1.1 - end - if self.axis == "z" then - yvel = math.abs(vel.z)*1.1 - end - self.object:setvelocity(vector.new(vel.x,yvel,vel.z)) - elseif self.slope == "down" then - - local yvel = 0 - if self.axis == "x" then - yvel = math.abs(vel.x)*-1 - end - if self.axis == "z" then - yvel = math.abs(vel.z)*-1 - end - - self.object:setvelocity(vector.new(vel.x,yvel,vel.z)) - end - end -end - ---swap axis and speed 90 degrees -local function turn_check(self,pos) - local axis = self.axis - local vel = self.object:getvelocity() - vel.x = math.abs(vel.x) - vel.y = math.abs(vel.y) - vel.z = math.abs(vel.z) - - if axis == "x" then - if rail(vector.new(pos.x,pos.y,pos.z-1)) then - print("-x") - self.object:setvelocity(vector.new(0,0,vel.x*-1)) - self.axis = "z" - snap_rail(self,pos) - self.turn_timer = 0 - return - elseif rail(vector.new(pos.x,pos.y,pos.z+1)) then - print("+x") - self.object:setvelocity(vector.new(0,0,vel.x)) - self.axis = "z" - snap_rail(self,pos) - self.turn_timer = 0 - return - end - end - if axis == "z" then - if rail(vector.new(pos.x-1,pos.y,pos.z)) then - print("-z") - self.object:setvelocity(vector.new(vel.z*-1,0,0)) - self.axis = "x" - snap_rail(self,pos) - self.turn_timer = 0 - return - elseif rail(vector.new(pos.x+1,pos.y,pos.z)) then - print("+z") - self.object:setvelocity(vector.new(vel.z,0,0)) - self.axis = "x" - snap_rail(self,pos) - self.turn_timer = 0 - return - end - end -end ---try to turn -local function turn(self,pos) - if pastcenter(self,pos) then - if not node_forward(self,pos) and self.axis then - turn_check(self,pos) - end - end -end - ---the main mechanics of the minecart -local function minecart_brain(self,dtime) - if self.turn_timer < 5 then - self.turn_timer = self.turn_timer + dtime - end - local pos = self.object:getpos() - pos.y = pos.y - 0.5 - - - if not self.axis then - self.axis = axis(pos) - end - - if newnode(self,pos) then - snap_rail(self,pos) - end - --check_hill(self,pos) - --navigate_hill(self) - - - turn(self,pos) - - on_rail(self,pos) - physical(self,pos) - --print(self.axis) - - --check if falling and then fall at the same speed to go down -end - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -minetest.register_entity("minecart:minecart", { - initial_properties = { - physical = true, -- otherwise going uphill breaks - collisionbox = {-0.4, -0.5, -0.4, 0.4, 0.45, 0.4},--{-0.5, -0.4, -0.5, 0.5, 0.25, 0.5}, - visual = "mesh", - mesh = "minecart.obj", - visual_size = {x=1, y=1}, - textures = {"minecart.png"}, - automatic_face_movement_dir = 90.0, - automatic_face_movement_max_rotation_per_sec = 600, - }, - - rider = nil, - punched = false, - speed = 0, - turn_timer = 0, - incline = nil, - turn_timer = 5, - - on_rightclick = function(self,clicker) - if not clicker or not clicker:is_player() then - return - end - local player_name = clicker:get_player_name() - - if self.rider and player_name == self.rider then - self.rider = nil - --carts:manage_attachment(clicker, nil) - elseif not self.rider then - self.rider = player_name - clicker:set_attach(self.object, "", {x=0, y=-4.5, z=0}, {x=0, y=0, z=0}) - --player:set_eye_offset({x=0, y=-4, z=0},{x=0, y=-4, z=0}) - --carts:manage_attachment(clicker, self.object) - - -- player_api does not update the animation - -- when the player is attached, reset to default animation - - --player_api.set_animation(clicker, "stand") - end - end, - - on_activate = function(self,staticdata, dtime_s) - self.object:set_armor_groups({immortal=1}) - if string.sub(staticdata, 1, string.len("return")) ~= "return" then - return - end - local data = minetest.deserialize(staticdata) - if type(data) ~= "table" then - return - end - self.railtype = data.railtype - if data.old_dir then - self.old_dir = data.old_dir - end - end, - - get_staticdata = function(self) - return minetest.serialize({ - }) - end, - - on_punch = function(self,puncher, time_from_last_punch, tool_capabilities, dir, damage) - local obj = minetest.add_item(self.object:getpos(), "minecart:minecart") - self.object:remove() - end, - - --repel from players on track "push" - push = function(self) - if self.turn_timer > 0.3 then - local pos = self.object:getpos() - local radius = 1.2 - for _,object in ipairs(minetest.get_objects_inside_radius(pos, radius)) do - if object:is_player() and object:get_player_name() ~= self.rider then - local player_pos = object:getpos() - pos.y = 0 - player_pos.y = 0 - - local currentvel = self.object:getvelocity() - local vel = vector.subtract(pos, player_pos) - vel = vector.normalize(vel) - local distance = vector.distance(pos,player_pos) - distance = (radius-distance)*20 - vel = vector.multiply(vel,distance) - local acceleration = vector.new(vel.x-currentvel.x,0,vel.z-currentvel.z) - - --note : set a maximum velocity that can be added to the cart to limit extreme glitches - - if self.axis == "x" then - self.object:add_velocity(vector.new(acceleration.x,0,0)) - elseif self.axis == "z" then - self.object:add_velocity(vector.new(0,0,acceleration.z)) - else - self.object:add_velocity(acceleration) - end - - --acceleration = vector.multiply(acceleration, -0.5) - --object:add_player_velocity(acceleration) - end - end - end - end, - - --slows the minecart down - slowdown = function(self) - if not self.moving == true then - local vel = self.object:getvelocity() - local deceleration = vector.multiply(vel, -0.01) - self.object:add_velocity(deceleration) - end - end, - - --mechanics to follow rails - ride_rail = function(self,dtime) - minecart_brain(self,dtime) - end, - - on_step = function(self,dtime) - self.push(self) - self.slowdown(self) - self.ride_rail(self,dtime) - end, - -}) - -minetest.register_craftitem("minecart:minecart", { - description = "Minecart", - inventory_image = "minecartitem.png", - wield_image = "minecartitem.png", - on_place = function(itemstack, placer, pointed_thing) - if not pointed_thing.type == "node" then - return - end - - if minetest.get_item_group(minetest.get_node(pointed_thing.under).name, "rail")>0 then - minetest.add_entity(pointed_thing.under, "minecart:minecart") - else - return - end - - itemstack:take_item() - - return itemstack - end, -}) - -minetest.register_craft({ - output = "minecart:minecart", - recipe = { - {"main:iron", "", "main:iron"}, - {"main:iron", "main:iron", "main:iron"}, - }, -}) diff --git a/mods/minecart/rail.lua b/mods/minecart/rail.lua deleted file mode 100644 index e69de29..0000000