updated trike mechanics
69
crafts.lua
Executable file
@ -0,0 +1,69 @@
|
||||
-- wing
|
||||
minetest.register_craftitem("trike:wing",{
|
||||
description = "trike wing",
|
||||
inventory_image = "trike_wing_ico.png",
|
||||
})
|
||||
-- fuselage
|
||||
minetest.register_craftitem("trike:fuselage",{
|
||||
description = "trike fuselage",
|
||||
inventory_image = "trike_body.png",
|
||||
})
|
||||
|
||||
-- trike
|
||||
minetest.register_craftitem("trike:trike", {
|
||||
description = "Ultralight Trike",
|
||||
inventory_image = "trike.png",
|
||||
liquids_pointable = true,
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
if pointed_thing.type ~= "node" then
|
||||
return
|
||||
end
|
||||
|
||||
local pointed_pos = pointed_thing.under
|
||||
--local node_below = minetest.get_node(pointed_pos).name
|
||||
--local nodedef = minetest.registered_nodes[node_below]
|
||||
|
||||
pointed_pos.y=pointed_pos.y+0.5
|
||||
local trike = minetest.add_entity(pointed_pos, "trike:trike")
|
||||
if trike and placer then
|
||||
local ent = trike:get_luaentity()
|
||||
local owner = placer:get_player_name()
|
||||
ent.owner = owner
|
||||
trike:set_yaw(placer:get_look_horizontal())
|
||||
itemstack:take_item()
|
||||
end
|
||||
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
--
|
||||
-- crafting
|
||||
--
|
||||
|
||||
if not minetest.settings:get_bool('trike.disable_craftitems') and minetest.get_modpath("default") then
|
||||
minetest.register_craft({
|
||||
output = "trike:wing",
|
||||
recipe = {
|
||||
{"", "wool:white", "" },
|
||||
{"wool:white", "default:steel_ingot", "wool:white"},
|
||||
{"farming:string", "wool:white", "farming:string"},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "trike:fuselage",
|
||||
recipe = {
|
||||
{"", "default:diamondblock", ""},
|
||||
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
|
||||
{"default:steel_ingot", "default:mese_block", "default:steel_ingot"},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "trike:trike",
|
||||
recipe = {
|
||||
{"", ""},
|
||||
{"trike:fuselage", "trike:wing"},
|
||||
}
|
||||
})
|
||||
end
|
@ -1,3 +0,0 @@
|
||||
mobkit
|
||||
default
|
||||
biofuel
|
56
entities.lua
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
--
|
||||
-- entity
|
||||
--
|
||||
|
||||
trike.vector_up = vector.new(0, 1, 0)
|
||||
|
||||
minetest.register_entity('trike:pointer',{
|
||||
initial_properties = {
|
||||
physical = false,
|
||||
collide_with_objects=false,
|
||||
pointable=false,
|
||||
visual = "mesh",
|
||||
mesh = "trike_pointer.b3d",
|
||||
visual_size = {x = 0.4, y = 0.4, z = 0.4},
|
||||
textures = {"trike_grey.png"},
|
||||
},
|
||||
|
||||
on_activate = function(self,std)
|
||||
self.sdata = minetest.deserialize(std) or {}
|
||||
if self.sdata.remove then self.object:remove() end
|
||||
end,
|
||||
|
||||
get_staticdata=function(self)
|
||||
self.sdata.remove=true
|
||||
return minetest.serialize(self.sdata)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_entity('trike:wheels',{
|
||||
initial_properties = {
|
||||
physical = false,
|
||||
collide_with_objects=false,
|
||||
pointable=false,
|
||||
visual = "mesh",
|
||||
backface_culling = false,
|
||||
mesh = "trike_wheels.b3d",
|
||||
--visual_size = {x = 3, y = 3, z = 3},
|
||||
textures = {"trike_black.png", "trike_metal.png", "trike_black.png", "trike_metal.png",},
|
||||
},
|
||||
|
||||
on_activate = function(self,std)
|
||||
self.sdata = minetest.deserialize(std) or {}
|
||||
if self.sdata.remove then self.object:remove() end
|
||||
end,
|
||||
|
||||
get_staticdata=function(self)
|
||||
self.sdata.remove=true
|
||||
return minetest.serialize(self.sdata)
|
||||
end,
|
||||
|
||||
})
|
||||
|
||||
minetest.register_entity("trike:trike",
|
||||
airutils.properties_copy(trike.plane_properties)
|
||||
)
|
271
init.lua
Normal file → Executable file
@ -1,39 +1,206 @@
|
||||
trike={}
|
||||
trike.gravity = tonumber(minetest.settings:get("movement_gravity")) or 9.8
|
||||
|
||||
trike.colors ={
|
||||
black='#2b2b2b',
|
||||
blue='#0063b0',
|
||||
brown='#8c5922',
|
||||
cyan='#07B6BC',
|
||||
dark_green='#567a42',
|
||||
dark_grey='#6d6d6d',
|
||||
green='#4ee34c',
|
||||
grey='#9f9f9f',
|
||||
magenta='#ff0098',
|
||||
orange='#ff8b0e',
|
||||
pink='#ff62c6',
|
||||
red='#dc1818',
|
||||
violet='#a437ff',
|
||||
white='#FFFFFF',
|
||||
yellow='#ffe400',
|
||||
|
||||
trike={}
|
||||
|
||||
local TRIKE_GAUGE_FUEL_POSITION = {x=1.5,y=6.2,z=15.2}
|
||||
local TRIKE_GAUGE_POWER_POSITION = {x=1.5,y=7.7,z=15.2}
|
||||
local TRIKE_GAUGE_CLIMBER_POSITION = {x=-1.2,y=7.55,z=15.2}
|
||||
|
||||
function trike.register_parts_method(self)
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
local wheels=minetest.add_entity(pos,'trike:wheels')
|
||||
wheels:set_attach(self.object,'',{x=0,y=0,z=0},{x=0,y=0,z=0})
|
||||
self.wheels = wheels
|
||||
|
||||
local fuel_gauge=minetest.add_entity(pos,'trike:pointer')
|
||||
local fuel_percentage = (self._energy*100)/self._max_fuel
|
||||
local fuel_angle = -(fuel_percentage*180)/100
|
||||
fuel_gauge:set_attach(self.object,'',TRIKE_GAUGE_FUEL_POSITION,{x=0,y=0,z=fuel_angle})
|
||||
self.fuel_gauge = fuel_gauge
|
||||
|
||||
local power_gauge=minetest.add_entity(pos,'trike:pointer')
|
||||
local power_indicator_angle = airutils.get_gauge_angle(self._power_lever/6.5)
|
||||
power_gauge:set_attach(self.object,'',TRIKE_GAUGE_POWER_POSITION,{x=0,y=0,z=power_indicator_angle})
|
||||
self.power_gauge = power_gauge
|
||||
|
||||
local climb_gauge=minetest.add_entity(pos,'trike:pointer')
|
||||
local climb_angle = airutils.get_gauge_angle(0)
|
||||
climb_gauge:set_attach(self.object,'',TRIKE_GAUGE_CLIMBER_POSITION,{x=0,y=0,z=climb_angle})
|
||||
self.climb_gauge = climb_gauge
|
||||
end
|
||||
|
||||
function trike.destroy_parts_method(self)
|
||||
if self.wheels then self.wheels:remove() end
|
||||
if self.fuel_gauge then self.fuel_gauge:remove() end
|
||||
if self.power_gauge then self.power_gauge:remove() end
|
||||
if self.climb_gauge then self.climb_gauge:remove() end
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
pos.y=pos.y+2
|
||||
minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'trike:wing')
|
||||
|
||||
for i=1,6 do
|
||||
minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'default:mese_crystal')
|
||||
minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'default:diamond')
|
||||
end
|
||||
|
||||
for i=1,3 do
|
||||
minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'default:steel_ingot')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
function trike.step_additional_function(self)
|
||||
self.object:set_bone_position("wing", {x=0,y=29,z=0}, {x=-self._elevator_angle/2.5,y=0,z=(self._rudder_angle/2.5)})
|
||||
if (self.driver_name==nil) and (self.co_pilot==nil) then --pilot or copilot
|
||||
return
|
||||
end
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
local fuel_percentage = (self._energy*100)/self._max_fuel
|
||||
local fuel_angle = -(fuel_percentage*180)/100
|
||||
self.fuel_gauge:set_attach(self.object,'',TRIKE_GAUGE_FUEL_POSITION,{x=0,y=0,z=fuel_angle})
|
||||
|
||||
local power_indicator_angle = airutils.get_gauge_angle(self._power_lever/6.5)
|
||||
self.power_gauge:set_attach(self.object,'',TRIKE_GAUGE_POWER_POSITION,{x=0,y=0,z=power_indicator_angle})
|
||||
|
||||
local climb_angle = airutils.get_gauge_angle(self._climb_rate)
|
||||
self.climb_gauge:set_attach(self.object,'',TRIKE_GAUGE_CLIMBER_POSITION,{x=0,y=0,z=climb_angle})
|
||||
end
|
||||
|
||||
trike.plane_properties = {
|
||||
initial_properties = {
|
||||
physical = true,
|
||||
collide_with_objects = true,
|
||||
collisionbox = {-1.2, 0.0, -1.2, 1.2, 3, 1.2}, --{-1,0,-1, 1,0.3,1},
|
||||
selectionbox = {-2, 0, -2, 2, 1, 2},
|
||||
visual = "mesh",
|
||||
backface_culling = false,
|
||||
mesh = "trike_body.b3d",
|
||||
stepheight = 0.5,
|
||||
textures = {
|
||||
"trike_black.png", --bancos
|
||||
"airutils_metal.png",
|
||||
"airutils_metal.png",
|
||||
"airutils_metal.png",
|
||||
"airutils_metal.png",
|
||||
"airutils_metal.png",
|
||||
"trike_painting.png", --pintura
|
||||
"trike_grey.png", --motor
|
||||
"airutils_metal.png", --trem nariz
|
||||
"trike_white.png", --tanque
|
||||
"trike_black.png", --tampa do tanque
|
||||
"trike_black.png", --carburador
|
||||
"trike_black.png", --escape
|
||||
"trike_grey.png", --interior
|
||||
"trike_metal.png", --estrutura asa
|
||||
"trike_black.png", -- cabos
|
||||
"trike_wing.png", --bordo de fuga
|
||||
"trike_painting.png", --bordo de ataque
|
||||
"trike_panel.png", --painel
|
||||
"trike_rotor.png", --helice
|
||||
"trike_black.png", --cubo helice
|
||||
"airutils_red.png",
|
||||
"airutils_green.png",
|
||||
"airutils_blue.png",
|
||||
"airutils_metal.png",
|
||||
},
|
||||
},
|
||||
textures = {},
|
||||
_anim_frames = 11,
|
||||
driver_name = nil,
|
||||
sound_handle = nil,
|
||||
owner = "",
|
||||
static_save = true,
|
||||
infotext = "",
|
||||
hp_max = 50,
|
||||
shaded = true,
|
||||
show_on_minimap = true,
|
||||
springiness = 0.1,
|
||||
buoyancy = 1.02,
|
||||
physics = airutils.physics,
|
||||
_vehicle_name = "trike",
|
||||
_use_camera_relocation = false,
|
||||
_seats = {{x=0,y=7,z=8},{x=0,y=9,z=1.6},},
|
||||
_seats_rot = {0,0}, --necessary when using reversed seats
|
||||
_have_copilot = false, --wil use the second position of the _seats list
|
||||
_max_plane_hp = 50,
|
||||
_enable_fire_explosion = false,
|
||||
_longit_drag_factor = 0.13*0.13,
|
||||
_later_drag_factor = 2.0,
|
||||
_wing_angle_of_attack = 2.5,
|
||||
_wing_span = 12, --meters
|
||||
_min_speed = 3,
|
||||
_max_speed = 8,
|
||||
_max_fuel = 5,
|
||||
_fuel_consumption_divisor = 1600000,
|
||||
_speed_not_exceed = 14,
|
||||
_damage_by_wind_speed = 4,
|
||||
_hard_damage = true,
|
||||
_min_attack_angle = 0.2,
|
||||
_max_attack_angle = 90,
|
||||
_elevator_auto_estabilize = 100,
|
||||
_tail_lift_min_speed = 3,
|
||||
_tail_lift_max_speed = 5,
|
||||
_max_engine_acc = 7.5,
|
||||
_tail_angle = 0, --degrees
|
||||
_lift = 18,
|
||||
_trunk_slots = 2, --the trunk slots
|
||||
_rudder_limit = 30.0,
|
||||
_elevator_limit = 40.0,
|
||||
_elevator_response_attenuation = 10,
|
||||
_pitch_intensity = 0.8,
|
||||
_yaw_intensity = 40,
|
||||
_yaw_turn_rate = 12,
|
||||
_elevator_pos = {x=0, y=0, z=0},
|
||||
_rudder_pos = {x=0,y=0,z=0},
|
||||
_aileron_r_pos = {x=0,y=0,z=0},
|
||||
_aileron_l_pos = {x=0,y=0,z=0},
|
||||
_color = "#0063b0",
|
||||
_color_2 = "#0063b0",
|
||||
_rudder_angle = 0,
|
||||
_acceleration = 0,
|
||||
_engine_running = false,
|
||||
_angle_of_attack = 0,
|
||||
_elevator_angle = 0,
|
||||
_power_lever = 0,
|
||||
_last_applied_power = 0,
|
||||
_energy = 1.0,
|
||||
_last_vel = {x=0,y=0,z=0},
|
||||
_longit_speed = 0,
|
||||
_show_hud = true,
|
||||
_instruction_mode = false, --flag to intruction mode
|
||||
_command_is_given = false, --flag to mark the "owner" of the commands now
|
||||
_autopilot = false,
|
||||
_auto_pilot_altitude = 0,
|
||||
_last_accell = {x=0,y=0,z=0},
|
||||
_last_time_command = 1,
|
||||
_inv = nil,
|
||||
_inv_id = "",
|
||||
_collision_sound = "airutils_collision", --the col sound
|
||||
_engine_sound = "trike_engine",
|
||||
_painting_texture = {"trike_painting.png",}, --the texture to paint
|
||||
_painting_texture_2 = {"airutils_painting_2.png",}, --the texture to paint
|
||||
_mask_painting_associations = {},
|
||||
_register_parts_method = trike.register_parts_method, --the method to register plane parts
|
||||
_destroy_parts_method = trike.destroy_parts_method,
|
||||
_plane_y_offset_for_bullet = 1,
|
||||
_custom_step_additional_function = trike.step_additional_function,
|
||||
_inverted_pitch_reaction = true,
|
||||
|
||||
get_staticdata = airutils.get_staticdata,
|
||||
on_deactivate = airutils.on_deactivate,
|
||||
on_activate = airutils.on_activate,
|
||||
logic = airutils.logic,
|
||||
on_step = airutils.on_step,
|
||||
on_punch = airutils.on_punch,
|
||||
on_rightclick = airutils.on_rightclick,
|
||||
}
|
||||
|
||||
trike.trunk_slots = 3
|
||||
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "trike_global_definitions.lua")
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "trike_crafts.lua")
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "trike_control.lua")
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "trike_fuel_management.lua")
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "trike_custom_physics.lua")
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "trike_utilities.lua")
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "trike_entities.lua")
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "trike_hud.lua")
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "trike_forms.lua")
|
||||
|
||||
--
|
||||
-- helpers and co.
|
||||
--
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "crafts.lua")
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "entities.lua")
|
||||
|
||||
--
|
||||
-- items
|
||||
@ -45,37 +212,13 @@ local function fetch_setting(name)
|
||||
return settings and settings:get(sname) or minetest.settings:get(sname)
|
||||
end
|
||||
|
||||
trike.restricted = fetch_setting("restricted")
|
||||
|
||||
minetest.register_privilege("flight_licence", {
|
||||
description = "Gives a flight licence to the player",
|
||||
give_to_singleplayer = true
|
||||
local old_entities = {"trike:seat_base","trike:engine"}
|
||||
for _,entity_name in ipairs(old_entities) do
|
||||
minetest.register_entity(":"..entity_name, {
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:remove()
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
-- add chatcommand to eject from trike
|
||||
|
||||
minetest.register_chatcommand("trike_eject", {
|
||||
params = "",
|
||||
description = "Ejects from trike",
|
||||
privs = {interact = true},
|
||||
func = function(name, param)
|
||||
local colorstring = core.colorize('#ff0000', " >>> you are not inside your ultralight trike")
|
||||
local player = minetest.get_player_by_name(name)
|
||||
local attached_to = player:get_attach()
|
||||
|
||||
if attached_to ~= nil then
|
||||
local parent = attached_to:get_attach()
|
||||
if parent ~= nil then
|
||||
local entity = parent:get_luaentity()
|
||||
if entity.driver_name == name and entity.name == "trike:trike" then
|
||||
trike.dettachPlayer(entity, player)
|
||||
else
|
||||
minetest.chat_send_player(name,colorstring)
|
||||
end
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(name,colorstring)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
BIN
models/trike_wheels.b3d
Executable file
Before Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
@ -1,160 +0,0 @@
|
||||
--global constants
|
||||
trike.trike_last_time_command = 0
|
||||
trike.vector_up = vector.new(0, 1, 0)
|
||||
trike.max_engine_acc = 4.5
|
||||
trike.ideal_step = 0.02
|
||||
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "trike_utilities.lua")
|
||||
|
||||
function trike.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 trike.control(self, dtime, hull_direction, longit_speed,
|
||||
longit_drag, later_speed, later_drag, accel, player, is_flying)
|
||||
|
||||
trike.trike_last_time_command = trike.trike_last_time_command + self.dtime
|
||||
if trike.trike_last_time_command > 1 then trike.trike_last_time_command = 1 end
|
||||
if self.driver_name == nil then return end
|
||||
local retval_accel = accel
|
||||
|
||||
local rudder_limit = 30
|
||||
local stop = false
|
||||
|
||||
-- player control
|
||||
if player then
|
||||
local ctrl = player:get_player_control()
|
||||
|
||||
--engine and power control
|
||||
if ctrl.aux1 and trike.trike_last_time_command > 0.3 then
|
||||
trike.trike_last_time_command = 0
|
||||
if self._engine_running then
|
||||
self._engine_running = false
|
||||
-- sound and animation
|
||||
if self.sound_handle then
|
||||
minetest.sound_stop(self.sound_handle)
|
||||
self.sound_handle = nil
|
||||
end
|
||||
self.engine:set_animation_frame_speed(0)
|
||||
elseif self._engine_running == false and self._energy > 0 then
|
||||
self._engine_running = true
|
||||
-- sound and animation
|
||||
self.sound_handle = minetest.sound_play({name = "trike_engine"},
|
||||
{object = self.object, gain = 2.0,
|
||||
pitch = 0.5 + ((self._power_lever/100)/2),max_hear_distance = 32,
|
||||
loop = true,})
|
||||
self.engine:set_animation_frame_speed(60)
|
||||
end
|
||||
end
|
||||
|
||||
self._acceleration = 0
|
||||
if self._engine_running then
|
||||
--engine acceleration calc
|
||||
local engineacc = (self._power_lever * trike.max_engine_acc) / 100;
|
||||
self.engine:set_animation_frame_speed(60 + self._power_lever)
|
||||
|
||||
local add_factor = 1
|
||||
add_factor = add_factor * (dtime/trike.ideal_step) --adjusting the command speed by dtime
|
||||
|
||||
--increase power lever
|
||||
if ctrl.jump then
|
||||
if self._power_lever < 100 then
|
||||
self._power_lever = self._power_lever + add_factor
|
||||
end
|
||||
if self._power_lever > 100 then
|
||||
self._power_lever = 100
|
||||
engineacc = trike.max_engine_acc
|
||||
else
|
||||
--sound
|
||||
if self.sound_handle then
|
||||
minetest.sound_stop(self.sound_handle)
|
||||
self.sound_handle = minetest.sound_play({name = "trike_engine"},
|
||||
{object = self.object, gain = 2.0,
|
||||
pitch = 0.5 + ((self._power_lever/100)/2),max_hear_distance = 32,
|
||||
loop = true,})
|
||||
end
|
||||
end
|
||||
end
|
||||
--decrease power lever
|
||||
if ctrl.sneak then
|
||||
if self._power_lever > 0 then
|
||||
self._power_lever = self._power_lever - add_factor
|
||||
if self._power_lever < 0 then self._power_lever = 0 end
|
||||
end
|
||||
if self._power_lever <= 0 and is_flying == false then
|
||||
--break
|
||||
if longit_speed > 0 then
|
||||
engineacc = -1
|
||||
if (longit_speed + engineacc) < 0 then engineacc = longit_speed * -1 end
|
||||
end
|
||||
if longit_speed < 0 then
|
||||
engineacc = 1
|
||||
if (longit_speed + engineacc) > 0 then engineacc = longit_speed * -1 end
|
||||
end
|
||||
if abs(longit_speed) < 0.1 then
|
||||
stop = true
|
||||
end
|
||||
else
|
||||
--sound
|
||||
minetest.sound_stop(self.sound_handle)
|
||||
self.sound_handle = minetest.sound_play({name = "trike_engine"},
|
||||
{object = self.object, gain = 2.0,
|
||||
pitch = 0.5 + ((self._power_lever/100)/2),
|
||||
max_hear_distance = 32, loop = true,})
|
||||
end
|
||||
end
|
||||
--do not exceed
|
||||
local max_speed = 6
|
||||
if longit_speed > max_speed then
|
||||
engineacc = engineacc - (longit_speed-max_speed)
|
||||
if engineacc < 0 then engineacc = 0 end
|
||||
end
|
||||
self._acceleration = engineacc
|
||||
else
|
||||
local pushacc = 0
|
||||
if longit_speed < 1.0 then
|
||||
if ctrl.jump then pushacc = 0.5 end
|
||||
end
|
||||
if longit_speed > -1.0 then
|
||||
if ctrl.sneak then pushacc = -0.5 end
|
||||
end
|
||||
self._acceleration = pushacc
|
||||
end
|
||||
|
||||
local hull_acc = vector.multiply(hull_direction,self._acceleration)
|
||||
retval_accel=vector.add(retval_accel,hull_acc)
|
||||
|
||||
--wing
|
||||
local wing_limit = 10
|
||||
if ctrl.down then
|
||||
self._angle_of_attack = math.max(self._angle_of_attack-10*self.dtime,2)
|
||||
elseif ctrl.up then
|
||||
self._angle_of_attack = math.min(self._angle_of_attack+10*self.dtime,wing_limit)
|
||||
end
|
||||
|
||||
-- yaw
|
||||
if ctrl.right then
|
||||
self._rudder_angle = math.max(self._rudder_angle-30*self.dtime,-rudder_limit)
|
||||
elseif ctrl.left then
|
||||
self._rudder_angle = math.min(self._rudder_angle+30*self.dtime,rudder_limit)
|
||||
end
|
||||
end
|
||||
|
||||
if longit_speed > 0 then
|
||||
local factor = 1
|
||||
if self._rudder_angle > 0 then factor = -1 end
|
||||
local correction = (rudder_limit*(longit_speed/1000)) * factor
|
||||
self._rudder_angle = self._rudder_angle + correction
|
||||
end
|
||||
|
||||
return retval_accel, stop
|
||||
end
|
||||
|
||||
|
@ -1,80 +0,0 @@
|
||||
-- engine
|
||||
minetest.register_craftitem("trike:wing",{
|
||||
description = "Trike wing",
|
||||
inventory_image = "icon3.png",
|
||||
})
|
||||
-- hull
|
||||
minetest.register_craftitem("trike:fuselage",{
|
||||
description = "Trike body",
|
||||
inventory_image = "icon2.png",
|
||||
})
|
||||
|
||||
|
||||
-- trike
|
||||
minetest.register_craftitem("trike:trike", {
|
||||
description = "Ultralight Trike",
|
||||
inventory_image = "icon1.png",
|
||||
liquids_pointable = false,
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
if pointed_thing.type ~= "node" then
|
||||
return
|
||||
end
|
||||
|
||||
local pointed_pos = pointed_thing.under
|
||||
local node_below = minetest.get_node(pointed_pos).name
|
||||
local nodedef = minetest.registered_nodes[node_below]
|
||||
if nodedef.liquidtype == "none" then
|
||||
pointed_pos.y=pointed_pos.y+1.5
|
||||
local new_trike = minetest.add_entity(pointed_pos, "trike:trike")
|
||||
if new_trike and placer then
|
||||
local ent = new_trike:get_luaentity()
|
||||
local owner = placer:get_player_name()
|
||||
ent.owner = owner
|
||||
new_trike:set_yaw(placer:get_look_horizontal())
|
||||
itemstack:take_item()
|
||||
airutils.create_inventory(ent, trike.trunk_slots, owner)
|
||||
end
|
||||
end
|
||||
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
--
|
||||
-- crafting
|
||||
--
|
||||
|
||||
if minetest.get_modpath("default") then
|
||||
minetest.register_craft({
|
||||
output = "trike:wing",
|
||||
recipe = {
|
||||
{"", "wool:white", "" },
|
||||
{"wool:white", "default:steel_ingot", "wool:white"},
|
||||
{"farming:string", "wool:white", "farming:string"},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "trike:fuselage",
|
||||
recipe = {
|
||||
{"", "default:diamondblock", ""},
|
||||
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
|
||||
{"default:steel_ingot", "default:mese_block", "default:steel_ingot"},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "trike:trike",
|
||||
recipe = {
|
||||
{"", ""},
|
||||
{"trike:fuselage", "trike:wing"},
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "trike:repair_tool",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "", "default:steel_ingot"},
|
||||
{"", "default:steel_ingot", ""},
|
||||
{"", "default:steel_ingot", ""},
|
||||
},
|
||||
})
|
||||
end
|
@ -1,40 +0,0 @@
|
||||
local abs = math.abs
|
||||
|
||||
function trike.physics(self)
|
||||
local friction = 0.99
|
||||
local vel=self.object:get_velocity()
|
||||
-- dumb friction
|
||||
if self.isonground and not self.isinliquid then
|
||||
--minetest.chat_send_all('okay')
|
||||
vel = {x=vel.x*friction, y=vel.y, z=vel.z*friction}
|
||||
self.object:set_velocity(vel)
|
||||
end
|
||||
|
||||
-- bounciness
|
||||
if self.springiness and self.springiness > 0 then
|
||||
vel=self.object:get_velocity()
|
||||
local vnew = vector.new(vel)
|
||||
|
||||
if not self.collided then -- ugly workaround for inconsistent collisions
|
||||
for _,k in ipairs({'y','z','x'}) do
|
||||
if vel[k]==0 and abs(self.lastvelocity[k])> 0.1 then
|
||||
vnew[k]=-self.lastvelocity[k]*self.springiness
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not vector.equals(vel,vnew) then
|
||||
self.collided = true
|
||||
else
|
||||
if self.collided then
|
||||
vnew = vector.new(self.lastvelocity)
|
||||
end
|
||||
self.collided = false
|
||||
end
|
||||
|
||||
self.object:set_velocity(vnew)
|
||||
end
|
||||
|
||||
--local accel = self._last_accell
|
||||
--self.object:set_acceleration(accel)
|
||||
end
|
@ -1,445 +0,0 @@
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "trike_global_definitions.lua")
|
||||
|
||||
--
|
||||
-- entity
|
||||
--
|
||||
|
||||
trike.vector_up = vector.new(0, 1, 0)
|
||||
|
||||
minetest.register_entity('trike:engine',{
|
||||
initial_properties = {
|
||||
physical = false,
|
||||
collide_with_objects=false,
|
||||
pointable=false,
|
||||
visual = "mesh",
|
||||
mesh = "trike_propeller.b3d",
|
||||
--visual_size = {x = 3, y = 3, z = 3},
|
||||
textures = {"trike_rotor.png", "trike_black.png",},
|
||||
},
|
||||
|
||||
on_activate = function(self,std)
|
||||
self.sdata = minetest.deserialize(std) or {}
|
||||
if self.sdata.remove then self.object:remove() end
|
||||
end,
|
||||
|
||||
get_staticdata=function(self)
|
||||
self.sdata.remove=true
|
||||
return minetest.serialize(self.sdata)
|
||||
end,
|
||||
|
||||
})
|
||||
|
||||
minetest.register_entity('trike:front_wheel',{
|
||||
initial_properties = {
|
||||
physical = false,
|
||||
collide_with_objects=false,
|
||||
pointable=false,
|
||||
visual = "mesh",
|
||||
mesh = "trike_front_wheel.b3d",
|
||||
--visual_size = {x = 3, y = 3, z = 3},
|
||||
textures = {"trike_metal.png", "trike_black.png", "trike_metal.png",},
|
||||
},
|
||||
|
||||
on_activate = function(self,std)
|
||||
self.sdata = minetest.deserialize(std) or {}
|
||||
if self.sdata.remove then self.object:remove() end
|
||||
end,
|
||||
|
||||
get_staticdata=function(self)
|
||||
self.sdata.remove=true
|
||||
return minetest.serialize(self.sdata)
|
||||
end,
|
||||
|
||||
})
|
||||
|
||||
--
|
||||
-- fuel
|
||||
--
|
||||
minetest.register_entity('trike:pointer',{
|
||||
initial_properties = {
|
||||
physical = false,
|
||||
collide_with_objects=false,
|
||||
pointable=false,
|
||||
visual = "mesh",
|
||||
mesh = "pointer.b3d",
|
||||
visual_size = {x = 0.4, y = 0.4, z = 0.4},
|
||||
textures = {"trike_grey.png"},
|
||||
},
|
||||
|
||||
on_activate = function(self,std)
|
||||
self.sdata = minetest.deserialize(std) or {}
|
||||
if self.sdata.remove then self.object:remove() end
|
||||
end,
|
||||
|
||||
get_staticdata=function(self)
|
||||
self.sdata.remove=true
|
||||
return minetest.serialize(self.sdata)
|
||||
end,
|
||||
})
|
||||
|
||||
--
|
||||
-- seat pivot
|
||||
--
|
||||
minetest.register_entity('trike:seat_base',{
|
||||
initial_properties = {
|
||||
physical = false,
|
||||
collide_with_objects=false,
|
||||
pointable=false,
|
||||
visual = "mesh",
|
||||
mesh = "trike_seat_base.b3d",
|
||||
textures = {"trike_black.png",},
|
||||
},
|
||||
|
||||
on_activate = function(self,std)
|
||||
self.sdata = minetest.deserialize(std) or {}
|
||||
if self.sdata.remove then self.object:remove() end
|
||||
end,
|
||||
|
||||
get_staticdata=function(self)
|
||||
self.sdata.remove=true
|
||||
return minetest.serialize(self.sdata)
|
||||
end,
|
||||
|
||||
})
|
||||
|
||||
minetest.register_entity("trike:trike", {
|
||||
initial_properties = {
|
||||
physical = true,
|
||||
collide_with_objects = true,
|
||||
collisionbox = {-1.2, 0.0, -1.2, 1.2, 3, 1.2}, --{-1,0,-1, 1,0.3,1},
|
||||
selectionbox = {-2, 0, -2, 2, 1, 2},
|
||||
visual = "mesh",
|
||||
mesh = "trike_body.b3d",
|
||||
backface_culling = false,
|
||||
stepheight = 0.5,
|
||||
textures = {
|
||||
"trike_black.png", --bancos
|
||||
"trike_metal.png", --freios
|
||||
"trike_metal.png", --montante trem
|
||||
"trike_metal.png", --haste trem
|
||||
"trike_metal.png", --suporte asa
|
||||
"trike_metal.png", --haste trem
|
||||
"trike_painting.png", --pintura
|
||||
"trike_grey.png", --motor
|
||||
"trike_white.png", --tanque
|
||||
"trike_black.png", --tampa do tanque
|
||||
"trike_black.png", --carburador
|
||||
"trike_black.png", --escape
|
||||
"trike_grey.png", --interior
|
||||
"trike_metal.png", --estrutura asa
|
||||
"trike_black.png", -- cabos
|
||||
"trike_wing.png", --bordo de fuga
|
||||
"trike_painting.png", --bordo de ataque
|
||||
"trike_panel.png", --painel
|
||||
"trike_black.png", --pneus
|
||||
"trike_metal.png", --rodas
|
||||
}
|
||||
},
|
||||
textures = {},
|
||||
driver_name = nil,
|
||||
sound_handle = nil,
|
||||
owner = "",
|
||||
static_save = true,
|
||||
infotext = "A nice ultralight",
|
||||
hp_max = 50,
|
||||
shaded = true,
|
||||
show_on_minimap = true,
|
||||
buoyancy = 2,
|
||||
physics = trike.physics,
|
||||
springiness = 0.3,
|
||||
_passenger = nil,
|
||||
_color = "#0063b0",
|
||||
_rudder_angle = 0,
|
||||
_acceleration = 0,
|
||||
_engine_running = false,
|
||||
_angle_of_attack = 2,
|
||||
_power_lever = 0,
|
||||
_energy = 0.001,
|
||||
_longit_speed = 0,
|
||||
_lastrot = {x=0,y=0,z=0},
|
||||
_last_accell = {x=0,y=0,z=0},
|
||||
_show_hud = false,
|
||||
lastvelocity = nil,
|
||||
_inv = nil,
|
||||
_inv_id = "",
|
||||
|
||||
_change_color = function(self, colstr)
|
||||
airutils.paint(self, colstr, "trike_painting.png")
|
||||
end,
|
||||
|
||||
get_staticdata = function(self) -- unloaded/unloads ... is now saved
|
||||
return minetest.serialize({
|
||||
stored_energy = self._energy,
|
||||
stored_owner = self.owner,
|
||||
stored_hp = self.hp_max,
|
||||
stored_color = self._color,
|
||||
stored_power_lever = self._power_lever,
|
||||
stored_driver_name = self.driver_name,
|
||||
stored_inv_id = self._inv_id,
|
||||
})
|
||||
end,
|
||||
|
||||
on_deactivate = function(self)
|
||||
airutils.save_inventory(self)
|
||||
end,
|
||||
|
||||
on_activate = function(self, staticdata, dtime_s)
|
||||
airutils.actfunc(self, staticdata, dtime_s)
|
||||
if staticdata ~= "" and staticdata ~= nil then
|
||||
local data = minetest.deserialize(staticdata) or {}
|
||||
self._energy = data.stored_energy
|
||||
self.owner = data.stored_owner
|
||||
self.hp_max = data.stored_hp
|
||||
self._color = data.stored_color
|
||||
self._power_lever = data.stored_power_lever
|
||||
self.driver_name = data.stored_driver_name
|
||||
self._inv_id = data.stored_inv_id
|
||||
--minetest.debug("loaded: ", self._energy)
|
||||
end
|
||||
airutils.setText(self, "ultralight trike")
|
||||
self.object:set_animation({x = 1, y = 12}, 0, 0, true)
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
local engine=minetest.add_entity(pos,'trike:engine')
|
||||
engine:set_attach(self.object,'',{x=0,y=0,z=0},{x=0,y=0,z=0})
|
||||
-- set the animation once and later only change the speed
|
||||
engine:set_animation({x = 1, y = 12}, 0, 0, true)
|
||||
self.engine = engine
|
||||
|
||||
local wheel=minetest.add_entity(pos,'trike:front_wheel')
|
||||
wheel:set_attach(self.object,'',{x=0,y=0,z=0},{x=0,y=0,z=0})
|
||||
-- set the animation once and later only change the speed
|
||||
wheel:set_animation({x = 1, y = 12}, 0, 0, true)
|
||||
self.wheel = wheel
|
||||
|
||||
local fuel_gauge=minetest.add_entity(pos,'trike:pointer')
|
||||
local energy_indicator_angle = trike.get_gauge_angle(self._energy)
|
||||
fuel_gauge:set_attach(self.object,'',TRIKE_GAUGE_FUEL_POSITION,{x=0,y=0,z=energy_indicator_angle})
|
||||
self.fuel_gauge = fuel_gauge
|
||||
|
||||
local power_gauge=minetest.add_entity(pos,'trike:pointer')
|
||||
local power_indicator_angle = trike.get_gauge_angle(self._power_lever)
|
||||
power_gauge:set_attach(self.object,'',TRIKE_GAUGE_POWER_POSITION,{x=0,y=0,z=power_indicator_angle})
|
||||
self.power_gauge = power_gauge
|
||||
|
||||
local climb_gauge=minetest.add_entity(pos,'trike:pointer')
|
||||
local climb_angle = trike.get_gauge_angle(0)
|
||||
climb_gauge:set_attach(self.object,'',TRIKE_GAUGE_CLIMBER_POSITION,{x=0,y=0,z=climb_angle})
|
||||
self.climb_gauge = climb_gauge
|
||||
|
||||
local pilot_seat_base=minetest.add_entity(pos,'trike:seat_base')
|
||||
pilot_seat_base:set_attach(self.object,'',{x=0,y=7,z=8},{x=0,y=0,z=0})
|
||||
self.pilot_seat_base = pilot_seat_base
|
||||
|
||||
local passenger_seat_base=minetest.add_entity(pos,'trike:seat_base')
|
||||
passenger_seat_base:set_attach(self.object,'',{x=0,y=9,z=1.6},{x=0,y=0,z=0})
|
||||
self.passenger_seat_base = passenger_seat_base
|
||||
|
||||
airutils.paint(self, self._color, "trike_painting.png")
|
||||
|
||||
self.object:set_armor_groups({immortal=1})
|
||||
|
||||
local inv = minetest.get_inventory({type = "detached", name = self._inv_id})
|
||||
-- if the game was closed the inventories have to be made anew, instead of just reattached
|
||||
if not inv then
|
||||
airutils.create_inventory(self, trike.trunk_slots)
|
||||
else
|
||||
self.inv = inv
|
||||
end
|
||||
end,
|
||||
|
||||
--on_step = airutils.stepfunc,
|
||||
on_step = function(self,dtime,colinfo)
|
||||
self.dtime = math.min(dtime,0.2)
|
||||
self.colinfo = colinfo
|
||||
self.height = airutils.get_box_height(self)
|
||||
|
||||
-- physics comes first
|
||||
local vel = self.object:get_velocity()
|
||||
|
||||
if colinfo then
|
||||
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
|
||||
|
||||
self:physics()
|
||||
|
||||
if self.logic then
|
||||
self:logic()
|
||||
end
|
||||
|
||||
self.lastvelocity = self.object:get_velocity()
|
||||
self.time_total=self.time_total+self.dtime
|
||||
end,
|
||||
|
||||
logic = trike.flightstep,
|
||||
|
||||
on_punch = function(self, puncher, ttime, toolcaps, dir, damage)
|
||||
if self.hp_max <= 0 then
|
||||
trike.destroy(self)
|
||||
end
|
||||
|
||||
if not puncher or not puncher:is_player() then
|
||||
return
|
||||
end
|
||||
local is_admin = false
|
||||
is_admin = minetest.check_player_privs(puncher, {server=true})
|
||||
local name = puncher:get_player_name()
|
||||
if self.owner and self.owner ~= name and self.owner ~= "" then
|
||||
if is_admin == false then return end
|
||||
end
|
||||
if self.owner == nil then
|
||||
self.owner = name
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
local is_attached = false
|
||||
if puncher:get_attach() == self.object then is_attached = true end
|
||||
|
||||
local itmstck=puncher:get_wielded_item()
|
||||
local item_name = ""
|
||||
if itmstck then item_name = itmstck:get_name() end
|
||||
|
||||
if is_attached == false then
|
||||
if trike.loadFuel(self, puncher:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
--repair
|
||||
if item_name == "airutils:repair_tool" and self._engine_running == false then
|
||||
if self.hp_max < 50 then
|
||||
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
|
||||
if self.hp_max > 50 then self.hp_max = 50 end
|
||||
airutils.setText(self,"ultralight trike")
|
||||
else
|
||||
minetest.chat_send_player(puncher:get_player_name(), "You need steel ingots in your inventory to perform this repair.")
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- deal with painting or destroying
|
||||
if itmstck then
|
||||
if airutils.set_paint(self, puncher, itmstck, "trike_painting.png") == false then
|
||||
-- deal damage
|
||||
if not self.driver and toolcaps and toolcaps.damage_groups and
|
||||
toolcaps.damage_groups.fleshy and item_name ~= airutils.fuel then
|
||||
--airutils.hurt(self,toolcaps.damage_groups.fleshy - 1)
|
||||
--airutils.make_sound(self,'hit')
|
||||
self.hp_max = self.hp_max - 10
|
||||
minetest.sound_play("trike_collision", {
|
||||
object = self.object,
|
||||
max_hear_distance = 5,
|
||||
gain = 1.0,
|
||||
fade = 0.0,
|
||||
pitch = 1.0,
|
||||
})
|
||||
airutils.setText(self,"ultralight trike")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.hp_max <= 0 then
|
||||
trike.destroy(self)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end,
|
||||
|
||||
on_rightclick = function(self, clicker)
|
||||
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
|
||||
|
||||
local passenger_name = nil
|
||||
if self._passenger then
|
||||
passenger_name = self._passenger
|
||||
end
|
||||
|
||||
local touching_ground, liquid_below = trike.check_node_below(self.object)
|
||||
local is_on_ground = self.isinliquid or touching_ground or liquid_below
|
||||
local is_under_water = airutils.check_is_under_water(self.object)
|
||||
|
||||
--minetest.chat_send_all('name '.. dump(name) .. ' - pilot: ' .. dump(self.driver_name) .. ' - pax: ' .. dump(passenger_name))
|
||||
--=========================
|
||||
-- detach pilot
|
||||
--=========================
|
||||
if name == self.driver_name then
|
||||
trike.pilot_formspec(name)
|
||||
--=========================
|
||||
-- detach passenger
|
||||
--=========================
|
||||
elseif name == passenger_name then
|
||||
if is_on_ground or clicker:get_player_control().sneak then
|
||||
trike.dettach_pax(self, clicker)
|
||||
else
|
||||
minetest.chat_send_player(name, "Hold sneak and right-click to disembark while flying")
|
||||
end
|
||||
|
||||
--=========================
|
||||
-- attach pilot
|
||||
--=========================
|
||||
elseif not self.driver_name then
|
||||
if self.owner == name or minetest.check_player_privs(clicker, {protection_bypass=true}) then
|
||||
if clicker:get_player_control().aux1 == true then --lets see the inventory
|
||||
airutils.show_vehicle_trunk_formspec(self, clicker, trike.trunk_slots)
|
||||
else
|
||||
if trike.restricted == "true" and not minetest.check_player_privs(clicker, {flight_licence=true}) then
|
||||
minetest.show_formspec(name, "trike:flightlicence",
|
||||
"size[4,2]" ..
|
||||
"label[0.0,0.0;Sorry ...]"..
|
||||
"label[0.0,0.7;You need a flight licence to fly it.]" ..
|
||||
"label[0.0,1.0;You must obtain it from server admin.]" ..
|
||||
"button_exit[1.5,1.9;0.9,0.1;e;Exit]")
|
||||
return
|
||||
end
|
||||
|
||||
if is_under_water then return end
|
||||
--remove pax to prevent bug
|
||||
if self._passenger then
|
||||
local pax_obj = minetest.get_player_by_name(self._passenger)
|
||||
trike.dettach_pax(self, pax_obj)
|
||||
end
|
||||
|
||||
--attach player
|
||||
-- no driver => clicker is new driver
|
||||
trike.attach(self, clicker)
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(name, core.colorize('#ff0000', " >>> You aren't the owner of this ultralight."))
|
||||
end
|
||||
|
||||
--=========================
|
||||
-- attach passenger
|
||||
--=========================
|
||||
elseif self.driver_name and not self._passenger then
|
||||
trike.attach_pax(self, clicker)
|
||||
|
||||
else
|
||||
minetest.chat_send_player(name, core.colorize('#ff0000', " >>> Can't enter airplane."))
|
||||
end
|
||||
end,
|
||||
|
||||
})
|
@ -1,57 +0,0 @@
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "trike_global_definitions.lua")
|
||||
|
||||
--------------
|
||||
-- Manual --
|
||||
--------------
|
||||
|
||||
function trike.getPlaneFromPlayer(player)
|
||||
local seat = player:get_attach()
|
||||
if seat then
|
||||
local plane = seat:get_attach()
|
||||
return plane
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function trike.pilot_formspec(name)
|
||||
local basic_form = table.concat({
|
||||
"formspec_version[3]",
|
||||
"size[6,4.5]",
|
||||
}, "")
|
||||
|
||||
basic_form = basic_form.."button[1,1.0;4,1;go_out;Go Offboard]"
|
||||
basic_form = basic_form.."button[1,2.5;4,1;hud;Show/Hide Gauges]"
|
||||
|
||||
minetest.show_formspec(name, "trike:pilot_main", basic_form)
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname == "trike:pilot_main" then
|
||||
local name = player:get_player_name()
|
||||
local plane_obj = trike.getPlaneFromPlayer(player)
|
||||
if plane_obj == nil then
|
||||
minetest.close_formspec(name, "trike:pilot_main")
|
||||
return
|
||||
end
|
||||
local ent = plane_obj:get_luaentity()
|
||||
if fields.hud then
|
||||
if ent._show_hud == true then
|
||||
ent._show_hud = false
|
||||
else
|
||||
ent._show_hud = true
|
||||
end
|
||||
end
|
||||
if fields.go_out then
|
||||
-- eject passenger if the plane is on ground
|
||||
local touching_ground, liquid_below = trike.check_node_below(plane_obj)
|
||||
if ent.isinliquid or touching_ground or liquid_below then --isn't flying?
|
||||
if ent._passenger then
|
||||
local passenger = minetest.get_player_by_name(ent._passenger)
|
||||
if passenger then trike.dettach_pax(ent, passenger) end
|
||||
end
|
||||
end
|
||||
trike.dettachPlayer(ent, player)
|
||||
end
|
||||
minetest.close_formspec(name, "trike:pilot_main")
|
||||
end
|
||||
end)
|
@ -1,48 +0,0 @@
|
||||
function trike.contains(table, val)
|
||||
for k,v in pairs(table) do
|
||||
if k == val then
|
||||
return v
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function trike.loadFuel(self, player_name)
|
||||
local player = minetest.get_player_by_name(player_name)
|
||||
local inv = player:get_inventory()
|
||||
|
||||
local itmstck=player:get_wielded_item()
|
||||
local item_name = ""
|
||||
if itmstck then item_name = itmstck:get_name() end
|
||||
|
||||
local fuel = trike.contains(airutils.fuel, item_name)
|
||||
if fuel then
|
||||
if self._energy < 10 then
|
||||
itmstck:set_count(1)
|
||||
inv:remove_item("main", itmstck)
|
||||
self._energy = self._energy + fuel
|
||||
if self._energy > 10 then self._energy = 10 end
|
||||
|
||||
local energy_indicator_angle = trike.get_gauge_angle(self._energy)
|
||||
self.fuel_gauge:set_attach(self.object,'',TRIKE_GAUGE_FUEL_POSITION,{x=0,y=0,z=energy_indicator_angle})
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function trike.consumptionCalc(self, accel)
|
||||
if accel == nil then return end
|
||||
if self._energy > 0 and self._engine_running and accel ~= nil then
|
||||
local consumed_power = self._power_lever/700000
|
||||
--minetest.chat_send_all('consumed: '.. consumed_power)
|
||||
self._energy = self._energy - consumed_power;
|
||||
end
|
||||
if self._energy <= 0 and self._engine_running and accel ~= nil then
|
||||
self._engine_running = false
|
||||
if self.sound_handle then minetest.sound_stop(self.sound_handle) end
|
||||
self.engine:set_animation_frame_speed(0)
|
||||
end
|
||||
end
|
@ -1,13 +0,0 @@
|
||||
--
|
||||
-- constants
|
||||
--
|
||||
LONGIT_DRAG_FACTOR = 0.13*0.13
|
||||
LATER_DRAG_FACTOR = 2.0
|
||||
|
||||
deg = math.deg
|
||||
abs = math.abs
|
||||
|
||||
TRIKE_GAUGE_FUEL_POSITION = {x=1.5,y=6.2,z=15.2}
|
||||
TRIKE_GAUGE_POWER_POSITION = {x=1.5,y=7.7,z=15.2}
|
||||
TRIKE_GAUGE_CLIMBER_POSITION = {x=-1.2,y=7.55,z=15.2}
|
||||
|
354
trike_hud.lua
@ -1,354 +0,0 @@
|
||||
trike.hud_list = {}
|
||||
|
||||
function trike.animate_gauge(player, ids, prefix, x, y, angle)
|
||||
local angle_in_rad = math.rad(angle + 180)
|
||||
local dim = 10
|
||||
local pos_x = math.sin(angle_in_rad) * dim
|
||||
local pos_y = math.cos(angle_in_rad) * dim
|
||||
player:hud_change(ids[prefix .. "2"], "offset", {x = pos_x + x, y = pos_y + y})
|
||||
dim = 20
|
||||
pos_x = math.sin(angle_in_rad) * dim
|
||||
pos_y = math.cos(angle_in_rad) * dim
|
||||
player:hud_change(ids[prefix .. "3"], "offset", {x = pos_x + x, y = pos_y + y})
|
||||
dim = 30
|
||||
pos_x = math.sin(angle_in_rad) * dim
|
||||
pos_y = math.cos(angle_in_rad) * dim
|
||||
player:hud_change(ids[prefix .. "4"], "offset", {x = pos_x + x, y = pos_y + y})
|
||||
dim = 40
|
||||
pos_x = math.sin(angle_in_rad) * dim
|
||||
pos_y = math.cos(angle_in_rad) * dim
|
||||
player:hud_change(ids[prefix .. "5"], "offset", {x = pos_x + x, y = pos_y + y})
|
||||
dim = 50
|
||||
pos_x = math.sin(angle_in_rad) * dim
|
||||
pos_y = math.cos(angle_in_rad) * dim
|
||||
player:hud_change(ids[prefix .. "6"], "offset", {x = pos_x + x, y = pos_y + y})
|
||||
dim = 60
|
||||
pos_x = math.sin(angle_in_rad) * dim
|
||||
pos_y = math.cos(angle_in_rad) * dim
|
||||
player:hud_change(ids[prefix .. "7"], "offset", {x = pos_x + x, y = pos_y + y})
|
||||
end
|
||||
|
||||
function trike.update_hud(player, climb, speed, power, fuel)
|
||||
local player_name = player:get_player_name()
|
||||
|
||||
local screen_pos_y = -150
|
||||
local screen_pos_x = 10
|
||||
|
||||
local clb_gauge_x = screen_pos_x + 75
|
||||
local clb_gauge_y = screen_pos_y + 1
|
||||
local sp_gauge_x = screen_pos_x + 170
|
||||
local sp_gauge_y = clb_gauge_y
|
||||
|
||||
local pwr_gauge_x = screen_pos_x + 330
|
||||
local pwr_gauge_y = clb_gauge_y
|
||||
|
||||
local fu_gauge_x = screen_pos_x + 340
|
||||
local fu_gauge_y = clb_gauge_y
|
||||
|
||||
local ids = trike.hud_list[player_name]
|
||||
if ids then
|
||||
trike.animate_gauge(player, ids, "clb_pt_", clb_gauge_x, clb_gauge_y, climb)
|
||||
trike.animate_gauge(player, ids, "sp_pt_", sp_gauge_x, sp_gauge_y, speed)
|
||||
trike.animate_gauge(player, ids, "pwr_pt_", pwr_gauge_x, pwr_gauge_y, power)
|
||||
trike.animate_gauge(player, ids, "fu_pt_", fu_gauge_x, fu_gauge_y, fuel)
|
||||
else
|
||||
ids = {}
|
||||
|
||||
ids["title"] = player:hud_add({
|
||||
hud_elem_type = "text",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = screen_pos_x +140, y = screen_pos_y -100},
|
||||
text = "Flight Information",
|
||||
alignment = 0,
|
||||
scale = { x = 100, y = 30},
|
||||
number = 0xFFFFFF,
|
||||
})
|
||||
|
||||
ids["bg"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = screen_pos_x, y = screen_pos_y},
|
||||
text = "trike_hud_panel.png",
|
||||
scale = { x = 0.5, y = 0.5},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
|
||||
ids["clb_pt_1"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = clb_gauge_x, y = clb_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
|
||||
ids["clb_pt_2"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = clb_gauge_x, y = clb_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["clb_pt_3"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = clb_gauge_x, y = clb_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["clb_pt_4"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = clb_gauge_x, y = clb_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["clb_pt_5"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = clb_gauge_x, y = clb_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["clb_pt_6"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = clb_gauge_x, y = clb_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["clb_pt_7"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = clb_gauge_x, y = clb_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
|
||||
ids["sp_pt_1"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = sp_gauge_x, y = sp_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["sp_pt_2"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = sp_gauge_x, y = sp_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["sp_pt_3"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = sp_gauge_x, y = sp_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["sp_pt_4"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = sp_gauge_x, y = sp_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["sp_pt_5"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = sp_gauge_x, y = sp_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["sp_pt_6"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = sp_gauge_x, y = sp_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["sp_pt_7"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = sp_gauge_x, y = sp_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
|
||||
ids["pwr_pt_1"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = pwr_gauge_x, y = pwr_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
|
||||
ids["pwr_pt_2"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = pwr_gauge_x, y = pwr_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["pwr_pt_3"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = pwr_gauge_x, y = pwr_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["pwr_pt_4"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = pwr_gauge_x, y = pwr_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["pwr_pt_5"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = pwr_gauge_x, y = pwr_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["pwr_pt_6"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = pwr_gauge_x, y = pwr_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["pwr_pt_7"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = pwr_gauge_x, y = pwr_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
|
||||
ids["fu_pt_1"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = fu_gauge_x, y = fu_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
|
||||
ids["fu_pt_2"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = fu_gauge_x, y = fu_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["fu_pt_3"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = fu_gauge_x, y = fu_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["fu_pt_4"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = fu_gauge_x, y = fu_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["fu_pt_5"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = fu_gauge_x, y = fu_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["fu_pt_6"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = fu_gauge_x, y = fu_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
ids["fu_pt_7"] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0, y = 1},
|
||||
offset = {x = fu_gauge_x, y = fu_gauge_y},
|
||||
text = "trike_ind_box.png",
|
||||
scale = { x = 6, y = 6},
|
||||
alignment = { x = 1, y = 0 },
|
||||
})
|
||||
|
||||
trike.hud_list[player_name] = ids
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function trike.remove_hud(player)
|
||||
if player then
|
||||
local player_name = player:get_player_name()
|
||||
--minetest.chat_send_all(player_name)
|
||||
local ids = trike.hud_list[player_name]
|
||||
if ids then
|
||||
--player:hud_remove(ids["altitude"])
|
||||
--player:hud_remove(ids["time"])
|
||||
player:hud_remove(ids["title"])
|
||||
player:hud_remove(ids["bg"])
|
||||
player:hud_remove(ids["clb_pt_7"])
|
||||
player:hud_remove(ids["clb_pt_6"])
|
||||
player:hud_remove(ids["clb_pt_5"])
|
||||
player:hud_remove(ids["clb_pt_4"])
|
||||
player:hud_remove(ids["clb_pt_3"])
|
||||
player:hud_remove(ids["clb_pt_2"])
|
||||
player:hud_remove(ids["clb_pt_1"])
|
||||
player:hud_remove(ids["sp_pt_7"])
|
||||
player:hud_remove(ids["sp_pt_6"])
|
||||
player:hud_remove(ids["sp_pt_5"])
|
||||
player:hud_remove(ids["sp_pt_4"])
|
||||
player:hud_remove(ids["sp_pt_3"])
|
||||
player:hud_remove(ids["sp_pt_2"])
|
||||
player:hud_remove(ids["sp_pt_1"])
|
||||
player:hud_remove(ids["pwr_pt_7"])
|
||||
player:hud_remove(ids["pwr_pt_6"])
|
||||
player:hud_remove(ids["pwr_pt_5"])
|
||||
player:hud_remove(ids["pwr_pt_4"])
|
||||
player:hud_remove(ids["pwr_pt_3"])
|
||||
player:hud_remove(ids["pwr_pt_2"])
|
||||
player:hud_remove(ids["pwr_pt_1"])
|
||||
player:hud_remove(ids["fu_pt_7"])
|
||||
player:hud_remove(ids["fu_pt_6"])
|
||||
player:hud_remove(ids["fu_pt_5"])
|
||||
player:hud_remove(ids["fu_pt_4"])
|
||||
player:hud_remove(ids["fu_pt_3"])
|
||||
player:hud_remove(ids["fu_pt_2"])
|
||||
player:hud_remove(ids["fu_pt_1"])
|
||||
end
|
||||
trike.hud_list[player_name] = nil
|
||||
end
|
||||
|
||||
end
|
@ -1,477 +0,0 @@
|
||||
dofile(minetest.get_modpath("trike") .. DIR_DELIM .. "trike_global_definitions.lua")
|
||||
|
||||
function trike.get_hipotenuse_value(point1, point2)
|
||||
return math.sqrt((point1.x - point2.x) ^ 2 + (point1.y - point2.y) ^ 2 + (point1.z - point2.z) ^ 2)
|
||||
end
|
||||
|
||||
function trike.dot(v1,v2)
|
||||
return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z
|
||||
end
|
||||
|
||||
function trike.sign(n)
|
||||
return n>=0 and 1 or -1
|
||||
end
|
||||
|
||||
function trike.minmax(v,m)
|
||||
return math.min(math.abs(v),m)*trike.sign(v)
|
||||
end
|
||||
|
||||
function trike.get_gauge_angle(value)
|
||||
local angle = value * 18
|
||||
angle = angle - 90
|
||||
angle = angle * -1
|
||||
return angle
|
||||
end
|
||||
|
||||
-- attach player
|
||||
function trike.attach(self, player)
|
||||
local name = player:get_player_name()
|
||||
self.driver_name = name
|
||||
|
||||
-- attach the driver
|
||||
player:set_attach(self.pilot_seat_base, "", {x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
||||
local eye_y = -6
|
||||
if airutils.detect_player_api(player) == 1 then
|
||||
eye_y = 0.5
|
||||
end
|
||||
player:set_eye_offset({x = 0, y = eye_y, z = 2}, {x = 0, y = 1, z = -30})
|
||||
player_api.player_attached[name] = true
|
||||
player_api.set_animation(player, "sit")
|
||||
-- make the driver sit
|
||||
minetest.after(1, function()
|
||||
player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
airutils.sit(player)
|
||||
--apply_physics_override(player, {speed=0,gravity=0,jump=0})
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- attach passenger
|
||||
function trike.attach_pax(self, player)
|
||||
local name = player:get_player_name()
|
||||
self._passenger = name
|
||||
|
||||
-- attach the driver
|
||||
player:set_attach(self.passenger_seat_base, "", {x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
||||
local eye_y = -3
|
||||
if airutils.detect_player_api(player) == 1 then
|
||||
eye_y = 3.5
|
||||
end
|
||||
player:set_eye_offset({x = 0, y = eye_y, z = 3}, {x = 0, y = 3, z = -30})
|
||||
player_api.player_attached[name] = true
|
||||
player_api.set_animation(player, "sit")
|
||||
-- make the driver sit
|
||||
minetest.after(1, function()
|
||||
player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
airutils.sit(player)
|
||||
--apply_physics_override(player, {speed=0,gravity=0,jump=0})
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function trike.dettachPlayer(self, player)
|
||||
local name = self.driver_name
|
||||
airutils.setText(self,"ultralight trike")
|
||||
|
||||
trike.remove_hud(player)
|
||||
self._engine_running = false
|
||||
|
||||
-- driver clicked the object => driver gets off the vehicle
|
||||
self.driver_name = nil
|
||||
-- sound and animation
|
||||
if self.sound_handle then
|
||||
minetest.sound_stop(self.sound_handle)
|
||||
self.sound_handle = nil
|
||||
end
|
||||
|
||||
self.engine:set_animation_frame_speed(0)
|
||||
|
||||
-- detach the player
|
||||
if player then
|
||||
player:set_detach()
|
||||
player_api.player_attached[name] = nil
|
||||
player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
|
||||
player_api.set_animation(player, "stand")
|
||||
end
|
||||
self.driver = nil
|
||||
--remove_physics_override(player, {speed=1,gravity=1,jump=1})
|
||||
end
|
||||
|
||||
function trike.dettach_pax(self, player)
|
||||
local name = self._passenger
|
||||
|
||||
-- passenger clicked the object => driver gets off the vehicle
|
||||
self._passenger = nil
|
||||
|
||||
-- detach the player
|
||||
if player then
|
||||
player:set_detach()
|
||||
player_api.player_attached[name] = nil
|
||||
player_api.set_animation(player, "stand")
|
||||
player:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
|
||||
--remove_physics_override(player, {speed=1,gravity=1,jump=1})
|
||||
end
|
||||
end
|
||||
|
||||
function trike.checkAttach(self, player)
|
||||
if player then
|
||||
local player_attach = player:get_attach()
|
||||
if player_attach then
|
||||
if player_attach == self.pilot_seat_base then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- destroy the boat
|
||||
function trike.destroy(self)
|
||||
if self.sound_handle then
|
||||
minetest.sound_stop(self.sound_handle)
|
||||
self.sound_handle = nil
|
||||
end
|
||||
|
||||
if self._passenger then
|
||||
-- detach the passenger
|
||||
local passenger = minetest.get_player_by_name(self._passenger)
|
||||
if passenger then
|
||||
trike.dettach_pax(self, passenger)
|
||||
end
|
||||
end
|
||||
|
||||
if self.driver_name then
|
||||
-- detach the driver
|
||||
local player = minetest.get_player_by_name(self.driver_name)
|
||||
trike.dettachPlayer(self, player)
|
||||
end
|
||||
|
||||
local pos = self.object:get_pos()
|
||||
if self.fuel_gauge then self.fuel_gauge:remove() end
|
||||
if self.power_gauge then self.power_gauge:remove() end
|
||||
if self.climb_gauge then self.climb_gauge:remove() end
|
||||
if self.engine then self.engine:remove() end
|
||||
if self.wheel then self.wheel:remove() end
|
||||
if self.pilot_seat_base then self.pilot_seat_base:remove() end
|
||||
if self.passenger_seat_base then self.passenger_seat_base:remove() end
|
||||
|
||||
airutils.destroy_inventory(self)
|
||||
self.object:remove()
|
||||
|
||||
pos.y=pos.y+2
|
||||
minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'trike:wing')
|
||||
|
||||
for i=1,6 do
|
||||
minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'default:mese_crystal')
|
||||
minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'default:diamond')
|
||||
end
|
||||
|
||||
for i=1,3 do
|
||||
minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'default:steel_ingot')
|
||||
end
|
||||
|
||||
--minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'trike:trike')
|
||||
|
||||
--local total_biofuel = math.floor(self._energy) - 1
|
||||
--for i=0,total_biofuel do
|
||||
--minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'biofuel:biofuel')
|
||||
--end
|
||||
end
|
||||
|
||||
function trike.check_node_below(obj)
|
||||
local pos_below = obj:get_pos()
|
||||
if pos_below then
|
||||
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
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
function trike.testImpact(self, velocity)
|
||||
local p = self.object:get_pos()
|
||||
local collision = false
|
||||
if self.lastvelocity == nil then return end
|
||||
--lets calculate the vertical speed, to avoid the bug on colliding on floor with hard lag
|
||||
if abs(velocity.y - self.lastvelocity.y) > 2 then
|
||||
local noded = airutils.nodeatpos(airutils.pos_shift(p,{y=-1}))
|
||||
if (noded and noded.drawtype ~= 'airlike') then
|
||||
collision = true
|
||||
else
|
||||
self.object:set_velocity(self.lastvelocity)
|
||||
self.object:set_acceleration(self._last_accell)
|
||||
end
|
||||
end
|
||||
local impact = abs(trike.get_hipotenuse_value(velocity, self.lastvelocity))
|
||||
if impact > 2 then
|
||||
--minetest.chat_send_all('impact: '.. impact .. ' - hp: ' .. self.hp_max)
|
||||
if self.colinfo then
|
||||
collision = self.colinfo.collides
|
||||
end
|
||||
end
|
||||
|
||||
if impact > 0.5 and self._longit_speed > 2 then
|
||||
local noded = airutils.nodeatpos(airutils.pos_shift(p,{y=-0.1}))
|
||||
if (noded and noded.drawtype ~= 'airlike') then
|
||||
minetest.sound_play("trike_touch", {
|
||||
--to_player = self.driver_name,
|
||||
object = self.object,
|
||||
max_hear_distance = 15,
|
||||
gain = 1.0,
|
||||
fade = 0.0,
|
||||
pitch = 1.0,
|
||||
}, true)
|
||||
end
|
||||
end
|
||||
|
||||
if collision then
|
||||
--self.object:set_velocity({x=0,y=0,z=0})
|
||||
local damage = impact / 2
|
||||
self.hp_max = self.hp_max - damage --subtract the impact value directly to hp meter
|
||||
|
||||
if self.driver_name then
|
||||
minetest.sound_play("trike_collision", {
|
||||
to_player = self.driver_name,
|
||||
--pos = curr_pos,
|
||||
--max_hear_distance = 5,
|
||||
gain = 1.0,
|
||||
fade = 0.0,
|
||||
pitch = 1.0,
|
||||
})
|
||||
|
||||
local player_name = self.driver_name
|
||||
airutils.setText(self,"ultralight trike")
|
||||
|
||||
--minetest.chat_send_all('damage: '.. damage .. ' - hp: ' .. self.hp_max)
|
||||
if self.hp_max < 0 then --if acumulated damage is greater than 50, adieu
|
||||
trike.destroy(self)
|
||||
end
|
||||
|
||||
local player = minetest.get_player_by_name(player_name)
|
||||
if player then
|
||||
if player:get_hp() > 0 then
|
||||
player:set_hp(player:get_hp()-(damage/2))
|
||||
end
|
||||
end
|
||||
if self._passenger ~= nil then
|
||||
local passenger = minetest.get_player_by_name(self._passenger)
|
||||
if passenger then
|
||||
if passenger:get_hp() > 0 then
|
||||
passenger:set_hp(passenger:get_hp()-(damage/2))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function trike.checkattachBug(self)
|
||||
-- for some engine error the player can be detached from the submarine, so lets set him attached again
|
||||
local can_stop = true
|
||||
if self.owner and self.driver_name then
|
||||
-- attach the driver again
|
||||
local player = minetest.get_player_by_name(self.owner)
|
||||
if player then
|
||||
if player:get_hp() > 0 then
|
||||
trike.attach(self, player)
|
||||
can_stop = false
|
||||
else
|
||||
trike.dettachPlayer(self, player)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if can_stop then
|
||||
--detach player
|
||||
if self.sound_handle ~= nil then
|
||||
minetest.sound_stop(self.sound_handle)
|
||||
self.sound_handle = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function trike.flightstep(self)
|
||||
local accel_y = self.object:get_acceleration().y
|
||||
local rotation = airutils.normalize_rotations(self.object:get_rotation())
|
||||
local yaw = rotation.y
|
||||
local newyaw=yaw
|
||||
local pitch = rotation.x
|
||||
local roll = rotation.z
|
||||
|
||||
local velocity = self.object:get_velocity()
|
||||
--self.object:set_velocity(velocity) --hack to avoid glitches
|
||||
local hull_direction = airutils.rot_to_dir(rotation) --minetest.yaw_to_dir(yaw)
|
||||
local nhdir = {x=hull_direction.z,y=0,z=-hull_direction.x} -- lateral unit vector
|
||||
|
||||
local longit_speed = vector.dot(velocity,hull_direction)
|
||||
self._longit_speed = longit_speed
|
||||
local longit_drag = vector.multiply(hull_direction,longit_speed*longit_speed*LONGIT_DRAG_FACTOR*
|
||||
-1*trike.sign(longit_speed))
|
||||
local later_speed = trike.dot(velocity,nhdir)
|
||||
--minetest.chat_send_all('later_speed: '.. later_speed)
|
||||
local later_drag = vector.multiply(nhdir,later_speed*later_speed*LATER_DRAG_FACTOR*-1*trike.sign(later_speed))
|
||||
local accel = vector.add(longit_drag,later_drag)
|
||||
local stop = false
|
||||
|
||||
local player = nil
|
||||
if self.driver_name then player = minetest.get_player_by_name(self.driver_name) end
|
||||
|
||||
local curr_pos = self.object:get_pos()
|
||||
self.object:move_to(curr_pos)
|
||||
|
||||
local node_bellow = airutils.nodeatpos(airutils.pos_shift(curr_pos,{y=-1}))
|
||||
local is_flying = true
|
||||
if self.colinfo then
|
||||
is_flying = not self.colinfo.touching_ground
|
||||
end
|
||||
|
||||
local is_attached = trike.checkAttach(self, player)
|
||||
|
||||
if not is_attached then
|
||||
-- for some engine error the player can be detached from the machine, so lets set him attached again
|
||||
trike.checkattachBug(self)
|
||||
end
|
||||
|
||||
if longit_speed == 0 and is_flying == false and is_attached == false and self._engine_running == false then
|
||||
return
|
||||
end
|
||||
|
||||
if is_attached then
|
||||
--control
|
||||
accel, stop = trike.control(self, self.dtime, hull_direction,
|
||||
longit_speed, longit_drag, later_speed, later_drag, accel, player, is_flying)
|
||||
end
|
||||
trike.testImpact(self, velocity)
|
||||
|
||||
-- new yaw
|
||||
if math.abs(self._rudder_angle)>5 then
|
||||
local turn_rate = math.rad(24)
|
||||
newyaw = yaw + self.dtime*(1 - 1 / (math.abs(longit_speed) + 1)) *
|
||||
self._rudder_angle / 30 * turn_rate * trike.sign(longit_speed)
|
||||
end
|
||||
|
||||
-- calculate energy consumption --
|
||||
trike.consumptionCalc(self, accel)
|
||||
|
||||
--roll adjust
|
||||
---------------------------------
|
||||
local sdir = minetest.yaw_to_dir(newyaw)
|
||||
local snormal = {x=sdir.z,y=0,z=-sdir.x} -- rightside, dot is negative
|
||||
local prsr = trike.dot(snormal,nhdir)
|
||||
local rollfactor = -20
|
||||
local newroll = (prsr*math.rad(rollfactor))*(later_speed)
|
||||
--minetest.chat_send_all('newroll: '.. newroll)
|
||||
---------------------------------
|
||||
-- end roll
|
||||
|
||||
-- pitch
|
||||
local newpitch = self._angle_of_attack/200 --(velocity.y * math.rad(6))
|
||||
|
||||
-- adjust pitch by velocity
|
||||
if is_flying == false then --isn't flying?
|
||||
if newpitch < 0 then newpitch = 0 end
|
||||
newroll = 0
|
||||
|
||||
local min_speed = 4
|
||||
if longit_speed < min_speed then
|
||||
if newpitch > 0 then
|
||||
local percentage = ((longit_speed * 100)/min_speed)/100
|
||||
newpitch = newpitch * percentage
|
||||
if newpitch < 0 then newpitch = 0 end
|
||||
end
|
||||
end
|
||||
|
||||
--animate wheels
|
||||
self.object:set_animation_frame_speed(longit_speed * 10)
|
||||
self.wheel:set_animation_frame_speed(longit_speed * 10)
|
||||
else
|
||||
--stop wheels
|
||||
self.object:set_animation_frame_speed(0)
|
||||
self.wheel:set_animation_frame_speed(0)
|
||||
end
|
||||
|
||||
local indicated_speed = longit_speed
|
||||
if indicated_speed < 0 then indicated_speed = 0 end
|
||||
local speed_angle = trike.get_gauge_angle(indicated_speed, -45)
|
||||
|
||||
--adjust power indicator
|
||||
local power_indicator_angle = trike.get_gauge_angle(self._power_lever/10)
|
||||
self.power_gauge:set_attach(self.object,'',TRIKE_GAUGE_POWER_POSITION,{x=0,y=0,z=power_indicator_angle})
|
||||
|
||||
--lift calculation
|
||||
accel.y = accel.y + airutils.gravity --accel_y
|
||||
local new_accel = accel
|
||||
if longit_speed > 2 then
|
||||
local lift = 10
|
||||
new_accel = airutils.getLiftAccel(self, velocity, new_accel, longit_speed, roll, curr_pos, lift, 2500)
|
||||
end
|
||||
|
||||
if self.isinliquid then self._engine_running = false end
|
||||
|
||||
--added accell check to avoid mercurio server problem
|
||||
if new_accel then
|
||||
if new_accel.x ~= nil and new_accel.y ~= nil and new_accel.z ~= nil then
|
||||
self.object:set_acceleration(new_accel)
|
||||
end
|
||||
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
|
||||
|
||||
--adjust wing pitch (3d model)
|
||||
self.object:set_bone_position("wing", {x=0,y=29,z=0}, {x=-self._angle_of_attack,y=0,z=(self._rudder_angle/3)})
|
||||
|
||||
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 *
|
||||
trike.sign(longit_speed) * math.abs(longit_speed/2)
|
||||
newyaw = yaw + yaw_turn
|
||||
end
|
||||
|
||||
if newyaw~=yaw or newpitch~=pitch or newroll~=roll then
|
||||
self.object:set_rotation({x=newpitch,y=newyaw,z=newroll})
|
||||
end
|
||||
|
||||
|
||||
if stop ~= true then
|
||||
self._last_accell = new_accel
|
||||
elseif stop == false then
|
||||
self.object:set_velocity({x=0,y=0,z=0})
|
||||
end
|
||||
|
||||
--adjust climb indicator
|
||||
local climb_rate = velocity.y * 1.5
|
||||
if climb_rate > 5 then climb_rate = 5 end
|
||||
if climb_rate < -5 then climb_rate = -5 end
|
||||
--minetest.chat_send_all('rate '.. climb_rate)
|
||||
local climb_angle = trike.get_gauge_angle(climb_rate)
|
||||
self.climb_gauge:set_attach(self.object,'',TRIKE_GAUGE_CLIMBER_POSITION,{x=0,y=0,z=climb_angle})
|
||||
|
||||
local energy_indicator_angle = trike.get_gauge_angle(self._energy)
|
||||
if self.fuel_gauge:get_luaentity() then
|
||||
self.fuel_gauge:set_attach(self.object,'',TRIKE_GAUGE_FUEL_POSITION,{x=0,y=0,z=energy_indicator_angle})
|
||||
end
|
||||
|
||||
if is_attached then
|
||||
if self._show_hud then
|
||||
trike.update_hud(player, climb_angle, speed_angle - 130, power_indicator_angle - 270, (energy_indicator_angle*-1)-90)
|
||||
else
|
||||
trike.remove_hud(player)
|
||||
end
|
||||
end
|
||||
|
||||
--saves last velocity for collision detection (abrupt stop)
|
||||
self.lastvelocity = self.object:get_velocity()
|
||||
end
|
||||
|