2025-02-15 09:12:56 -03:00
dofile ( core.get_modpath ( " airutils " ) .. DIR_DELIM .. " lib_planes " .. DIR_DELIM .. " global_definitions.lua " )
2023-06-11 17:29:08 -03:00
2024-01-27 02:06:23 +01:00
local S = airutils.S
2024-06-30 11:27:45 -03:00
local function lib_change_color ( self , colstr )
2023-06-13 12:09:13 -03:00
airutils.param_paint ( self , colstr )
2023-06-11 17:29:08 -03:00
end
function airutils . get_staticdata ( self ) -- unloaded/unloads ... is now saved
2025-02-15 09:12:56 -03:00
return core.serialize ( {
2023-06-11 17:29:08 -03:00
--stored_sound_handle = self.sound_handle,
2024-01-23 21:38:27 -03:00
stored_energy = self._energy or 0 ,
stored_owner = self.owner or " " ,
stored_hp = self.hp_max or 10 ,
stored_color = self._color or " #FFFFFF " ,
stored_color_2 = self._color_2 or " #FFFFFF " ,
stored_power_lever = self._power_lever or 0 ,
stored_driver_name = self.driver_name or nil ,
stored_last_accell = self._last_accell or vector.new ( ) ,
stored_inv_id = self._inv_id or nil ,
stored_flap = self._flap or false ,
stored_passengers = self._passengers or { } ,
stored_adf_destiny = self._adf_destiny or vector.new ( ) ,
stored_skin = self._skin or " " ,
2024-02-12 19:41:23 -03:00
stored_vehicle_custom_data = self._vehicle_custom_data or nil ,
stored_ship_name = self._ship_name or " " ,
2024-03-10 13:29:00 -03:00
remove = self._remove or false ,
2023-06-11 17:29:08 -03:00
} )
end
function airutils . on_deactivate ( self )
airutils.save_inventory ( self )
2023-11-15 22:01:47 -03:00
local pos = self.object : get_pos ( )
if airutils.debug_log then
2025-02-15 09:12:56 -03:00
core.log ( " action " , " deactivating: " .. self._vehicle_name .. " from " .. self.owner .. " at position " .. math.floor ( pos.x ) .. " , " .. math.floor ( pos.y ) .. " , " .. math.floor ( pos.z ) )
2023-11-15 22:01:47 -03:00
end
2023-06-11 17:29:08 -03:00
end
function airutils . on_activate ( self , staticdata , dtime_s )
2025-02-09 08:24:03 -03:00
if not self.object then return end
2023-11-15 22:01:47 -03:00
local pos = self.object : get_pos ( )
2023-06-11 17:29:08 -03:00
airutils.actfunc ( self , staticdata , dtime_s )
2023-07-04 21:20:39 -03:00
self._flap = false
2023-07-02 15:16:07 -03:00
2023-06-11 17:29:08 -03:00
if staticdata ~= " " and staticdata ~= nil then
2025-02-15 09:12:56 -03:00
local data = core.deserialize ( staticdata ) or { }
2024-01-23 21:38:27 -03:00
self._energy = data.stored_energy or 0
self.owner = data.stored_owner or " "
self.hp_max = data.stored_hp or 10
self._color = data.stored_color or " #FFFFFF "
2023-07-13 21:40:40 -03:00
self._color_2 = data.stored_color_2 or data.stored_color --if it has no color 2, now it have!
2024-01-23 21:38:27 -03:00
self._power_lever = data.stored_power_lever or 0
self.driver_name = data.stored_driver_name or nil
self._last_accell = data.stored_last_accell or vector.new ( )
self._inv_id = data.stored_inv_id or nil
if self._wing_angle_extra_flaps then self._flap = data.stored_flap or false end
2023-07-02 15:16:07 -03:00
self._passengers = data.stored_passengers or { }
2023-07-05 21:58:01 -03:00
self._adf_destiny = data.stored_adf_destiny or vector.new ( )
2024-01-23 21:38:27 -03:00
self._skin = data.stored_skin or " "
2024-02-12 19:41:23 -03:00
self._ship_name = data.stored_ship_name or " "
2024-03-10 13:29:00 -03:00
self._remove = data.remove or false
2024-01-23 21:38:27 -03:00
local custom_data = data.stored_vehicle_custom_data or nil
2023-06-20 20:42:35 -03:00
if custom_data then
self._vehicle_custom_data = custom_data
else
-- o macete aqui eh inicializar mesmo que não exista no escopo da entity
self._vehicle_custom_data = { } --initialize it
end
2025-02-15 09:12:56 -03:00
--core.debug("loaded: ", self._energy)
2023-06-11 17:29:08 -03:00
if self._engine_running then
self._last_applied_power = - 1 --signal to start
end
2024-03-03 17:50:54 -03:00
2024-03-10 13:29:00 -03:00
if self._remove == true then
2024-03-09 09:47:50 -03:00
airutils.destroy_inventory ( self )
2024-03-03 17:50:54 -03:00
self.object : remove ( )
return
end
2023-06-11 17:29:08 -03:00
end
2024-10-05 11:27:56 +02:00
2023-07-02 16:42:20 -03:00
self._climb_rate = 0
self._yaw = 0
self._roll = 0
self._pitch = 0
2023-07-02 15:16:07 -03:00
2023-11-15 22:01:47 -03:00
if airutils.debug_log then
2025-02-15 09:12:56 -03:00
core.log ( " action " , " activating: " .. self._vehicle_name .. " from " .. self.owner .. " at position " .. math.floor ( pos.x ) .. " , " .. math.floor ( pos.y ) .. " , " .. math.floor ( pos.z ) )
2023-11-15 22:01:47 -03:00
end
2023-06-11 17:29:08 -03:00
if self._register_parts_method then
self._register_parts_method ( self )
end
2023-06-18 13:59:31 -03:00
airutils.param_paint ( self , self._color , self._color_2 )
2023-06-11 17:29:08 -03:00
self.object : set_armor_groups ( { immortal = 1 } )
2023-07-08 13:08:34 -03:00
local start_frame = 1
local end_frame = self._anim_frames
if self._anim_start_frame then
start_frame = self._anim_start_frame
end_frame = self._anim_start_frame + self._anim_frames
2024-10-05 11:27:56 +02:00
end
2023-07-08 13:08:34 -03:00
self.object : set_animation ( { x = start_frame , y = end_frame } , 0 , 0 , true )
2023-06-11 17:29:08 -03:00
if self.wheels then
self.wheels : set_animation ( { x = 1 , y = self._anim_frames } , 0 , 0 , true )
end
2024-01-23 21:38:27 -03:00
local inv = nil
if self._inv_id then
2025-02-15 09:12:56 -03:00
inv = core.get_inventory ( { type = " detached " , name = self._inv_id } )
2024-01-23 21:38:27 -03:00
end
2023-06-11 17:29:08 -03:00
-- if the game was closed the inventories have to be made anew, instead of just reattached
if not inv then
airutils.create_inventory ( self , self._trunk_slots )
else
2023-11-20 14:36:24 -03:00
self._inv = inv
2023-06-11 17:29:08 -03:00
end
2023-06-18 22:14:27 -03:00
2024-03-29 15:54:56 -03:00
--airutils.seats_create(self)
2023-07-02 11:38:36 -03:00
self._passengers = { }
2023-06-20 20:42:35 -03:00
if not self._vehicle_custom_data then self._vehicle_custom_data = { } end --initialize when it does not exists
2023-07-03 18:37:55 -03:00
if self._flap then airutils.flap_on ( self ) end
2024-01-23 21:38:27 -03:00
if self._vehicle_name then airutils.setText ( self , self._vehicle_name ) end
2024-06-30 11:27:45 -03:00
self._change_color = lib_change_color
2024-09-21 12:59:27 -03:00
--initialize array with seats
airutils.seats_create ( self )
2023-06-11 17:29:08 -03:00
end
function airutils . on_step ( self , dtime , colinfo )
self.dtime = math.min ( dtime , 0.2 )
self.colinfo = colinfo
self.height = airutils.get_box_height ( self )
2024-10-05 11:27:56 +02:00
2025-02-09 08:24:03 -03:00
if not self.object then return end
2023-06-11 17:29:08 -03:00
-- physics comes first
local vel = self.object : get_velocity ( )
2023-10-14 17:56:14 +02:00
local pos = self.object : get_pos ( )
local props = self.object : get_properties ( )
-- handle visibility on radar
if ( pos and pos.y < airutils.radarMinHeight and props.show_on_minimap ) then
props.show_on_minimap = false
self.object : set_properties ( props )
end
if ( pos and pos.y >= airutils.radarMinHeight and not props.show_on_minimap ) then
props.show_on_minimap = true
self.object : set_properties ( props )
end
2023-11-08 18:49:53 -03:00
if self.isonground and props.show_on_minimap then
2023-10-14 18:20:39 +02:00
props.show_on_minimap = false
2023-10-27 19:42:09 -03:00
self.object : set_properties ( props )
2023-10-14 18:20:39 +02:00
end
2024-10-05 11:27:56 +02:00
if colinfo then
2023-06-11 17:29:08 -03:00
self.isonground = colinfo.touching_ground
else
if self.lastvelocity . y == 0 and vel.y == 0 then
self.isonground = true
else
self.isonground = false
end
end
2024-10-05 11:27:56 +02:00
2025-02-09 08:24:03 -03:00
if self.hp_max then
if self.hp_max <= 0 then
airutils.destroy ( self )
end
2023-08-24 20:14:00 -03:00
end
2023-06-11 17:29:08 -03:00
self : physics ( )
if self.logic then
self : logic ( )
end
2024-10-05 11:27:56 +02:00
2023-06-11 17:29:08 -03:00
self.lastvelocity = self.object : get_velocity ( )
self.time_total = self.time_total + self.dtime
end
2023-06-29 20:04:13 -03:00
local function ground_pitch ( self , longit_speed , curr_pitch )
2023-11-08 18:49:53 -03:00
local newpitch = curr_pitch
2023-06-29 21:44:38 -03:00
if self._last_longit_speed == nil then self._last_longit_speed = 0 end
-- Estado atual do sistema
if self._current_value == nil then self._current_value = 0 end -- Valor atual do sistema
if self._last_error == nil then self._last_error = 0 end -- Último erro registrado
2023-06-29 20:04:13 -03:00
-- adjust pitch at ground
if math.abs ( longit_speed ) < self._tail_lift_max_speed then
local speed_range = self._tail_lift_max_speed - self._tail_lift_min_speed
local percentage = 1 - ( ( math.abs ( longit_speed ) - self._tail_lift_min_speed ) / speed_range )
if percentage > 1 then percentage = 1 end
if percentage < 0 then percentage = 0 end
local angle = self._tail_angle * percentage
2023-06-29 21:44:38 -03:00
local rad_angle = math.rad ( angle )
if newpitch < rad_angle then newpitch = rad_angle end --ja aproveita o pitch atual se ja estiver cerrto
--[[self._current_value = curr_pitch
local kp = ( longit_speed - self._tail_lift_min_speed ) / 10
local output , last_error = airutils.pid_controller ( self._current_value , rad_angle , self._last_error , self.dtime , kp )
self._last_error = last_error
newpitch = output ] ] --
2023-06-29 20:04:13 -03:00
if newpitch > math.rad ( self._tail_angle ) then newpitch = math.rad ( self._tail_angle ) end --não queremos arrastar o cauda no chão
end
2024-10-05 11:27:56 +02:00
2023-06-29 20:04:13 -03:00
return newpitch
end
2023-06-11 17:29:08 -03:00
function airutils . logic ( self )
local velocity = self.object : get_velocity ( )
2024-03-09 21:30:39 -03:00
local rem_obj = self.object : get_attach ( )
local extern_ent = nil
if rem_obj then
extern_ent = rem_obj : get_luaentity ( )
end
2023-06-11 17:29:08 -03:00
local curr_pos = self.object : get_pos ( )
2023-07-06 20:25:01 -03:00
self._curr_pos = curr_pos --shared
2023-10-27 19:30:18 -03:00
self._last_accel = self.object : get_acceleration ( )
2023-06-11 17:29:08 -03:00
self._last_time_command = self._last_time_command + self.dtime
if self._last_time_command > 1 then self._last_time_command = 1 end
local player = nil
2025-02-15 09:12:56 -03:00
if self.driver_name then player = core.get_player_by_name ( self.driver_name ) end
2023-07-03 19:22:37 -03:00
local co_pilot = nil
2025-02-15 09:12:56 -03:00
if self.co_pilot and self._have_copilot then co_pilot = core.get_player_by_name ( self.co_pilot ) end
2023-06-11 17:29:08 -03:00
2023-11-20 14:36:24 -03:00
--test collision
airutils.testImpact ( self , velocity , curr_pos )
2024-03-12 20:49:26 -03:00
--if self._autoflymode == true then airutils.seats_update(self) end
2024-03-12 20:42:44 -03:00
2023-06-11 17:29:08 -03:00
if player then
local ctrl = player : get_player_control ( )
---------------------
-- change the driver
---------------------
2023-07-06 21:31:15 -03:00
if co_pilot and self._have_copilot and self._last_time_command >= 1 then
2023-06-11 17:29:08 -03:00
if self._command_is_given == true then
if ctrl.sneak or ctrl.jump or ctrl.up or ctrl.down or ctrl.right or ctrl.left then
self._last_time_command = 0
--take the control
airutils.transfer_control ( self , false )
end
else
2023-07-06 21:31:15 -03:00
if ctrl.sneak == true and ctrl.jump == true then
2023-06-11 17:29:08 -03:00
self._last_time_command = 0
--trasnfer the control to student
airutils.transfer_control ( self , true )
2023-07-06 21:31:15 -03:00
end
2023-06-11 17:29:08 -03:00
end
end
-----------
--autopilot
-----------
if self._instruction_mode == false and self._last_time_command >= 1 then
if self._autopilot == true then
if ctrl.sneak or ctrl.jump or ctrl.up or ctrl.down or ctrl.right or ctrl.left then
self._last_time_command = 0
self._autopilot = false
2025-02-15 09:12:56 -03:00
core.chat_send_player ( self.driver_name , S ( " >>> Autopilot deactivated " ) )
2023-06-11 17:29:08 -03:00
end
else
2023-07-06 21:31:15 -03:00
if ctrl.sneak == true and ctrl.jump == true and self._have_auto_pilot then
2023-06-11 17:29:08 -03:00
self._last_time_command = 0
self._autopilot = true
self._auto_pilot_altitude = curr_pos.y
2025-02-15 09:12:56 -03:00
core.chat_send_player ( self.driver_name , core.colorize ( ' #00ff00 ' , S ( " >>> Autopilot activated " ) ) )
if self.driver_name then
core.sound_play ( " airutils_beep " , {
to_player = self.driver_name ,
gain = 1.0 ,
fade = 0.0 ,
pitch = 0.7 ,
} , true )
end
2023-06-11 17:29:08 -03:00
end
end
end
end
2023-08-24 20:14:00 -03:00
if not self.object : get_acceleration ( ) then return end
2023-06-11 17:29:08 -03:00
local accel_y = self.object : get_acceleration ( ) . y
local rotation = self.object : get_rotation ( )
local yaw = rotation.y
local newyaw = yaw
local roll = rotation.z
local newroll = roll
newroll = math.floor ( newroll / 360 )
newroll = newroll * 360
2025-02-15 09:12:56 -03:00
local hull_direction = airutils.rot_to_dir ( rotation ) --core.yaw_to_dir(yaw)
2023-06-11 17:29:08 -03:00
local nhdir = { x = hull_direction.z , y = 0 , z =- hull_direction.x } -- lateral unit vector
local longit_speed = vector.dot ( velocity , hull_direction )
2024-03-09 21:30:39 -03:00
if extern_ent then
if extern_ent.curr_speed then longit_speed = extern_ent.curr_speed end
2025-02-15 09:12:56 -03:00
--core.chat_send_all(dump(longit_speed))
2024-03-09 21:30:39 -03:00
end
2023-06-11 17:29:08 -03:00
self._longit_speed = longit_speed
local longit_drag = vector.multiply ( hull_direction , longit_speed *
longit_speed * self._longit_drag_factor *- 1 * airutils.sign ( longit_speed ) )
local later_speed = airutils.dot ( velocity , nhdir )
2025-02-15 09:12:56 -03:00
--core.chat_send_all('later_speed: '.. later_speed)
2023-06-11 17:29:08 -03:00
local later_drag = vector.multiply ( nhdir , later_speed * later_speed *
self._later_drag_factor *- 1 * airutils.sign ( later_speed ) )
local accel = vector.add ( longit_drag , later_drag )
local stop = false
local is_flying = true
if self.colinfo then
2023-07-17 10:32:38 -03:00
is_flying = ( not self.colinfo . touching_ground ) and ( self.isinliquid == false )
2024-03-09 21:30:39 -03:00
else
--special routine for automated plane
if extern_ent then
if not extern_ent.on_rightclick then
2024-03-10 11:24:40 -03:00
local touch_point = ( self.initial_properties . collisionbox [ 2 ] ) - 0.5
2024-03-09 21:30:39 -03:00
local node_bellow = airutils.nodeatpos ( airutils.pos_shift ( curr_pos , { y = touch_point } ) )
2025-02-15 09:12:56 -03:00
--core.chat_send_all(dump(node_bellow.drawtype))
2024-03-09 21:30:39 -03:00
if ( node_bellow and node_bellow.drawtype ~= ' airlike ' ) then
is_flying = false
end
end
end
2023-06-11 17:29:08 -03:00
end
2025-02-15 09:12:56 -03:00
--core.chat_send_all(dump(is_flying))
--if is_flying then core.chat_send_all('is flying') end
2023-06-11 17:29:08 -03:00
local is_attached = airutils.checkAttach ( self , player )
2023-06-28 19:48:53 -03:00
if self._indicated_speed == nil then self._indicated_speed = 0 end
2023-06-11 17:29:08 -03:00
2024-03-15 21:06:21 -03:00
-- for some engine error the player can be detached from the machine, so lets set him attached again
airutils.checkattachBug ( self )
2023-06-11 17:29:08 -03:00
2023-06-28 19:48:53 -03:00
if self._custom_step_additional_function then
self._custom_step_additional_function ( self )
end
2023-09-14 19:08:51 -03:00
--fix old planes
if not self._flap then self._flap = false end
if not self._wing_configuration then self._wing_configuration = self._wing_angle_of_attack end
2023-07-03 18:37:55 -03:00
if self._wing_configuration == self._wing_angle_of_attack and self._flap then
airutils.flap_on ( self )
end
if self._wing_configuration ~= self._wing_angle_of_attack and self._flap == false then
airutils.flap_off ( self )
end
2023-07-04 21:20:39 -03:00
--landing light
if self._have_landing_lights then
airutils.landing_lights_operate ( self )
end
2023-08-26 14:34:02 -03:00
--smoke and fire
if self._engine_running then
local curr_health_percent = ( self.hp_max * 100 ) / self._max_plane_hp
if curr_health_percent < 20 then
airutils.add_smoke_trail ( self , 2 )
elseif curr_health_percent < 50 then
airutils.add_smoke_trail ( self , 1 )
end
else
if self._smoke_spawner and not self._smoke_semaphore then
self._smoke_semaphore = 1 --to set it only one time
2025-02-15 09:12:56 -03:00
core.after ( 5 , function ( )
2023-08-26 14:34:02 -03:00
if self._smoke_spawner then
2025-02-15 09:12:56 -03:00
core.delete_particlespawner ( self._smoke_spawner )
2023-08-26 14:34:02 -03:00
self._smoke_spawner = nil
self._smoke_semaphore = nil
end
end )
end
end
2023-10-29 20:12:03 -03:00
--adjust elevator pitch (3d model)
self.object : set_bone_position ( " elevator " , self._elevator_pos , { x =- self._elevator_angle * 2 - 90 , y = 0 , z = 0 } )
--adjust rudder
self.object : set_bone_position ( " rudder " , self._rudder_pos , { x = 0 , y = self._rudder_angle , z = 0 } )
--adjust ailerons
if self._aileron_r_pos and self._aileron_l_pos then
local ailerons = self._rudder_angle
if self._invert_ailerons then ailerons = ailerons * - 1 end
self.object : set_bone_position ( " aileron.r " , self._aileron_r_pos , { x =- ailerons - 90 , y = 0 , z = 0 } )
self.object : set_bone_position ( " aileron.l " , self._aileron_l_pos , { x = ailerons - 90 , y = 0 , z = 0 } )
end
2023-08-26 14:34:02 -03:00
2023-10-29 19:50:41 -03:00
if ( math.abs ( velocity.x ) < 0.1 and math.abs ( velocity.z ) < 0.1 ) and is_flying == false and is_attached == false and self._engine_running == false then
2023-10-29 20:02:45 -03:00
if self._ground_friction then
2023-11-13 20:37:47 -03:00
if not self.isinliquid then self.object : set_velocity ( { x = 0 , y = airutils.gravity * self.dtime , z = 0 } ) end
2023-10-29 20:02:45 -03:00
end
2023-06-11 17:29:08 -03:00
return
end
2023-06-13 18:02:41 -03:00
--adjust climb indicator
2023-10-26 22:28:38 -03:00
local y_velocity = 0
if self._engine_running or is_flying then y_velocity = velocity.y end
local climb_rate = y_velocity
2023-06-13 18:02:41 -03:00
if climb_rate > 5 then climb_rate = 5 end
if climb_rate < - 5 then
climb_rate = - 5
2023-06-11 17:29:08 -03:00
end
-- pitch
2023-10-26 22:28:38 -03:00
local newpitch = airutils.get_plane_pitch ( y_velocity , longit_speed , self._min_speed , self._angle_of_attack )
2023-06-11 17:29:08 -03:00
2023-09-03 19:49:20 -03:00
--for airplanes with cannard or pendulum wing
local actuator_angle = self._elevator_angle
if self._inverted_pitch_reaction then actuator_angle = - 1 * self._elevator_angle end
2023-06-13 18:02:41 -03:00
--is an stall, force a recover
2023-06-18 12:42:59 -03:00
if longit_speed < ( self._min_speed + 0.5 ) and climb_rate < - 1.5 and is_flying then
2024-10-05 11:27:56 +02:00
--[[
2023-06-18 12:42:59 -03:00
if player and self.driver_name then
2025-02-15 09:12:56 -03:00
core.chat_send_player ( self.driver_name , core.colorize ( ' #ff0000 ' , " >>> STALL " ) )
2023-06-18 12:42:59 -03:00
end
2024-10-05 11:27:56 +02:00
] ] --
2023-06-13 18:02:41 -03:00
self._elevator_angle = 0
2023-06-18 12:42:59 -03:00
self._angle_of_attack = - 1
2023-06-13 18:02:41 -03:00
newpitch = math.rad ( self._angle_of_attack )
else
--ajustar angulo de ataque
2023-07-17 13:15:14 -03:00
if longit_speed > self._min_speed then
2023-06-13 18:02:41 -03:00
local percentage = math.abs ( ( ( longit_speed * 100 ) / ( self._min_speed + 5 ) ) / 100 )
if percentage > 1.5 then percentage = 1.5 end
2023-09-13 20:25:18 -03:00
2023-09-03 19:49:20 -03:00
self._angle_of_attack = self._wing_angle_of_attack - ( ( actuator_angle / self._elevator_response_attenuation ) * percentage )
2023-06-13 18:02:41 -03:00
2023-09-13 20:25:18 -03:00
--airutils.adjust_attack_angle_by_speed(angle_of_attack, min_angle, max_angle, limit, longit_speed, ideal_step, dtime)
2023-09-13 20:28:27 -03:00
self._angle_of_attack = airutils.adjust_attack_angle_by_speed ( self._angle_of_attack , self._min_attack_angle , self._max_attack_angle , 40 , longit_speed , airutils.ideal_step , self.dtime )
2023-06-13 18:02:41 -03:00
if self._angle_of_attack < self._min_attack_angle then
self._angle_of_attack = self._min_attack_angle
2023-09-03 19:49:20 -03:00
actuator_angle = actuator_angle - 0.2
2023-06-13 18:02:41 -03:00
end --limiting the negative angle]]--
--[[if self._angle_of_attack > self._max_attack_angle then
self._angle_of_attack = self._max_attack_angle
2023-09-03 19:49:20 -03:00
actuator_angle = actuator_angle + 0.2
2023-06-13 18:02:41 -03:00
end --limiting the very high climb angle due to strange behavior]]--]]--
2023-09-03 19:49:20 -03:00
if self._inverted_pitch_reaction then self._elevator_angle = - 1 * actuator_angle end --revert the reversion
2024-10-05 11:27:56 +02:00
2023-06-13 18:02:41 -03:00
end
end
2025-02-15 09:12:56 -03:00
--core.chat_send_all(self._angle_of_attack)
2023-06-11 17:29:08 -03:00
-- adjust pitch at ground
2023-07-17 13:15:14 -03:00
if math.abs ( longit_speed ) > self._tail_lift_min_speed and is_flying == false then
2023-06-29 20:04:13 -03:00
newpitch = ground_pitch ( self , longit_speed , newpitch )
2023-06-11 17:29:08 -03:00
else
2023-06-13 18:02:41 -03:00
if math.abs ( longit_speed ) < self._tail_lift_min_speed then
2023-06-11 17:29:08 -03:00
newpitch = math.rad ( self._tail_angle )
end
end
-- new yaw
if math.abs ( self._rudder_angle ) > 1.5 then
2023-07-02 11:38:36 -03:00
local turn_rate = math.rad ( self._yaw_turn_rate )
2023-06-11 17:29:08 -03:00
local yaw_turn = self.dtime * math.rad ( self._rudder_angle ) * turn_rate *
airutils.sign ( longit_speed ) * math.abs ( longit_speed / 2 )
newyaw = yaw + yaw_turn
end
--roll adjust
---------------------------------
local delta = 0.002
if is_flying then
local roll_reference = newyaw
2025-02-15 09:12:56 -03:00
local sdir = core.yaw_to_dir ( roll_reference )
2023-06-11 17:29:08 -03:00
local snormal = { x = sdir.z , y = 0 , z =- sdir.x } -- rightside, dot is negative
local prsr = airutils.dot ( snormal , nhdir )
local rollfactor = - 90
local roll_rate = math.rad ( 10 )
newroll = ( prsr * math.rad ( rollfactor ) ) * ( later_speed * roll_rate ) * airutils.sign ( longit_speed )
--[[local rollRotation = -self._rudder_angle * 0.1
newroll = rollRotation ] ] --
2025-02-15 09:12:56 -03:00
--core.chat_send_all('newroll: '.. newroll)
2023-06-11 17:29:08 -03:00
else
delta = 0.2
if roll > 0 then
newroll = roll - delta
if newroll < 0 then newroll = 0 end
end
if roll < 0 then
newroll = roll + delta
if newroll > 0 then newroll = 0 end
end
end
---------------------------------
-- end roll
local pilot = player
2023-07-03 19:22:37 -03:00
if self._have_copilot then
if self._command_is_given and co_pilot then
pilot = co_pilot
else
self._command_is_given = false
end
2023-06-11 17:29:08 -03:00
end
------------------------------------------------------
--accell calculation block
------------------------------------------------------
2023-07-03 19:22:37 -03:00
if is_attached or co_pilot then
2023-06-11 17:29:08 -03:00
if self._autopilot ~= true then
accel , stop = airutils.control ( self , self.dtime , hull_direction ,
longit_speed , longit_drag , later_speed , later_drag , accel , pilot , is_flying )
else
accel = airutils.autopilot ( self , self.dtime , hull_direction , longit_speed , accel , curr_pos )
end
end
--end accell
2023-07-02 15:16:07 -03:00
--get disconnected players
2024-10-05 11:27:56 +02:00
if self._autoflymode ~= true then
2024-03-15 20:18:39 -03:00
airutils.rescueConnectionFailedPassengers ( self )
end
2023-07-02 15:16:07 -03:00
2023-06-11 17:29:08 -03:00
if accel == nil then accel = { x = 0 , y = 0 , z = 0 } end
--lift calculation
accel.y = accel_y
--lets apply some bob in water
if self.isinliquid then
2023-07-17 04:55:29 -03:00
local bob = airutils.minmax ( airutils.dot ( accel , hull_direction ) , 0.02 ) -- vertical bobbing
2023-07-16 20:37:23 -03:00
if bob < 0 then bob = 0 end
2023-06-11 17:29:08 -03:00
accel.y = accel.y + bob
local max_pitch = 6
2023-07-16 20:37:23 -03:00
local ref_speed = longit_speed * 20
if ref_speed < 0 then ref_speed = 0 end
local h_vel_compensation = ( ( ref_speed * 100 ) / max_pitch ) / 100
2023-06-11 17:29:08 -03:00
if h_vel_compensation < 0 then h_vel_compensation = 0 end
if h_vel_compensation > max_pitch then h_vel_compensation = max_pitch end
2025-02-15 09:12:56 -03:00
--core.chat_send_all(h_vel_compensation)
2023-06-11 17:29:08 -03:00
newpitch = newpitch + ( velocity.y * math.rad ( max_pitch - h_vel_compensation ) )
2024-08-21 20:27:59 -03:00
if airutils.use_water_particles == true and airutils.add_splash and self._splash_x_position and self.buoyancy then
local splash_frequency = 0.15
if self._last_splash == nil then self._last_splash = 0.5 else self._last_splash = self._last_splash + self.dtime end
if longit_speed >= 2.0 and self._last_vel and self._last_splash >= splash_frequency then
self._last_splash = 0
local splash_pos = vector.new ( curr_pos )
local bellow_position = self.initial_properties . collisionbox [ 2 ]
local collision_height = self.initial_properties . collisionbox [ 5 ] - bellow_position
splash_pos.y = splash_pos.y + ( bellow_position + ( collision_height * self.buoyancy ) ) - ( collision_height / 10 )
airutils.add_splash ( splash_pos , newyaw , self._splash_x_position )
end
end
2023-06-11 17:29:08 -03:00
end
local new_accel = accel
2023-06-29 20:04:13 -03:00
if longit_speed > self._min_speed * 0.66 then
--[[lets do something interesting:
here I ' ll fake the longit speed effect for takeoff, to force the airplane
2024-10-05 11:27:56 +02:00
to use more runway
2023-06-29 20:04:13 -03:00
] ] --
local factorized_longit_speed = longit_speed
if is_flying == false and airutils.quadBezier then
local takeoff_speed = self._min_speed * 4 --so first I'll consider the takeoff speed 4x the minimal flight speed
if longit_speed < takeoff_speed and longit_speed > self._min_speed then -- then if the airplane is above the mininam speed and bellow the take off
local scale = ( longit_speed * 1 ) / takeoff_speed --get a scale of current longit speed relative to takeoff speed
if scale == nil then scale = 0 end --lets avoid any nil
factorized_longit_speed = airutils.quadBezier ( scale , self._min_speed , longit_speed , longit_speed ) --here the magic happens using a bezier curve
2025-02-15 09:12:56 -03:00
--core.chat_send_all("factor: " .. factorized_longit_speed .. " - longit: " .. longit_speed .. " - scale: " .. scale)
2023-06-29 20:04:13 -03:00
if factorized_longit_speed < 0 then factorized_longit_speed = 0 end --lets avoid negative numbers
if factorized_longit_speed == nil then factorized_longit_speed = longit_speed end --and nil numbers
end
end
local ceiling = 15000
new_accel = airutils.getLiftAccel ( self , velocity , new_accel , factorized_longit_speed , roll , curr_pos , self._lift , ceiling , self._wing_span )
2023-06-11 17:29:08 -03:00
end
-- end lift
--wind effects
if longit_speed > 1.5 and airutils.wind then
local wind = airutils.get_wind ( curr_pos , 0.1 )
new_accel = vector.add ( new_accel , wind )
end
if stop ~= true then --maybe == nil
self._last_accell = new_accel
self.object : move_to ( curr_pos )
2023-10-10 22:12:23 -03:00
--airutils.set_acceleration(self.object, new_accel)
2023-10-26 20:00:05 -03:00
local limit = ( self._max_speed / self.dtime )
2023-10-25 20:15:13 -03:00
if new_accel.y > limit then new_accel.y = limit end --it isn't a rocket :/
2023-10-26 22:28:38 -03:00
2023-06-11 17:29:08 -03:00
else
if stop == true then
2023-10-29 18:05:38 -03:00
self._last_accell = vector.new ( ) --self.object:get_acceleration()
2023-06-11 17:29:08 -03:00
self.object : set_acceleration ( { x = 0 , y = 0 , z = 0 } )
self.object : set_velocity ( { x = 0 , y = 0 , z = 0 } )
end
end
if self.wheels then
if is_flying == false then --isn't flying?
--animate wheels
2023-10-29 19:38:44 -03:00
local min_speed_animation = 0.1
if math.abs ( velocity.x ) > min_speed_animation or math.abs ( velocity.z ) > min_speed_animation then
2023-06-11 17:29:08 -03:00
self.wheels : set_animation_frame_speed ( longit_speed * 10 )
else
2024-03-09 21:30:39 -03:00
if extern_ent then
self.wheels : set_animation_frame_speed ( longit_speed * 10 )
else
self.wheels : set_animation_frame_speed ( 0 )
end
2023-06-11 17:29:08 -03:00
end
else
--stop wheels
self.wheels : set_animation_frame_speed ( 0 )
end
end
------------------------------------------------------
-- end accell
------------------------------------------------------
------------------------------------------------------
-- sound and animation
------------------------------------------------------
airutils.engine_set_sound_and_animation ( self )
2023-08-26 14:34:02 -03:00
2023-06-11 17:29:08 -03:00
------------------------------------------------------
--self.object:get_luaentity() --hack way to fix jitter on climb
2023-06-17 19:08:31 -03:00
--GAUGES
2025-02-15 09:12:56 -03:00
--core.chat_send_all('rate '.. climb_rate)
2023-06-11 17:29:08 -03:00
local climb_angle = airutils.get_gauge_angle ( climb_rate )
2023-07-02 16:42:20 -03:00
self._climb_rate = climb_rate
2023-06-11 17:29:08 -03:00
local indicated_speed = longit_speed * 0.9
if indicated_speed < 0 then indicated_speed = 0 end
2023-06-25 17:52:16 -03:00
self._indicated_speed = indicated_speed
2023-06-27 22:28:58 -03:00
local speed_angle = airutils.get_gauge_angle ( indicated_speed , - 45 )
2023-06-11 17:29:08 -03:00
2023-06-17 19:08:31 -03:00
--adjust power indicator
2023-06-29 22:00:27 -03:00
local power_indicator_angle = airutils.get_gauge_angle ( self._power_lever / 10 ) + 90
2023-07-02 18:15:18 -03:00
local fuel_in_percent = ( self._energy * 1 ) / self._max_fuel
local energy_indicator_angle = ( 180 * fuel_in_percent ) - 180 --(airutils.get_gauge_angle((self._max_fuel - self._energy)*2)) - 90
2023-06-17 19:08:31 -03:00
2023-06-11 17:29:08 -03:00
if is_attached then
if self._show_hud then
2023-06-29 22:00:27 -03:00
airutils.update_hud ( player , climb_angle , speed_angle , power_indicator_angle , energy_indicator_angle )
2023-06-11 17:29:08 -03:00
else
airutils.remove_hud ( player )
end
end
if is_flying == false then
-- new yaw
local turn_rate = math.rad ( 30 )
local yaw_turn = self.dtime * math.rad ( self._rudder_angle ) * turn_rate *
airutils.sign ( longit_speed ) * math.abs ( longit_speed / 2 )
newyaw = yaw + yaw_turn
end
2023-07-02 17:15:55 -03:00
if player and self._use_camera_relocation then
2025-02-15 09:12:56 -03:00
--core.chat_send_all(dump(newroll))
2023-06-27 20:21:25 -03:00
local new_eye_offset = airutils.camera_reposition ( player , newpitch , newroll )
2023-06-25 19:19:28 -03:00
player : set_eye_offset ( new_eye_offset , { x = 0 , y = 1 , z = - 30 } )
end
2023-06-11 17:29:08 -03:00
--apply rotations
self.object : set_rotation ( { x = newpitch , y = newyaw , z = newroll } )
--end
2023-07-08 15:50:29 -03:00
if ( longit_speed / 2 ) > self._max_speed and self._flap == true then
2023-07-02 15:16:07 -03:00
if is_attached and self.driver_name then
2025-02-15 09:12:56 -03:00
core.chat_send_player ( self.driver_name , core.colorize ( ' #ff0000 ' , S ( " >>> Flaps retracted due for overspeed " ) ) )
2023-07-02 15:16:07 -03:00
end
self._flap = false
end
2023-06-11 17:29:08 -03:00
-- calculate energy consumption --
airutils.consumptionCalc ( self , accel )
--saves last velocity for collision detection (abrupt stop)
2023-10-27 19:30:18 -03:00
self._last_accel = new_accel
2023-06-11 17:29:08 -03:00
self._last_vel = self.object : get_velocity ( )
2023-06-29 21:44:38 -03:00
self._last_longit_speed = longit_speed
2023-07-02 16:42:20 -03:00
self._yaw = newyaw
self._roll = newroll
self._pitch = newpitch
2023-06-11 17:29:08 -03:00
end
2023-06-18 22:14:27 -03:00
local function damage_vehicle ( self , toolcaps , ttime , damage )
2024-02-08 13:54:43 -03:00
damage = damage or 0
2023-10-01 17:21:48 +02:00
if ( not toolcaps ) then
return
2023-06-18 22:14:27 -03:00
end
2023-11-08 18:49:53 -03:00
local value = toolcaps.damage_groups . fleshy or 0
2023-10-01 17:21:48 +02:00
if ( toolcaps.damage_groups . vehicle ) then
value = toolcaps.damage_groups . vehicle
end
damage = damage + value / 10
self.hp_max = self.hp_max - damage
2025-01-31 20:58:06 -03:00
if self.hp_max < 0 then self.hp_max = 0 end
2023-10-01 17:21:48 +02:00
airutils.setText ( self , self._vehicle_name )
2023-06-18 22:14:27 -03:00
end
2023-06-11 17:29:08 -03:00
function airutils . on_punch ( self , puncher , ttime , toolcaps , dir , damage )
2023-11-15 12:04:13 +01:00
local name = " "
local ppos = { }
if not puncher or not puncher : is_player ( ) then
return
end
if ( puncher : is_player ( ) ) then
name = puncher : get_player_name ( )
ppos = puncher : get_pos ( )
2025-02-15 09:12:56 -03:00
if ( core.is_protected ( ppos , name ) and
2023-11-15 12:47:40 +01:00
airutils.protect_in_areas ) then
2023-11-15 12:04:13 +01:00
return
end
end
2023-06-17 19:08:31 -03:00
if self.hp_max <= 0 then
2023-07-02 11:38:36 -03:00
airutils.destroy ( self , name )
2023-11-20 14:36:24 -03:00
return
2023-06-17 19:08:31 -03:00
end
2024-01-23 21:38:27 -03:00
if self._vehicle_name then airutils.setText ( self , self._vehicle_name ) end
2023-06-18 22:14:27 -03:00
2024-10-05 11:27:56 +02:00
if ( string.find ( puncher : get_wielded_item ( ) : get_name ( ) , " rayweapon " ) or
2023-11-15 12:04:13 +01:00
toolcaps.damage_groups . vehicle ) then
damage_vehicle ( self , toolcaps , ttime , damage )
2023-06-18 22:14:27 -03:00
end
2023-06-17 19:08:31 -03:00
2025-02-15 09:12:56 -03:00
local is_admin = core.check_player_privs ( puncher , { server = true } )
2023-06-11 17:29:08 -03:00
if self.owner == nil then
self.owner = name
end
2024-01-23 21:38:27 -03:00
if self.owner and self.owner ~= name and self.owner ~= " " then
if is_admin == false then return end
end
2024-10-05 11:27:56 +02:00
2025-02-15 09:12:56 -03:00
if is_admin == false and core.check_player_privs ( puncher , { protection_bypass = false } ) then
2024-03-03 12:14:03 -03:00
if self.driver_name and self.driver_name ~= name then
-- do not allow other players to remove the object while there is a driver
return
end
end
2024-10-05 11:27:56 +02:00
2023-06-11 17:29:08 -03:00
local is_attached = false
2023-06-17 19:08:31 -03:00
local player_attach = puncher : get_attach ( )
if player_attach then
if player_attach ~= self.object then
local slot_attach = player_attach : get_attach ( )
if slot_attach == self.object then is_attached = true end
else
is_attached = true
end
end
2024-10-05 11:27:56 +02:00
2023-06-11 17:29:08 -03:00
if puncher : get_attach ( ) == self.object then is_attached = true end
2023-06-17 19:08:31 -03:00
--if puncher:get_attach() == self.pilot_seat_base then is_attached = true end
2023-06-11 17:29:08 -03:00
local itmstck = puncher : get_wielded_item ( )
local item_name = " "
if itmstck then item_name = itmstck : get_name ( ) end
if is_attached == false then
if airutils.loadFuel ( self , puncher : get_player_name ( ) ) then
return
end
--repair
if ( item_name == " airutils:repair_tool " )
and self._engine_running == false then
2023-06-13 12:09:13 -03:00
if self.hp_max < self._max_plane_hp then
2023-06-11 17:29:08 -03:00
local inventory_item = " default:steel_ingot "
local inv = puncher : get_inventory ( )
if inv : contains_item ( " main " , inventory_item ) then
local stack = ItemStack ( inventory_item .. " 1 " )
inv : remove_item ( " main " , stack )
self.hp_max = self.hp_max + 10
2023-06-13 12:09:13 -03:00
if self.hp_max > self._max_plane_hp then self.hp_max = self._max_plane_hp end
2023-07-08 11:05:44 -03:00
airutils.setText ( self , self._vehicle_name )
2023-06-11 17:29:08 -03:00
else
2025-02-15 09:12:56 -03:00
core.chat_send_player ( puncher : get_player_name ( ) , S ( " You need steel ingots in your inventory to perform this repair. " ) )
2023-06-11 17:29:08 -03:00
end
end
return
end
-- deal with painting or destroying
if itmstck then
2023-06-18 13:59:31 -03:00
if airutils.set_param_paint ( self , puncher , itmstck , 1 ) == false then
2023-06-11 17:29:08 -03:00
if not self.driver and toolcaps and toolcaps.damage_groups
2023-08-09 21:13:51 -03:00
and toolcaps.groupcaps and ( toolcaps.groupcaps . choppy or toolcaps.groupcaps . axey_dig ) and item_name ~= airutils.fuel then
2023-06-11 17:29:08 -03:00
--airutils.hurt(self,toolcaps.damage_groups.fleshy - 1)
--airutils.make_sound(self,'hit')
2023-06-18 22:14:27 -03:00
damage_vehicle ( self , toolcaps , ttime , damage )
2025-02-15 09:12:56 -03:00
core.sound_play ( self._collision_sound , {
2023-06-11 17:29:08 -03:00
object = self.object ,
max_hear_distance = 5 ,
gain = 1.0 ,
fade = 0.0 ,
pitch = 1.0 ,
} )
2023-07-08 11:05:44 -03:00
airutils.setText ( self , self._vehicle_name )
2023-06-11 17:29:08 -03:00
end
end
end
if self.hp_max <= 0 then
2023-07-02 11:38:36 -03:00
airutils.destroy ( self , name )
2023-06-11 17:29:08 -03:00
end
2023-06-17 19:08:31 -03:00
else
if self._custom_punch_when_attached then self._custom_punch_when_attached ( self , puncher ) end
2023-06-11 17:29:08 -03:00
end
end
2024-06-30 11:05:34 -03:00
--returns the vehicle to inventory if it is registered as a tool
local function get_vehicle ( self , player )
if not player then return false end
local itmstck = player : get_wielded_item ( )
local item_name = " "
if itmstck then item_name = itmstck : get_name ( ) end
--remove
if ( item_name == " airutils:repair_tool " ) and self._engine_running == false then
local lua_ent = self.object : get_luaentity ( )
local staticdata = lua_ent : get_staticdata ( self )
local obj_name = lua_ent.name
2024-10-05 11:27:56 +02:00
local pos = self.object : get_pos ( )
2024-06-30 11:05:34 -03:00
local stack = ItemStack ( obj_name )
local tool = false
if stack : get_stack_max ( ) == 1 then tool = true end
if tool == false then return false end
local stack_meta = stack : get_meta ( )
stack_meta : set_string ( " staticdata " , staticdata )
local inv = player : get_inventory ( )
if inv then
if inv : room_for_item ( " main " , stack ) then
inv : add_item ( " main " , stack )
else
2025-02-15 09:12:56 -03:00
core.add_item ( { x = pos.x + math.random ( ) - 0.5 , y = pos.y , z = pos.z + math.random ( ) - 0.5 } , stack )
2024-06-30 11:05:34 -03:00
end
else
2025-02-15 09:12:56 -03:00
core.add_item ( { x = pos.x + math.random ( ) - 0.5 , y = pos.y , z = pos.z + math.random ( ) - 0.5 } , stack )
2024-06-30 11:05:34 -03:00
end
airutils.seats_destroy ( self )
local obj_children = self.object : get_children ( )
for _ , child in ipairs ( obj_children ) do
child : remove ( )
end
airutils.destroy_inventory ( self )
self.object : remove ( )
return true
end
2024-10-05 11:27:56 +02:00
2024-06-30 11:05:34 -03:00
return false
end
2023-06-11 17:29:08 -03:00
function airutils . on_rightclick ( self , clicker )
2023-07-02 11:38:36 -03:00
local message = " "
2023-06-11 17:29:08 -03:00
if not clicker or not clicker : is_player ( ) then
return
end
local name = clicker : get_player_name ( )
if self.owner == " " then
self.owner = name
end
2023-07-02 11:38:36 -03:00
local copilot_name = nil
if self.co_pilot and self._have_copilot then
copilot_name = self.co_pilot
2023-06-11 17:29:08 -03:00
end
2025-02-15 09:12:56 -03:00
--core.chat_send_all(dump(self.driver_name))
2024-03-29 15:54:56 -03:00
2023-06-11 17:29:08 -03:00
local is_under_water = airutils.check_is_under_water ( self.object )
2025-02-15 09:12:56 -03:00
--core.chat_send_all('name '.. dump(name) .. ' - pilot: ' .. dump(self.driver_name) .. ' - pax: ' .. dump(copilot_name))
2023-06-11 17:29:08 -03:00
--=========================
2023-07-02 11:38:36 -03:00
-- form to pilot
2023-06-11 17:29:08 -03:00
--=========================
2023-07-02 11:38:36 -03:00
local is_attached = false
local seat = clicker : get_attach ( )
if seat then
local plane = seat : get_attach ( )
if plane == self.object then is_attached = true end
end
2024-10-05 11:27:56 +02:00
2023-06-11 17:29:08 -03:00
if name == self.driver_name then
2023-07-02 11:38:36 -03:00
if is_attached then
local itmstck = clicker : get_wielded_item ( )
local item_name = " "
if itmstck then item_name = itmstck : get_name ( ) end
--adf program function
if ( item_name == " compassgps:cgpsmap_marked " ) then
2025-02-15 09:12:56 -03:00
local meta = core.deserialize ( itmstck : get_metadata ( ) )
2023-07-02 11:38:36 -03:00
if meta then
self._adf_destiny = { x = meta [ " x " ] , z = meta [ " z " ] }
end
else
--formspec of the plane
if not self._custom_pilot_formspec then
airutils.pilot_formspec ( name )
else
self._custom_pilot_formspec ( name )
end
2023-08-09 21:13:51 -03:00
airutils.sit ( clicker )
2023-07-02 11:38:36 -03:00
end
2023-06-19 20:12:50 -03:00
else
2023-07-02 11:38:36 -03:00
self.driver_name = nil --error, so clean it
2023-06-19 20:12:50 -03:00
end
2023-06-11 17:29:08 -03:00
--=========================
2023-07-02 11:38:36 -03:00
-- detach copilot
2023-06-11 17:29:08 -03:00
--=========================
2023-07-02 11:38:36 -03:00
elseif name == copilot_name then
2023-07-04 21:53:14 -03:00
if self._command_is_given then
2024-03-12 19:40:41 -03:00
--formspec of the plane
if not self._custom_pilot_formspec then
airutils.pilot_formspec ( name )
else
self._custom_pilot_formspec ( name )
end
2023-07-04 21:53:14 -03:00
else
airutils.pax_formspec ( name )
end
2023-06-11 17:29:08 -03:00
--=========================
-- attach pilot
--=========================
2024-03-10 11:31:30 -03:00
elseif not self.driver_name and not self._autoflymode then
2025-02-15 09:12:56 -03:00
if self.owner == name or core.check_player_privs ( clicker , { protection_bypass = true } ) then
2023-07-02 21:56:25 -03:00
local itmstck = clicker : get_wielded_item ( )
if itmstck then
if airutils.set_param_paint ( self , clicker , itmstck , 2 ) == true then
return
end
2024-06-30 11:05:34 -03:00
if get_vehicle ( self , clicker ) then
return
end
2023-07-02 21:56:25 -03:00
end
2024-09-21 12:59:27 -03:00
if clicker : get_player_control ( ) . sneak == true then --lets see the inventory
2023-07-02 11:38:36 -03:00
airutils.show_vehicle_trunk_formspec ( self , clicker , self._trunk_slots )
else
if is_under_water then return end
2024-10-05 11:27:56 +02:00
--remove the passengers first
2023-07-02 11:38:36 -03:00
local max_seats = table.getn ( self._seats )
for i = max_seats , 1 , - 1
2024-10-05 11:27:56 +02:00
do
2024-09-21 12:59:27 -03:00
if self._passengers [ i ] and self._passengers [ i ] ~= " " then
2025-02-15 09:12:56 -03:00
local passenger = core.get_player_by_name ( self._passengers [ i ] )
2023-07-02 11:38:36 -03:00
if passenger then airutils.dettach_pax ( self , passenger ) end
2023-06-18 13:59:31 -03:00
end
2023-07-02 11:38:36 -03:00
end
2023-06-18 13:59:31 -03:00
2023-07-02 11:38:36 -03:00
--attach player
2024-09-21 12:59:27 -03:00
--airutils.seat_create(self, 1)
--airutils.seat_create(self, 2)
if clicker : get_player_control ( ) . aux1 == true and max_seats > 1 then
2023-07-06 21:31:15 -03:00
-- flight instructor mode
self._instruction_mode = true
2023-07-14 21:08:19 -03:00
self.co_pilot_seat_base = self._passengers_base [ 1 ]
self.pilot_seat_base = self._passengers_base [ 2 ]
2023-07-06 21:31:15 -03:00
else
-- no driver => clicker is new driver
self._instruction_mode = false
2023-07-14 21:08:19 -03:00
self.co_pilot_seat_base = self._passengers_base [ 2 ]
self.pilot_seat_base = self._passengers_base [ 1 ]
2023-07-06 21:31:15 -03:00
end
2024-03-29 15:54:56 -03:00
airutils.attach ( self , clicker )
2023-07-02 11:38:36 -03:00
self._command_is_given = false
2023-06-11 17:29:08 -03:00
end
else
2023-07-02 11:38:36 -03:00
airutils.dettach_pax ( self , clicker )
2025-02-15 09:12:56 -03:00
core.chat_send_player ( name , core.colorize ( ' #ff0000 ' , S ( " >>> You aren't the owner of this " .. self.infotext .. " . " ) ) )
2023-06-11 17:29:08 -03:00
end
--=========================
-- attach passenger
--=========================
2023-07-02 11:38:36 -03:00
elseif self.driver_name ~= nil or self._autoflymode == true then
2024-03-09 22:46:11 -03:00
local d_name = self.driver_name
if d_name == nil then d_name = " " end
2025-02-15 09:12:56 -03:00
local player = core.get_player_by_name ( d_name )
2024-03-09 22:30:39 -03:00
if player or self._autoflymode == true then
2023-07-02 11:38:36 -03:00
is_attached = airutils.check_passenger_is_attached ( self , name )
if is_attached then
--remove pax
airutils.pax_formspec ( name )
else
--attach normal passenger
airutils.attach_pax ( self , clicker )
end
else
2025-02-15 09:12:56 -03:00
core.chat_send_player ( clicker : get_player_name ( ) , message )
2023-07-02 11:38:36 -03:00
end
2023-06-11 17:29:08 -03:00
else
2025-02-15 09:12:56 -03:00
core.chat_send_player ( clicker : get_player_name ( ) , message )
2023-06-11 17:29:08 -03:00
end
2023-07-02 11:38:36 -03:00
2023-06-11 17:29:08 -03:00
end
2023-07-02 11:38:36 -03:00