2023-06-11 17:29:08 -03:00
|
|
|
function airutils.physics(self)
|
2023-07-17 18:57:56 -03:00
|
|
|
local friction = self._ground_friction or 0.99
|
2023-06-11 17:29:08 -03:00
|
|
|
local vel=self.object:get_velocity()
|
2023-10-27 19:30:18 -03:00
|
|
|
local new_velocity = vector.new()
|
2023-07-16 20:37:23 -03:00
|
|
|
|
2023-06-17 21:55:14 -03:00
|
|
|
--buoyancy
|
|
|
|
local surface = nil
|
|
|
|
local surfnodename = nil
|
|
|
|
local spos = airutils.get_stand_pos(self)
|
2023-08-24 20:14:00 -03:00
|
|
|
if not spos then return end
|
2023-06-17 21:55:14 -03:00
|
|
|
spos.y = spos.y+0.01
|
|
|
|
-- get surface height
|
|
|
|
local snodepos = airutils.get_node_pos(spos)
|
|
|
|
local surfnode = airutils.nodeatpos(spos)
|
|
|
|
while surfnode and (surfnode.drawtype == 'liquid' or surfnode.drawtype == 'flowingliquid') do
|
|
|
|
surfnodename = surfnode.name
|
|
|
|
surface = snodepos.y +0.5
|
|
|
|
if surface > spos.y+self.height then break end
|
|
|
|
snodepos.y = snodepos.y+1
|
|
|
|
surfnode = airutils.nodeatpos(snodepos)
|
|
|
|
end
|
|
|
|
|
|
|
|
self.isinliquid = surfnodename
|
|
|
|
if surface then -- standing in liquid
|
|
|
|
self.isinliquid = true
|
|
|
|
end
|
2024-03-10 11:24:40 -03:00
|
|
|
local last_accel = vector.new()
|
2023-10-29 17:46:14 -03:00
|
|
|
if self._last_accel then
|
2024-01-23 21:38:27 -03:00
|
|
|
last_accel = vector.new(self._last_accel)
|
2023-10-29 17:46:14 -03:00
|
|
|
end
|
2023-06-17 21:55:14 -03:00
|
|
|
|
|
|
|
if self.isinliquid then
|
2023-07-17 04:55:29 -03:00
|
|
|
self.water_drag = 0.2
|
|
|
|
self.isinliquid = true
|
2023-06-17 21:55:14 -03:00
|
|
|
local height = self.height
|
2023-07-16 20:37:23 -03:00
|
|
|
local submergence = math.min(surface-spos.y,height)/height
|
2023-06-17 21:55:14 -03:00
|
|
|
-- local balance = self.buoyancy*self.height
|
2023-10-26 22:28:38 -03:00
|
|
|
local buoyacc = airutils.gravity*(self.buoyancy-submergence)
|
2023-07-17 04:55:29 -03:00
|
|
|
--local buoyacc = self._baloon_buoyancy*(self.buoyancy-submergence)
|
2024-10-05 11:27:56 +02:00
|
|
|
local accell = {
|
2023-11-12 18:26:31 -03:00
|
|
|
x=-vel.x*self.water_drag,
|
|
|
|
y=buoyacc-(vel.y*math.abs(vel.y)*0.4),
|
|
|
|
z=-vel.z*self.water_drag
|
|
|
|
}
|
2023-07-16 20:37:23 -03:00
|
|
|
if self.buoyancy >= 1 then self._engine_running = false end
|
2023-10-27 19:30:18 -03:00
|
|
|
if last_accel then
|
|
|
|
accell = vector.add(accell,last_accel)
|
|
|
|
end
|
|
|
|
new_velocity = vector.multiply(accell,self.dtime)
|
|
|
|
--airutils.set_acceleration(self.object,accell)
|
|
|
|
--self.object:move_to(self.object:get_pos())
|
2023-06-17 21:55:14 -03:00
|
|
|
else
|
2023-10-26 22:28:38 -03:00
|
|
|
--airutils.set_acceleration(self.object,{x=0,y=airutils.gravity,z=0})
|
2023-06-17 21:55:14 -03:00
|
|
|
self.isinliquid = false
|
2024-10-05 11:27:56 +02:00
|
|
|
|
2023-10-29 17:46:14 -03:00
|
|
|
if last_accel then
|
2023-10-27 19:30:18 -03:00
|
|
|
last_accel.y = last_accel.y + airutils.gravity --gravity here
|
|
|
|
|
|
|
|
new_velocity = vector.multiply(last_accel,self.dtime)
|
|
|
|
end
|
|
|
|
--self.object:set_acceleration({x=0,y=new_accel.y, z=0})
|
2023-06-17 21:55:14 -03:00
|
|
|
end
|
|
|
|
|
2023-07-16 20:37:23 -03:00
|
|
|
if self.isonground and not self.isinliquid then
|
|
|
|
--dumb friction
|
|
|
|
new_velocity = {x=new_velocity.x*friction,
|
|
|
|
y=new_velocity.y,
|
|
|
|
z=new_velocity.z*friction}
|
2023-10-11 19:51:55 -03:00
|
|
|
|
2023-07-16 20:37:23 -03:00
|
|
|
-- bounciness
|
|
|
|
if self.springiness and self.springiness > 0 and self.buoyancy >= 1 then
|
|
|
|
local vnew = vector.new(new_velocity)
|
2024-10-05 11:27:56 +02:00
|
|
|
|
2023-07-16 20:37:23 -03:00
|
|
|
if not self.collided then -- ugly workaround for inconsistent collisions
|
|
|
|
for _,k in ipairs({'y','z','x'}) do
|
|
|
|
if new_velocity[k]==0 and math.abs(self.lastvelocity[k])> 0.1 then
|
|
|
|
vnew[k]=-self.lastvelocity[k]*self.springiness
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2024-10-05 11:27:56 +02:00
|
|
|
|
2023-07-16 20:37:23 -03:00
|
|
|
if not vector.equals(new_velocity,vnew) then
|
|
|
|
self.collided = true
|
|
|
|
else
|
|
|
|
if self.collided then
|
|
|
|
vnew = vector.new(self.lastvelocity)
|
|
|
|
end
|
|
|
|
self.collided = false
|
|
|
|
end
|
|
|
|
new_velocity = vnew
|
|
|
|
end
|
2023-07-17 18:57:56 -03:00
|
|
|
|
|
|
|
--damage if the friction is below .97
|
|
|
|
if self._last_longit_speed then
|
|
|
|
if friction <= 0.97 and self._last_longit_speed > 0 then
|
|
|
|
self.hp_max = self.hp_max - 0.001
|
|
|
|
airutils.setText(self, self._vehicle_name)
|
|
|
|
end --damage the plane if it have hard friction
|
|
|
|
end
|
|
|
|
|
2023-10-11 19:51:55 -03:00
|
|
|
--self.object:set_velocity(new_velocity)
|
2023-10-27 19:30:18 -03:00
|
|
|
--new_velocity = vector.subtract(new_velocity,vel)
|
2023-10-29 19:28:42 -03:00
|
|
|
|
|
|
|
--fix bug with unexpe3cted moving
|
|
|
|
if not self.driver_name and math.abs(vel.x) < 0.2 and math.abs(vel.z) < 0.2 then
|
2023-10-29 19:21:32 -03:00
|
|
|
self.object:set_velocity({x=0,y=airutils.gravity*self.dtime,z=0})
|
2023-10-29 19:28:42 -03:00
|
|
|
if self.wheels then self.wheels:set_animation_frame_speed(0) end
|
2023-10-29 19:21:32 -03:00
|
|
|
return
|
|
|
|
end
|
2023-10-29 17:46:14 -03:00
|
|
|
end
|
2023-10-27 19:30:18 -03:00
|
|
|
|
2023-10-29 18:05:38 -03:00
|
|
|
self.object:add_velocity(new_velocity)
|
2023-06-11 17:29:08 -03:00
|
|
|
end
|
2023-07-16 20:37:23 -03:00
|
|
|
|