Advertisement
Guest User

Untitled

a guest
Jan 5th, 2018
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.31 KB | None | 0 0
  1. local enable_crash = false
  2. local crash_threshold = 6.5     -- ignored if enable_crash=false
  3.  
  4. ------------------------------------------------------------------------------
  5.  
  6. local mobs_redo = false
  7. if minetest.get_modpath("mobs") then
  8.     if mobs.mod and mobs.mod == "redo" then
  9.         mobs_redo = true
  10.     end
  11. end
  12.  
  13. --
  14. -- Helper functions
  15. --
  16.  
  17. --local function is_group(pos, group)
  18. --  local nn = minetest.get_node(pos).name
  19. --  return minetest.get_item_group(nn, group) ~= 0
  20. --end
  21.  
  22. local function node_is(pos)
  23.     local node = minetest.get_node(pos)
  24.     if node.name == "air" then
  25.         return "air"
  26.     end
  27.     if minetest.get_item_group(node.name, "liquid") ~= 0 then
  28.         return "liquid"
  29.     end
  30.     if minetest.get_item_group(node.name, "walkable") ~= 0 then
  31.         return "walkable"
  32.     end
  33.     return "other"
  34. end
  35.  
  36. local function get_sign(i)
  37.     i = i or 0
  38.     if i == 0 then
  39.         return 0
  40.     else
  41.         return i / math.abs(i)
  42.     end
  43. end
  44.  
  45. local function get_velocity(v, yaw, y)
  46.     local x = -math.sin(yaw) * v
  47.     local z =  math.cos(yaw) * v
  48.     return {x = x, y = y, z = z}
  49. end
  50.  
  51. local function get_v(v)
  52.     return math.sqrt(v.x ^ 2 + v.z ^ 2)
  53. end
  54.  
  55. local function force_detach(player)
  56.     local attached_to = player:get_attach()
  57.     if attached_to then
  58.         local entity = attached_to:get_luaentity()
  59.         if entity.driver and entity.driver == player then
  60.             entity.driver = nil
  61.         elseif entity.passenger and entity.passenger == player then
  62.             entity.passenger = nil
  63.         end
  64.         player:set_detach()
  65.         default.player_attached[player:get_player_name()] = false
  66.         player:set_eye_offset({x=0, y=0, z=0}, {x=0, y=0, z=0})
  67.     end
  68. end
  69.  
  70. -------------------------------------------------------------------------------
  71.  
  72.  
  73. minetest.register_on_leaveplayer(function(player)
  74.     force_detach(player)
  75. end)
  76.  
  77. minetest.register_on_shutdown(function()
  78.     local players = minetest.get_connected_players()
  79.     for i = 1,#players do
  80.         force_detach(players[i])
  81.     end
  82. end)
  83.  
  84. minetest.register_on_dieplayer(function(player)
  85.     force_detach(player)
  86.     return true
  87. end)
  88.  
  89. -------------------------------------------------------------------------------
  90.  
  91.  
  92. lib_mount = {}
  93.  
  94. function lib_mount.attach(entity, player, is_passenger)
  95.     local attach_at, eye_offset = {}, {}
  96.    
  97.     if not entity.player_rotation then
  98.         entity.player_rotation = {x=0, y=0, z=0}
  99.     end
  100.    
  101.     local rot_view = 0
  102.     if entity.player_rotation.y == 90 then
  103.         rot_view = math.pi/2
  104.     end
  105.  
  106.     if is_passenger == true then
  107.         if not entity.passenger_attach_at then
  108.             entity.passenger_attach_at = {x=0, y=0, z=0}
  109.         end
  110.         if not entity.passenger_eye_offset then
  111.             entity.passenger_eye_offset = {x=0, y=0, z=0}
  112.         end
  113.         attach_at = entity.passenger_attach_at
  114.         eye_offset = entity.passenger_eye_offset
  115.         entity.passenger = player
  116.     else
  117.         if not entity.driver_attach_at then
  118.             entity.driver_attach_at = {x=0, y=0, z=0}
  119.         end
  120.         if not entity.driver_eye_offset then
  121.             entity.driver_eye_offset = {x=0, y=0, z=0}
  122.         end
  123.         attach_at = entity.driver_attach_at
  124.         eye_offset = entity.driver_eye_offset
  125.         entity.driver = player
  126.     end
  127.  
  128.     force_detach(player)
  129.  
  130.     player:set_attach(entity.object, "", attach_at, entity.player_rotation)
  131.     default.player_attached[player:get_player_name()] = true
  132.     player:set_eye_offset(eye_offset, {x=0, y=0, z=0})
  133.     minetest.after(0.2, function()
  134.         default.player_set_animation(player, "sit" , 30)
  135.     end)
  136.     player:set_look_yaw(entity.object:getyaw() - rot_view)
  137. end
  138.  
  139. function lib_mount.detach(player, offset)
  140.     force_detach(player)
  141.     default.player_set_animation(player, "stand" , 30)
  142.     local pos = player:getpos()
  143.     local pname = player:get_player_name()
  144. if pos == nil then
  145. return
  146. end
  147.  
  148.     pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z}
  149.     minetest.after(0.1, function()
  150.         player:setpos(pos)
  151.     end)
  152. end
  153.  
  154. local aux_timer = 0
  155.  
  156. function lib_mount.drive(entity, dtime, is_mob, moving_anim, stand_anim, jump_height, can_fly)
  157.     aux_timer = aux_timer + dtime
  158.    
  159.     if can_fly and can_fly == true then
  160.         jump_height = 0
  161.     end
  162.  
  163.     local rot_steer, rot_view = math.pi/2, 0
  164.     if entity.player_rotation.y == 90 then
  165.         rot_steer, rot_view = 0, math.pi/2
  166.     end
  167.  
  168.     local acce_y = 0
  169.  
  170.     local velo = entity.object:getvelocity()
  171.     entity.v = get_v(velo) * get_sign(entity.v)
  172.  
  173.     -- process controls
  174.     if entity.driver then
  175.         local ctrl = entity.driver:get_player_control()
  176.         if ctrl.aux1 then
  177.             if aux_timer >= 0.2 then
  178.                 entity.mouselook = not entity.mouselook
  179.                 aux_timer = 0
  180.             end
  181.         end
  182.         if ctrl.up then
  183.             if get_sign(entity.v) >= 0 then
  184.                 entity.v = entity.v + entity.accel/10
  185.             else
  186.                 entity.v = entity.v + entity.braking/10
  187.             end
  188.         elseif ctrl.down then
  189.             if entity.max_speed_reverse == 0 and entity.v == 0 then return end
  190.             if get_sign(entity.v) < 0 then
  191.                 entity.v = entity.v - entity.accel/10
  192.             else
  193.                 entity.v = entity.v - entity.braking/10
  194.             end
  195.         end
  196.         if entity.mouselook then
  197.             if ctrl.left then
  198.                 entity.object:setyaw(entity.object:getyaw()+get_sign(entity.v)*math.rad(1+dtime)*entity.turn_spd)
  199.             elseif ctrl.right then
  200.                 entity.object:setyaw(entity.object:getyaw()-get_sign(entity.v)*math.rad(1+dtime)*entity.turn_spd)
  201.             end
  202.         else
  203.             entity.object:setyaw(entity.driver:get_look_yaw() - rot_steer)
  204.         end
  205.         if ctrl.jump then
  206.             if jump_height > 0 and velo.y == 0 then
  207.                 velo.y = velo.y + (jump_height * 3) + 1
  208.                 acce_y = acce_y + (acce_y * 3) + 1
  209.             end
  210.             if can_fly and can_fly == true then
  211.                 velo.y = velo.y + 1
  212.                 acce_y = acce_y + 1
  213.             end
  214.         end
  215.         if ctrl.sneak then
  216.             if can_fly and can_fly == true then
  217.                 velo.y = velo.y - 1
  218.                 acce_y = acce_y - 1
  219.             end
  220.         end
  221.     end
  222.  
  223.     -- if not moving then set animation and return
  224.     if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
  225.         if is_mob and mobs_redo == true then
  226.             if stand_anim and stand_anim ~= nil then
  227.                 set_animation(entity, stand_anim)
  228.             end
  229.         end
  230.         return
  231.     end
  232.    
  233.     -- set animation
  234.     if is_mob and mobs_redo == true then
  235.         if moving_anim and moving_anim ~= nil then
  236.             set_animation(entity, moving_anim)
  237.         end
  238.     end
  239.  
  240.     -- Stop!
  241.     local s = get_sign(entity.v)
  242.     entity.v = entity.v - 0.02 * s
  243.     if s ~= get_sign(entity.v) then
  244.         entity.object:setvelocity({x=0, y=0, z=0})
  245.         entity.v = 0
  246.         return
  247.     end
  248.  
  249.     -- enforce speed limit forward and reverse
  250.     local max_spd = entity.max_speed_reverse
  251.     if get_sign(entity.v) >= 0 then
  252.         max_spd = entity.max_speed_forward
  253.     end
  254.     if math.abs(entity.v) > max_spd then
  255.         entity.v = entity.v - get_sign(entity.v)
  256.     end
  257.  
  258.     -- Set position, velocity and acceleration 
  259.     local p = entity.object:getpos()
  260.     local new_velo = {x=0, y=0, z=0}
  261.     local new_acce = {x=0, y=-9.8, z=0}
  262.  
  263.     p.y = p.y - 0.5
  264.     local ni = node_is(p)
  265.     local v = entity.v
  266.     if ni == "air" then
  267.         if can_fly == true then
  268.             new_acce.y = 0
  269.         end
  270.     elseif ni == "liquid" then
  271.         if entity.terrain_type == 2 or entity.terrain_type == 3 then
  272.             new_acce.y = 0
  273.             p.y = p.y + 1
  274.             if node_is(p) == "liquid" then
  275.                 if velo.y >= 5 then
  276.                     velo.y = 5
  277.                 elseif velo.y < 0 then
  278.                     new_acce.y = 20
  279.                 else
  280.                     new_acce.y = 5
  281.                 end
  282.             else
  283.                 if math.abs(velo.y) < 1 then
  284.                     local pos = entity.object:getpos()
  285.                     pos.y = math.floor(pos.y) + 0.5
  286.                     entity.object:setpos(pos)
  287.                     velo.y = 0
  288.                 end
  289.             end
  290.         else
  291.             v = v*0.25
  292.         end
  293. --  elseif ni == "walkable" then
  294. --      v = 0
  295. --      new_acce.y = 1
  296.     end
  297.  
  298.     new_velo = get_velocity(v, entity.object:getyaw() - rot_view, velo.y)
  299.     new_acce.y = new_acce.y + acce_y
  300.  
  301.     entity.object:setvelocity(new_velo)
  302.     entity.object:setacceleration(new_acce)
  303.  
  304.     -- CRASH!
  305.     if enable_crash then
  306.         local intensity = entity.v2 - v
  307.         if intensity >= crash_threshold then
  308.             if is_mob then
  309.                 entity.object:set_hp(entity.object:get_hp() - intensity)
  310.             else
  311.                 if entity.driver then
  312.                     local drvr = entity.driver
  313.                     lib_mount.detach(drvr, {x=0, y=0, z=0})
  314.                     drvr:setvelocity(new_velo)
  315.                     drvr:set_hp(drvr:get_hp() - intensity)
  316.                 end
  317.                 if entity.passenger then
  318.                     local pass = entity.passenger
  319.                     lib_mount.detach(pass, {x=0, y=0, z=0})
  320.                     pass:setvelocity(new_velo)
  321.                     pass:set_hp(pass:get_hp() - intensity)
  322.                 end
  323.                 local pos = entity.object:getpos()
  324.                 minetest.add_item(pos, entity.drop_on_destroy)
  325.                 entity.removed = true
  326.                 -- delay remove to ensure player is detached
  327.                 minetest.after(0.1, function()
  328.                     entity.object:remove()
  329.                 end)
  330.             end
  331.         end
  332.     end
  333.  
  334.     entity.v2 = v
  335. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement