195 lines
6.3 KiB
Lua
Executable File
195 lines
6.3 KiB
Lua
Executable File
--global constants
|
|
|
|
helicopter.tilting_speed = 1
|
|
helicopter.tilting_max = 0.20
|
|
helicopter.power_max = 15
|
|
helicopter.power_min = 0.2 -- if negative, the helicopter can actively fly downwards
|
|
helicopter.wanted_vert_speed = 5
|
|
|
|
helicopter.vector_up = vector.new(0, 1, 0)
|
|
helicopter.vector_forward = vector.new(0, 0, 1)
|
|
|
|
helicopter.last_time_command = 0
|
|
|
|
function helicopter.vector_length_sq(v)
|
|
return v.x * v.x + v.y * v.y + v.z * v.z
|
|
end
|
|
|
|
if not minetest.global_exists("matrix3") then
|
|
dofile(minetest.get_modpath("nss_helicopter") .. DIR_DELIM .. "matrix.lua")
|
|
end
|
|
|
|
function helicopter.check_node_below(obj)
|
|
local pos_below = obj:get_pos()
|
|
pos_below.y = pos_below.y - 0.1
|
|
local node_below = minetest.get_node(pos_below).name
|
|
local nodedef = minetest.registered_nodes[node_below]
|
|
local touching_ground = not nodedef or -- unknown nodes are solid
|
|
nodedef.walkable or false
|
|
local liquid_below = not touching_ground and nodedef.liquidtype ~= "none"
|
|
return touching_ground, liquid_below
|
|
end
|
|
|
|
function helicopter.heli_control(self, dtime, touching_ground, liquid_below, vel_before)
|
|
helicopter.last_time_command = helicopter.last_time_command + dtime
|
|
if helicopter.last_time_command > 1 then helicopter.last_time_command = 1 end
|
|
|
|
if self.driver_name == nil then
|
|
return
|
|
end
|
|
local driver = minetest.get_player_by_name(self.driver_name)
|
|
|
|
if not driver then
|
|
-- there is no driver (eg. because driver left)
|
|
self.driver_name = nil
|
|
if self.sound_handle then
|
|
minetest.sound_stop(self.sound_handle)
|
|
self.sound_handle = nil
|
|
end
|
|
self.object:set_animation_frame_speed(0)
|
|
-- gravity
|
|
self.object:set_acceleration(vector.multiply(helicopter.vector_up, -helicopter.gravity))
|
|
return
|
|
end
|
|
|
|
local ctrl = driver:get_player_control()
|
|
|
|
if ctrl.aux1 and helicopter.last_time_command > 0.3 then
|
|
helicopter.last_time_command = 0
|
|
if self._by_mouse == true then
|
|
self._by_mouse = false
|
|
else
|
|
self._by_mouse = true
|
|
end
|
|
end
|
|
|
|
local rot = self.object:get_rotation()
|
|
local position = self.object:get_pos()
|
|
|
|
local max_height = 1500
|
|
local vert_vel_goal = 0
|
|
if not liquid_below then
|
|
if ctrl.jump then
|
|
local compensated_vert_speed = helicopter.wanted_vert_speed
|
|
local curr_percent_height = (100 - ((position.y * 100) / max_height))/100
|
|
compensated_vert_speed = compensated_vert_speed * curr_percent_height
|
|
vert_vel_goal = vert_vel_goal + compensated_vert_speed
|
|
end
|
|
if ctrl.sneak then
|
|
vert_vel_goal = vert_vel_goal - helicopter.wanted_vert_speed
|
|
end
|
|
else
|
|
vert_vel_goal = helicopter.wanted_vert_speed
|
|
end
|
|
|
|
-- rotation
|
|
if not touching_ground then
|
|
local rotation = self.object:get_rotation()
|
|
local yaw = rotation.y
|
|
local tilting_goal = vector.new()
|
|
if ctrl.up then
|
|
tilting_goal.z = tilting_goal.z + 4
|
|
end
|
|
if ctrl.down then
|
|
tilting_goal.z = tilting_goal.z - 4
|
|
end
|
|
if self._by_mouse == true then
|
|
if ctrl.right then
|
|
tilting_goal.x = tilting_goal.x + 4
|
|
end
|
|
if ctrl.left then
|
|
tilting_goal.x = tilting_goal.x - 4
|
|
end
|
|
else
|
|
if ctrl.right then
|
|
yaw = yaw - 0.02
|
|
tilting_goal.x = tilting_goal.x + 0.2
|
|
end
|
|
if ctrl.left then
|
|
yaw = yaw + 0.02
|
|
tilting_goal.x = tilting_goal.x - 0.2
|
|
end
|
|
end
|
|
tilting_goal = vector.multiply(vector.normalize(tilting_goal), helicopter.tilting_max)
|
|
|
|
-- tilting
|
|
if helicopter.vector_length_sq(vector.subtract(tilting_goal, self.tilting)) > (dtime * helicopter.tilting_speed)^2 then
|
|
self.tilting = vector.add(self.tilting,
|
|
vector.multiply(vector.direction(self.tilting, tilting_goal), dtime * helicopter.tilting_speed))
|
|
else
|
|
self.tilting = tilting_goal
|
|
end
|
|
if helicopter.vector_length_sq(self.tilting) > helicopter.tilting_max^2 then
|
|
self.tilting = vector.multiply(vector.normalize(self.tilting), helicopter.tilting_max)
|
|
end
|
|
local new_up = vector.new(self.tilting)
|
|
new_up.y = 1
|
|
new_up = vector.normalize(new_up) -- this is what vector_up should be after the rotation
|
|
local new_right = vector.cross(new_up, helicopter.vector_forward)
|
|
local new_forward = vector.cross(new_right, new_up)
|
|
local rot_mat = matrix3.new(
|
|
new_right.x, new_up.x, new_forward.x,
|
|
new_right.y, new_up.y, new_forward.y,
|
|
new_right.z, new_up.z, new_forward.z
|
|
)
|
|
rot = matrix3.to_pitch_yaw_roll(rot_mat)
|
|
|
|
if self._by_mouse == true then
|
|
rot.y = driver:get_look_horizontal()
|
|
else
|
|
rot.y = yaw
|
|
end
|
|
|
|
|
|
else
|
|
rot.x = 0
|
|
rot.z = 0
|
|
self.tilting.x = 0
|
|
self.tilting.z = 0
|
|
end
|
|
|
|
self.object:set_rotation(rot)
|
|
|
|
-- calculate how strong the heli should accelerate towards rotated up
|
|
local power = vert_vel_goal - vel_before.y + helicopter.gravity * dtime
|
|
power = math.min(math.max(power, helicopter.power_min * dtime), helicopter.power_max * dtime)
|
|
|
|
-- calculate energy consumption --
|
|
----------------------------------
|
|
if self.energy > 0 and touching_ground == false then
|
|
|
|
local consumed_power = (power/1500)
|
|
self.energy = self.energy - consumed_power;
|
|
|
|
local energy_indicator_angle = ((self.energy * 18) - 90) * -1
|
|
if self.pointer:get_luaentity() then
|
|
self.pointer:set_attach(self.object,'',{x=0,y=11.26,z=9.37},{x=0,y=0,z=energy_indicator_angle})
|
|
else
|
|
--in case it have lost the entity by some conflict
|
|
self.pointer=minetest.add_entity({x=0,y=11.26,z=9.37},"nss_helicopter:pointer")
|
|
self.pointer:set_attach(self.object,'',{x=0,y=11.26,z=9.37},{x=0,y=0,z=energy_indicator_angle})
|
|
end
|
|
end
|
|
if self.energy <= 0 then
|
|
power = 0.2
|
|
if touching_ground or liquid_below then
|
|
--criar uma fucao pra isso pois ela repete na linha 268
|
|
-- sound and animation
|
|
if self.sound_handle then minetest.sound_stop(self.sound_handle) end
|
|
self.object:set_animation_frame_speed(0)
|
|
-- gravity
|
|
self.object:set_acceleration(vector.multiply(helicopter.vector_up, -helicopter.gravity))
|
|
end
|
|
end
|
|
----------------------------
|
|
-- end energy consumption --
|
|
|
|
|
|
local rotated_up = matrix3.multiply(matrix3.from_pitch_yaw_roll(rot), helicopter.vector_up)
|
|
local added_vel = vector.multiply(rotated_up, power)
|
|
added_vel = vector.add(added_vel, vector.multiply(helicopter.vector_up, -helicopter.gravity * dtime))
|
|
return vector.add(vel_before, added_vel)
|
|
end
|
|
|
|
|