motorboat_custom_physics.lua 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. local min = math.min
  2. local abs = math.abs
  3. function motorboat.physics(self)
  4. local vel=self.object:get_velocity()
  5. -- dumb friction
  6. if self.isonground and not self.isinliquid then
  7. self.object:set_velocity({x= vel.x> 0.2 and vel.x*mobkit.friction or 0,
  8. y=vel.y,
  9. z=vel.z > 0.2 and vel.z*mobkit.friction or 0})
  10. end
  11. -- bounciness
  12. if self.springiness and self.springiness > 0 then
  13. local vnew = vector.new(vel)
  14. if not self.collided then -- ugly workaround for inconsistent collisions
  15. for _,k in ipairs({'y','z','x'}) do
  16. if vel[k]==0 and abs(self.lastvelocity[k])> 0.1 then
  17. vnew[k]=-self.lastvelocity[k]*self.springiness
  18. end
  19. end
  20. end
  21. if not vector.equals(vel,vnew) then
  22. self.collided = true
  23. else
  24. if self.collided then
  25. vnew = vector.new(self.lastvelocity)
  26. end
  27. self.collided = false
  28. end
  29. self.object:set_velocity(vnew)
  30. end
  31. -- buoyancy
  32. local surface = nil
  33. local surfnodename = nil
  34. local spos = mobkit.get_stand_pos(self)
  35. spos.y = spos.y+0.01
  36. -- get surface height
  37. local snodepos = mobkit.get_node_pos(spos)
  38. local surfnode = mobkit.nodeatpos(spos)
  39. while surfnode and (surfnode.drawtype == 'liquid' or surfnode.drawtype == 'flowingliquid') do
  40. surfnodename = surfnode.name
  41. surface = snodepos.y+0.5
  42. if surface > spos.y+self.height then break end
  43. snodepos.y = snodepos.y+1
  44. surfnode = mobkit.nodeatpos(snodepos)
  45. end
  46. self.isinliquid = surfnodename
  47. if surface then -- standing in liquid
  48. -- self.isinliquid = true
  49. local submergence = min(surface-spos.y,self.height)/self.height
  50. -- local balance = self.buoyancy*self.height
  51. local buoyacc = mobkit.gravity*(self.buoyancy-submergence)
  52. mobkit.set_acceleration(self.object,
  53. {x=-vel.x*self.water_drag,y=buoyacc-vel.y*abs(vel.y)*0.4,z=-vel.z*self.water_drag})
  54. else
  55. -- self.isinliquid = false
  56. self.object:set_acceleration({x=0,y=mobkit.gravity,z=0})
  57. end
  58. end