first
25
.luacheckrc
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
unused_args = false
|
||||||
|
allow_defined_top = true
|
||||||
|
|
||||||
|
globals = {
|
||||||
|
"minetest",
|
||||||
|
"mobkit",
|
||||||
|
"core",
|
||||||
|
"player_api",
|
||||||
|
"player_monoids",
|
||||||
|
"math.sign",
|
||||||
|
}
|
||||||
|
|
||||||
|
read_globals = {
|
||||||
|
string = {fields = {"split"}},
|
||||||
|
table = {fields = {"copy", "getn"}},
|
||||||
|
|
||||||
|
-- Builtin
|
||||||
|
"vector", "ItemStack",
|
||||||
|
"dump", "DIR_DELIM", "VoxelArea", "Settings",
|
||||||
|
|
||||||
|
-- MTG
|
||||||
|
"default", "sfinv", "creative",
|
||||||
|
}
|
||||||
|
|
||||||
|
ignore = {"611"}
|
2
LICENSE
Normal file → Executable file
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2023 Alexsandro Percy
|
Copyright (c) 2023 APercy - Alexsandro Percy
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
115
README.md
Normal file → Executable file
|
@ -1,2 +1,113 @@
|
||||||
# ap_airship
|
Minetest 5.4 mod: Steampunk Blimp
|
||||||
An Airship for Minetest
|
========================================
|
||||||
|
|
||||||
|
This mod implements a fantasy steampunk blimp for minetest.
|
||||||
|
The mod was made for fun, but tries to provide an immersion on it's operation.
|
||||||
|
It can carry 5 people.
|
||||||
|
|
||||||
|
To fly it, it is necessary to provide some items, such as fuel to be burned and
|
||||||
|
water for the boiler. The fuel can be coal, coal block and wood. To supply it,
|
||||||
|
be on board and punch the necessary items on the airship. There is another way to
|
||||||
|
load water to the boiler: if it is landed on water, it can load it through the
|
||||||
|
menu. But the current pressure will be lost.
|
||||||
|
|
||||||
|
Activate the furnace in the first option of the menu. Take control by activating
|
||||||
|
the option "Take the Control".
|
||||||
|
|
||||||
|
The information panel will be on the left and bottom of the screen. Wait for the
|
||||||
|
boiler to reach the proper pressure for operation (green) before operating the power lever.
|
||||||
|
To go up, press Jump (space). Note that it takes some pressure from the boiler. To go down,
|
||||||
|
hold sneak (shift).
|
||||||
|
|
||||||
|
Forward increases the propeller power, Backward reduces.
|
||||||
|
There is a power mode. When the lever reaches the up limit, hold E
|
||||||
|
and forward to increase the acceleration. But note that the boiler will lose pressure.
|
||||||
|
The blimp inventory can be accessed by Aux (E) + rightclick.
|
||||||
|
|
||||||
|
Shared owners:
|
||||||
|
This vehicle was made to be shared with a team. So the owner can set more users to
|
||||||
|
operate it. Inside the blimp, just use the command /blimp_share <name>
|
||||||
|
|
||||||
|
- To go reverse, hold aux (E key) and backward together.
|
||||||
|
- To remove someone from the sharing, /blimp_remove <name>
|
||||||
|
- To list the owners, /blimp_list
|
||||||
|
- To lock the blimp access, so only the owners can enter: /blimp_lock true
|
||||||
|
- To let anyone enter, /blimp_lock false
|
||||||
|
|
||||||
|
All shared owners can access the blimp inventory
|
||||||
|
|
||||||
|
Painting:
|
||||||
|
As the planes, punch a dye against the hull, so the primary color will change
|
||||||
|
- To change the secondary color, punch a dye, but holding Aux (E) key.
|
||||||
|
It is possible to set a logo on your blimp, so enter inside it and type the command /blimp_logo
|
||||||
|
Only the original owner can do the paintings
|
||||||
|
|
||||||
|
Shortcuts:
|
||||||
|
|
||||||
|
punch with dye to paint
|
||||||
|
forward and backward while in drive position: controls the power lever
|
||||||
|
left and right while in drive position: controls the direction
|
||||||
|
jump and sneak: controls the up and down movement
|
||||||
|
|
||||||
|
- right click to enter and access menu
|
||||||
|
- E + right click while inside: acess inventory
|
||||||
|
- E + backward while in drive position: the machine does backward
|
||||||
|
- E + foward while in drive position: extra power
|
||||||
|
|
||||||
|
Tip:
|
||||||
|
Drive it gently.
|
||||||
|
The captain can leave the drive position to walk too
|
||||||
|
If a player goes timeout or logoff in flight, the blimp will "rescue" him if no other player
|
||||||
|
enter the blimp, so is a good idea wait the friend at a secure place far from anyone who
|
||||||
|
wants to enter the blimp.
|
||||||
|
|
||||||
|
Know issues:
|
||||||
|
The walk movement inside the ship is affected by server lag, because the lack of
|
||||||
|
an interpolation method on attach function.
|
||||||
|
|
||||||
|
Rubber-band bug is from minetest nature, just close and reopen minetest to solve.
|
||||||
|
Or try to live the Michael Jackson's way of life and learn the Moonwalk properly XD
|
||||||
|
Some old versions of minetest can have an strange issue, the camera is set to
|
||||||
|
the map center. So if it happens, just type /blimp_eject to be free again.
|
||||||
|
|
||||||
|
|
||||||
|
License of source code:
|
||||||
|
MIT (see file LICENSE)
|
||||||
|
|
||||||
|
License of media (textures and sounds):
|
||||||
|
---------------------------------------
|
||||||
|
collision.ogg by APercy, CC0
|
||||||
|
|
||||||
|
Blimp model and textures by APercy. CC BY-SA 3.0
|
||||||
|
|
||||||
|
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||||
|
Copyright (C) 2022 Alexsandro Percy (APercy) <alexsandro.percy@gmail.com>
|
||||||
|
|
||||||
|
You are free to:
|
||||||
|
Share — copy and redistribute the material in any medium or format.
|
||||||
|
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||||
|
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||||
|
|
||||||
|
Under the following terms:
|
||||||
|
|
||||||
|
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||||
|
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||||
|
that suggests the licensor endorses you or your use.
|
||||||
|
|
||||||
|
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
||||||
|
your contributions under the same license as the original.
|
||||||
|
|
||||||
|
No additional restrictions — You may not apply legal terms or technological measures that
|
||||||
|
legally restrict others from doing anything the license permits.
|
||||||
|
|
||||||
|
Notices:
|
||||||
|
|
||||||
|
You do not have to comply with the license for elements of the material in the public
|
||||||
|
domain or where your use is permitted by an applicable exception or limitation.
|
||||||
|
No warranties are given. The license may not give you all of the permissions necessary
|
||||||
|
for your intended use. For example, other rights such as publicity, privacy, or moral
|
||||||
|
rights may limit how you use the material.
|
||||||
|
|
||||||
|
For more details:
|
||||||
|
http://creativecommons.org/licenses/by-sa/3.0/
|
||||||
|
|
||||||
|
|
170
control.lua
Executable file
|
@ -0,0 +1,170 @@
|
||||||
|
--global constants
|
||||||
|
|
||||||
|
ap_airship.vector_up = vector.new(0, 1, 0)
|
||||||
|
|
||||||
|
function ap_airship.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 ap_airship.powerAdjust(self,dtime,factor,dir,max_power)
|
||||||
|
local max = max_power or 100
|
||||||
|
local add_factor = factor/2
|
||||||
|
add_factor = add_factor * (dtime/ap_airship.ideal_step) --adjusting the command speed by dtime
|
||||||
|
local power_index = self._power_lever
|
||||||
|
|
||||||
|
if dir == 1 then
|
||||||
|
if self._power_lever < max then
|
||||||
|
self._power_lever = self._power_lever + add_factor
|
||||||
|
end
|
||||||
|
if self._power_lever > max then
|
||||||
|
self._power_lever = max
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if dir == -1 then
|
||||||
|
self._power_lever = self._power_lever - add_factor
|
||||||
|
if self._power_lever < -15 then self._power_lever = -15 end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.control(self, dtime, hull_direction, longit_speed, accel)
|
||||||
|
if self._last_time_command == nil then self._last_time_command = 0 end
|
||||||
|
self._last_time_command = self._last_time_command + dtime
|
||||||
|
if self._last_time_command > 1 then self._last_time_command = 1 end
|
||||||
|
local player = nil
|
||||||
|
if self.driver_name then
|
||||||
|
player = minetest.get_player_by_name(self.driver_name)
|
||||||
|
end
|
||||||
|
local retval_accel = accel;
|
||||||
|
|
||||||
|
-- player control
|
||||||
|
local ctrl = nil
|
||||||
|
if player and self._at_control == true then
|
||||||
|
ctrl = player:get_player_control()
|
||||||
|
local max_speed_anchor = 0.2
|
||||||
|
|
||||||
|
if self.anchored == false then
|
||||||
|
local factor = 1
|
||||||
|
if ctrl.up then
|
||||||
|
local can_acc = true
|
||||||
|
if self._power_lever >= 82 then can_acc = false end
|
||||||
|
if ctrl.aux1 then can_acc = true end
|
||||||
|
if can_acc then
|
||||||
|
ap_airship.powerAdjust(self, dtime, factor, 1)
|
||||||
|
end
|
||||||
|
elseif ctrl.down then
|
||||||
|
ap_airship.powerAdjust(self, dtime, factor, -1)
|
||||||
|
else
|
||||||
|
--self.object:set_animation_frame_speed(ap_airship.iddle_rotation)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
--anchor away, so stop!
|
||||||
|
self._power_lever = 0
|
||||||
|
end
|
||||||
|
if not ctrl.aux1 and self._power_lever < 0 then self._power_lever = 0 end
|
||||||
|
|
||||||
|
--control lift
|
||||||
|
self._is_going_up = false
|
||||||
|
local work_speed = math.abs(longit_speed)
|
||||||
|
if ap_airship.max_speed < work_speed then work_speed = ap_airship.max_speed end --limit the range
|
||||||
|
local normal_lift = 0.15
|
||||||
|
local extra_lift = 0.15
|
||||||
|
local abs_baloon_buoyancy = normal_lift + ((work_speed*extra_lift)/ap_airship.max_speed)
|
||||||
|
if ctrl.jump then
|
||||||
|
--if self._boiler_pressure > 0 then
|
||||||
|
self._baloon_buoyancy = abs_baloon_buoyancy
|
||||||
|
--end
|
||||||
|
self._is_going_up = true
|
||||||
|
elseif ctrl.sneak then
|
||||||
|
self._baloon_buoyancy = -1*abs_baloon_buoyancy
|
||||||
|
end
|
||||||
|
--end lift
|
||||||
|
|
||||||
|
--check if is near the ground, so revert the flight mode
|
||||||
|
local noded = automobiles_lib.nodeatpos(airutils.pos_shift(self.object:get_pos(),{y=-4}))
|
||||||
|
if (noded and noded.drawtype ~= 'airlike') then
|
||||||
|
--avoid liquids
|
||||||
|
if noded.drawtype == 'liquid' then
|
||||||
|
--self._baloon_buoyancy = abs_baloon_buoyancy*2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- rudder
|
||||||
|
local rudder_limit = 30
|
||||||
|
local speed = 10
|
||||||
|
if ctrl.right then
|
||||||
|
self._rudder_angle = math.max(self._rudder_angle-speed*dtime,-rudder_limit)
|
||||||
|
elseif ctrl.left then
|
||||||
|
self._rudder_angle = math.min(self._rudder_angle+speed*dtime,rudder_limit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--engine acceleration calc
|
||||||
|
local engineacc = (self._power_lever * ap_airship.max_engine_acc) / 100;
|
||||||
|
|
||||||
|
--do not exceed
|
||||||
|
if longit_speed > ap_airship.max_speed then
|
||||||
|
engineacc = engineacc - (longit_speed-ap_airship.max_speed)
|
||||||
|
end
|
||||||
|
|
||||||
|
if engineacc ~= nil then
|
||||||
|
retval_accel=vector.add(accel,vector.multiply(hull_direction,engineacc))
|
||||||
|
end
|
||||||
|
--minetest.chat_send_all('paddle: '.. paddleacc)
|
||||||
|
|
||||||
|
|
||||||
|
if longit_speed > 0 then
|
||||||
|
if ctrl then
|
||||||
|
if ctrl.right or ctrl.left then
|
||||||
|
else
|
||||||
|
ap_airship.rudder_auto_correction(self, longit_speed, dtime)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ap_airship.rudder_auto_correction(self, longit_speed, dtime)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ap_airship.buoyancy_auto_correction(self, self.dtime)
|
||||||
|
|
||||||
|
return retval_accel
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.rudder_auto_correction(self, longit_speed, dtime)
|
||||||
|
local factor = 1
|
||||||
|
if self._rudder_angle > 0 then factor = -1 end
|
||||||
|
local correction = (ap_airship.rudder_limit*(longit_speed/2000)) * factor * (dtime/ap_airship.ideal_step)
|
||||||
|
local before_correction = self._rudder_angle
|
||||||
|
local new_rudder_angle = self._rudder_angle + correction
|
||||||
|
if math.sign(before_correction) ~= math.sign(new_rudder_angle) then
|
||||||
|
self._rudder_angle = 0
|
||||||
|
else
|
||||||
|
self._rudder_angle = new_rudder_angle
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.buoyancy_auto_correction(self, dtime)
|
||||||
|
local factor = 1
|
||||||
|
--minetest.chat_send_player(self.driver_name, "antes: " .. self._baloon_buoyancy)
|
||||||
|
if self._baloon_buoyancy > 0 then factor = -1 end
|
||||||
|
local time_correction = (dtime/ap_airship.ideal_step)
|
||||||
|
local intensity = 0.001
|
||||||
|
local correction = (intensity*factor) * time_correction
|
||||||
|
--minetest.chat_send_player(self.driver_name, correction)
|
||||||
|
local before_correction = self._baloon_buoyancy
|
||||||
|
local new_baloon_buoyancy = self._baloon_buoyancy + correction
|
||||||
|
if math.sign(before_correction) ~= math.sign(new_baloon_buoyancy) then
|
||||||
|
self._baloon_buoyancy = 0
|
||||||
|
else
|
||||||
|
self._baloon_buoyancy = new_baloon_buoyancy
|
||||||
|
end
|
||||||
|
--minetest.chat_send_player(self.driver_name, "depois: " .. self._baloon_buoyancy)
|
||||||
|
end
|
||||||
|
|
86
custom_physics.lua
Executable file
|
@ -0,0 +1,86 @@
|
||||||
|
local min = math.min
|
||||||
|
local abs = math.abs
|
||||||
|
|
||||||
|
function ap_airship.physics(self)
|
||||||
|
local friction = 0.996
|
||||||
|
local vel=self.object:get_velocity()
|
||||||
|
-- dumb friction
|
||||||
|
if self.isonground and not self.isinliquid then
|
||||||
|
--minetest.chat_send_all("with friction")
|
||||||
|
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
|
||||||
|
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
|
||||||
|
--minetest.chat_send_all("vnew")
|
||||||
|
self.object:set_velocity(vnew)
|
||||||
|
end
|
||||||
|
--[[else
|
||||||
|
self.object:set_pos(self.object:get_pos())
|
||||||
|
if not self.isonground then
|
||||||
|
--minetest.chat_send_all("test")
|
||||||
|
self.object:set_velocity(vel)
|
||||||
|
end
|
||||||
|
end]]--
|
||||||
|
|
||||||
|
--buoyancy
|
||||||
|
local surface = nil
|
||||||
|
local surfnodename = nil
|
||||||
|
local spos = airutils.get_stand_pos(self)
|
||||||
|
spos.y = spos.y+0.01
|
||||||
|
-- get surface height
|
||||||
|
local snodepos = airutils.get_node_pos(spos)
|
||||||
|
local surfnode = airutils.nodeatpos(spos)
|
||||||
|
while surfnode and (surfnode.drawtype == 'liquid' or surfnode.drawtype == 'flowingliquid') do
|
||||||
|
surfnodename = surfnode.name
|
||||||
|
surface = snodepos.y +0.5
|
||||||
|
if surface > spos.y+self.height then break end
|
||||||
|
snodepos.y = snodepos.y+1
|
||||||
|
surfnode = airutils.nodeatpos(snodepos)
|
||||||
|
end
|
||||||
|
|
||||||
|
local new_velocity = nil
|
||||||
|
|
||||||
|
local accell = {x=0, y=0, z=0}
|
||||||
|
self.water_drag = 0.1
|
||||||
|
self.object:move_to(self.object:get_pos())
|
||||||
|
local time_correction = (self.dtime/ap_airship.ideal_step)
|
||||||
|
local y_accel = self._baloon_buoyancy*time_correction
|
||||||
|
--minetest.chat_send_all(y_accel)
|
||||||
|
local max_y_acell = 0.3
|
||||||
|
if y_accel > max_y_acell then y_accel = max_y_acell end
|
||||||
|
if y_accel < (-1*max_y_acell) then y_accel = -1*max_y_acell end
|
||||||
|
|
||||||
|
|
||||||
|
self.isinliquid = false
|
||||||
|
if self._baloon_buoyancy == 0 then
|
||||||
|
local velocity = vector.new(vel)
|
||||||
|
velocity.y = velocity.y - (velocity.y/100)
|
||||||
|
self.object:set_velocity(velocity)
|
||||||
|
end
|
||||||
|
--minetest.chat_send_all("_baloon_buoyancy: "..self._baloon_buoyancy.." - dtime: "..self.dtime.." - ideal: "..ap_airship.ideal_step)
|
||||||
|
airutils.set_acceleration(self.object,{x=0,y=y_accel,z=0})
|
||||||
|
|
||||||
|
|
||||||
|
end
|
50
engine_management.lua
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
ap_airship.PRESSURE_CONSUMPTION = 500
|
||||||
|
|
||||||
|
local adjust_variable = 500
|
||||||
|
local lost_power = (1/ap_airship.FUEL_CONSUMPTION)*adjust_variable
|
||||||
|
local gained_pressure = (2/ap_airship.FUEL_CONSUMPTION)*adjust_variable
|
||||||
|
|
||||||
|
ap_airship.boiler_min = 1
|
||||||
|
ap_airship.boiler_max = 310
|
||||||
|
|
||||||
|
function ap_airship.start_engine(self)
|
||||||
|
-- sound
|
||||||
|
--minetest.chat_send_all(dump(self.sound_handle_engine))
|
||||||
|
if self.sound_handle_engine == nil and self._engine_running == true then
|
||||||
|
self.object:set_animation_frame_speed(ap_airship.iddle_rotation)
|
||||||
|
if self.object then
|
||||||
|
self.sound_handle_engine = minetest.sound_play({name = "ap_airship_engine"},--"default_item_smoke"},
|
||||||
|
{object = self.object, gain = 3.0,
|
||||||
|
pitch = 0.4,
|
||||||
|
max_hear_distance = 120,
|
||||||
|
loop = true,})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function engines_step(self, accel)
|
||||||
|
ap_airship.start_engine(self)
|
||||||
|
ap_airship.engine_set_sound_and_animation(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function furnace_step(self, accel)
|
||||||
|
if self._energy > 0 and self._engine_running then
|
||||||
|
local consumed_power = (1/ap_airship.FUEL_CONSUMPTION)
|
||||||
|
--self._energy = self._energy - consumed_power; --removes energy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.engine_step(self, accel)
|
||||||
|
furnace_step(self, accel)
|
||||||
|
engines_step(self, accel)
|
||||||
|
|
||||||
|
if self.driver_name then
|
||||||
|
local player = minetest.get_player_by_name(self.driver_name)
|
||||||
|
|
||||||
|
local pressure = 0
|
||||||
|
local coal = self._energy
|
||||||
|
--minetest.chat_send_all(self._power_lever)
|
||||||
|
ap_airship.update_hud(player, coal, 180, -pressure, self._power_lever)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
679
entities.lua
Executable file
|
@ -0,0 +1,679 @@
|
||||||
|
--
|
||||||
|
-- constants
|
||||||
|
--
|
||||||
|
local LONGIT_DRAG_FACTOR = 0.13*0.13
|
||||||
|
local LATER_DRAG_FACTOR = 2.0
|
||||||
|
|
||||||
|
local function right_click_function(self, clicker)
|
||||||
|
local message = ""
|
||||||
|
if not clicker or not clicker:is_player() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local name = clicker:get_player_name()
|
||||||
|
|
||||||
|
local touching_ground, liquid_below = airutils.check_node_below(self.object, 2.5)
|
||||||
|
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('passengers: '.. dump(self._passengers))
|
||||||
|
--=========================
|
||||||
|
-- form to pilot
|
||||||
|
--=========================
|
||||||
|
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
|
||||||
|
|
||||||
|
--check error after being shot for any other mod
|
||||||
|
if is_attached == false then
|
||||||
|
for i = ap_airship.max_seats,1,-1
|
||||||
|
do
|
||||||
|
if self._passengers[i] == name then
|
||||||
|
self._passengers[i] = nil --clear the wrong information
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--shows pilot formspec
|
||||||
|
if name ~= self.driver_name then
|
||||||
|
local pass_is_attached = ap_airship.check_passenger_is_attached(self, name)
|
||||||
|
|
||||||
|
if pass_is_attached then
|
||||||
|
local can_bypass = minetest.check_player_privs(clicker, {protection_bypass=true})
|
||||||
|
if clicker:get_player_control().aux1 == true then --lets see the inventory
|
||||||
|
local is_shared = false
|
||||||
|
if name == self.owner or can_bypass then is_shared = true end
|
||||||
|
for k, v in pairs(self._shared_owners) do
|
||||||
|
if v == name then
|
||||||
|
is_shared = trueright_click_function
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if is_shared then
|
||||||
|
airutils.show_vehicle_trunk_formspec(self, clicker, ap_airship.trunk_slots)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ap_airship.pax_formspec(name)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
--first lets clean the boat slots
|
||||||
|
--note that when it happens, the "rescue" function will lost the historic
|
||||||
|
for i = ap_airship.max_seats,1,-1
|
||||||
|
do
|
||||||
|
if self._passengers[i] ~= nil then
|
||||||
|
local old_player = minetest.get_player_by_name(self._passengers[i])
|
||||||
|
if not old_player then self._passengers[i] = nil end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--attach normal passenger
|
||||||
|
--if self._door_closed == false then
|
||||||
|
ap_airship.attach_pax(self, clicker)
|
||||||
|
--end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function right_click_controls(self, clicker)
|
||||||
|
local message = ""
|
||||||
|
if not clicker or not clicker:is_player() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local name = clicker:get_player_name()
|
||||||
|
local ship_self = nil
|
||||||
|
|
||||||
|
local is_attached = false
|
||||||
|
local seat = clicker:get_attach()
|
||||||
|
if seat then
|
||||||
|
ship_attach = seat:get_attach()
|
||||||
|
if ship_attach then
|
||||||
|
ship_self = ship_attach:get_luaentity()
|
||||||
|
is_attached = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if is_attached then
|
||||||
|
--minetest.chat_send_all('passengers: '.. dump(ship_self._passengers))
|
||||||
|
--=========================
|
||||||
|
-- form to pilot
|
||||||
|
--=========================
|
||||||
|
if ship_self.owner == "" then
|
||||||
|
ship_self.owner = name
|
||||||
|
end
|
||||||
|
|
||||||
|
if ship_self.driver_name ~= nil and ship_self.driver_name ~= "" then
|
||||||
|
--shows pilot formspec
|
||||||
|
if name == ship_self.driver_name then
|
||||||
|
ap_airship.pilot_formspec(name)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
--lets take the control by force
|
||||||
|
if name == ship_self.owner or can_bypass then
|
||||||
|
--require the pilot position now
|
||||||
|
ap_airship.owner_formspec(name)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
else
|
||||||
|
--check if is on owner list
|
||||||
|
local is_shared = false
|
||||||
|
if name == ship_self.owner or can_bypass then is_shared = true end
|
||||||
|
for k, v in pairs(ship_self._shared_owners) do
|
||||||
|
if v == name then
|
||||||
|
is_shared = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--normal user
|
||||||
|
if is_shared == false then
|
||||||
|
ap_airship.pax_formspec(name)
|
||||||
|
else
|
||||||
|
--owners
|
||||||
|
ap_airship.pilot_formspec(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function right_click_cabin(self, clicker)
|
||||||
|
local message = ""
|
||||||
|
if not clicker or not clicker:is_player() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local name = clicker:get_player_name()
|
||||||
|
local ship_self = nil
|
||||||
|
|
||||||
|
local is_attached = false
|
||||||
|
local seat = clicker:get_attach()
|
||||||
|
if seat then
|
||||||
|
ship_attach = seat:get_attach()
|
||||||
|
if ship_attach then
|
||||||
|
ship_self = ship_attach:get_luaentity()
|
||||||
|
is_attached = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if is_attached then
|
||||||
|
--shows pilot formspec
|
||||||
|
if name == ship_self.driver_name then
|
||||||
|
return
|
||||||
|
else
|
||||||
|
ap_airship.pax_formspec(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- entity
|
||||||
|
--
|
||||||
|
|
||||||
|
minetest.register_entity('ap_airship:control_interactor',{
|
||||||
|
initial_properties = {
|
||||||
|
physical = true,
|
||||||
|
collide_with_objects=true,
|
||||||
|
collisionbox = {-0.5, 0, -0.5, 0.5, 0.5, 0.5},
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "ap_airship_stand_base.b3d",
|
||||||
|
textures = {"ap_airship_alpha.png",},
|
||||||
|
},
|
||||||
|
dist_moved = 0,
|
||||||
|
|
||||||
|
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,
|
||||||
|
|
||||||
|
on_punch = function(self, puncher, ttime, toolcaps, dir, damage)
|
||||||
|
--minetest.chat_send_all("punch")
|
||||||
|
if not puncher or not puncher:is_player() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
on_rightclick = right_click_controls,
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_entity('ap_airship:cabin_interactor',{
|
||||||
|
initial_properties = {
|
||||||
|
physical = true,
|
||||||
|
collide_with_objects=true,
|
||||||
|
collisionbox = {-0.5, 0, -0.5, 0.5, 5, 0.5},
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "ap_airship_stand_base.b3d",
|
||||||
|
textures = {"ap_airship_alpha.png",},
|
||||||
|
},
|
||||||
|
dist_moved = 0,
|
||||||
|
|
||||||
|
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,
|
||||||
|
|
||||||
|
on_punch = function(self, puncher, ttime, toolcaps, dir, damage)
|
||||||
|
--minetest.chat_send_all("punch")
|
||||||
|
if not puncher or not puncher:is_player() then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
on_rightclick = right_click_cabin,
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
--
|
||||||
|
-- seat pivot
|
||||||
|
--
|
||||||
|
minetest.register_entity('ap_airship:stand_base',{
|
||||||
|
initial_properties = {
|
||||||
|
physical = true,
|
||||||
|
collide_with_objects=true,
|
||||||
|
collisionbox = {-2, -2, -2, 2, 0, 2},
|
||||||
|
pointable=false,
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "ap_airship_stand_base.b3d",
|
||||||
|
textures = {"ap_airship_alpha.png",},
|
||||||
|
},
|
||||||
|
dist_moved = 0,
|
||||||
|
|
||||||
|
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("ap_airship:airship", {
|
||||||
|
initial_properties = {
|
||||||
|
physical = true,
|
||||||
|
collide_with_objects = true, --true,
|
||||||
|
collisionbox = {-10, -3.5, -10, 10, 15, 10}, --{-1,0,-1, 1,0.3,1},
|
||||||
|
--selectionbox = {-0.6,0.6,-0.6, 0.6,1,0.6},
|
||||||
|
visual = "mesh",
|
||||||
|
backface_culling = false,
|
||||||
|
mesh = "ap_airship_mesh.b3d",
|
||||||
|
textures = ap_airship.textures_copy(),
|
||||||
|
},
|
||||||
|
textures = {},
|
||||||
|
driver_name = nil,
|
||||||
|
sound_handle = nil,
|
||||||
|
static_save = true,
|
||||||
|
infotext = "A nice airship",
|
||||||
|
lastvelocity = vector.new(),
|
||||||
|
hp = 50,
|
||||||
|
color = "blue",
|
||||||
|
color2 = "white",
|
||||||
|
logo = "ap_airship_alpha_logo.png",
|
||||||
|
timeout = 0;
|
||||||
|
buoyancy = 0.15,
|
||||||
|
max_hp = 50,
|
||||||
|
anchored = false,
|
||||||
|
physics = ap_airship.physics,
|
||||||
|
hull_integrity = nil,
|
||||||
|
owner = "",
|
||||||
|
_shared_owners = {},
|
||||||
|
_engine_running = false,
|
||||||
|
_power_lever = 0,
|
||||||
|
_last_applied_power = 0,
|
||||||
|
_at_control = false,
|
||||||
|
_rudder_angle = 0,
|
||||||
|
_baloon_buoyancy = 0,
|
||||||
|
_show_hud = true,
|
||||||
|
_energy = 1.0,--0.001,
|
||||||
|
_boiler_pressure = 1.0, --min 155 max 310
|
||||||
|
_is_going_up = false, --to tell the boiler to lose pressure
|
||||||
|
_passengers = {}, --passengers list
|
||||||
|
_passengers_base = {}, --obj id
|
||||||
|
_passengers_base_pos = ap_airship.copy_vector({}),
|
||||||
|
_passengers_locked = false,
|
||||||
|
_disconnection_check_time = 0,
|
||||||
|
_inv = nil,
|
||||||
|
_inv_id = "",
|
||||||
|
item = "ap_airship:airship",
|
||||||
|
|
||||||
|
get_staticdata = function(self) -- unloaded/unloads ... is now saved
|
||||||
|
return minetest.serialize({
|
||||||
|
stored_baloon_buoyancy = self._baloon_buoyancy,
|
||||||
|
stored_energy = self._energy,
|
||||||
|
stored_owner = self.owner,
|
||||||
|
stored_shared_owners = self._shared_owners,
|
||||||
|
stored_hp = self.hp,
|
||||||
|
stored_color = self.color,
|
||||||
|
stored_color2 = self.color2,
|
||||||
|
stored_logo = self.logo,
|
||||||
|
stored_anchor = self.anchored,
|
||||||
|
stored_hull_integrity = self.hull_integrity,
|
||||||
|
stored_item = self.item,
|
||||||
|
stored_inv_id = self._inv_id,
|
||||||
|
stored_passengers = self._passengers, --passengers list
|
||||||
|
stored_passengers_locked = self._passengers_locked,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
|
||||||
|
on_deactivate = function(self)
|
||||||
|
airutils.save_inventory(self)
|
||||||
|
if self.sound_handle then minetest.sound_stop(self.sound_handle) end
|
||||||
|
if self.sound_handle_engine then minetest.sound_stop(self.sound_handle_engine) end
|
||||||
|
end,
|
||||||
|
|
||||||
|
on_activate = function(self, staticdata, dtime_s)
|
||||||
|
--minetest.chat_send_all('passengers: '.. dump(self._passengers))
|
||||||
|
if staticdata ~= "" and staticdata ~= nil then
|
||||||
|
local data = minetest.deserialize(staticdata) or {}
|
||||||
|
|
||||||
|
self._baloon_buoyancy = data.stored_baloon_buoyancy or 0
|
||||||
|
self._energy = data.stored_energy or 0
|
||||||
|
self.owner = data.stored_owner or ""
|
||||||
|
self._shared_owners = data.stored_shared_owners or {}
|
||||||
|
self.hp = data.stored_hp or 50
|
||||||
|
self.color = data.stored_color or "blue"
|
||||||
|
self.color2 = data.stored_color2 or "white"
|
||||||
|
self.logo = data.stored_logo or "ap_airship_alpha_logo.png"
|
||||||
|
self.anchored = data.stored_anchor or false
|
||||||
|
self.buoyancy = data.stored_buoyancy or 0.15
|
||||||
|
self.hull_integrity = data.stored_hull_integrity
|
||||||
|
self.item = data.stored_item
|
||||||
|
self._inv_id = data.stored_inv_id
|
||||||
|
self._passengers = data.stored_passengers or ap_airship.copy_vector({[1]=nil, [2]=nil, [3]=nil, [4]=nil, [5]=nil,})
|
||||||
|
self._passengers_locked = data.stored_passengers_locked
|
||||||
|
--minetest.debug("loaded: ", self._energy)
|
||||||
|
local properties = self.object:get_properties()
|
||||||
|
properties.infotext = data.stored_owner .. " nice airship"
|
||||||
|
self.object:set_properties(properties)
|
||||||
|
end
|
||||||
|
|
||||||
|
local colstr = ap_airship.colors[self.color]
|
||||||
|
if not colstr then
|
||||||
|
colstr = "blue"
|
||||||
|
self.color = colstr
|
||||||
|
end
|
||||||
|
ap_airship.paint(self, self.color)
|
||||||
|
ap_airship.paint2(self, self.color2)
|
||||||
|
local pos = self.object:get_pos()
|
||||||
|
|
||||||
|
self._passengers_base = ap_airship.copy_vector({[1]=nil, [2]=nil, [3]=nil, [4]=nil, [5]=nil,})
|
||||||
|
self._passengers_base_pos = ap_airship.copy_vector({[1]=nil, [2]=nil, [3]=nil, [4]=nil, [5]=nil,})
|
||||||
|
self._passengers_base_pos = {
|
||||||
|
[1]=ap_airship.copy_vector(ap_airship.passenger_pos[1]),
|
||||||
|
[2]=ap_airship.copy_vector(ap_airship.passenger_pos[2]),
|
||||||
|
[3]=ap_airship.copy_vector(ap_airship.passenger_pos[3]),
|
||||||
|
[4]=ap_airship.copy_vector(ap_airship.passenger_pos[4]),
|
||||||
|
[5]=ap_airship.copy_vector(ap_airship.passenger_pos[5]),} --curr pos
|
||||||
|
--self._passengers = {[1]=nil, [2]=nil, [3]=nil, [4]=nil, [5]=nil,} --passenger names
|
||||||
|
|
||||||
|
self._passengers_base[1]=minetest.add_entity(pos,'ap_airship:stand_base')
|
||||||
|
self._passengers_base[1]:set_attach(self.object,'',self._passengers_base_pos[1],{x=0,y=0,z=0})
|
||||||
|
|
||||||
|
self._passengers_base[2]=minetest.add_entity(pos,'ap_airship:stand_base')
|
||||||
|
self._passengers_base[2]:set_attach(self.object,'',self._passengers_base_pos[2],{x=0,y=0,z=0})
|
||||||
|
|
||||||
|
self._passengers_base[3]=minetest.add_entity(pos,'ap_airship:stand_base')
|
||||||
|
self._passengers_base[3]:set_attach(self.object,'',self._passengers_base_pos[3],{x=0,y=0,z=0})
|
||||||
|
|
||||||
|
self._passengers_base[4]=minetest.add_entity(pos,'ap_airship:stand_base')
|
||||||
|
self._passengers_base[4]:set_attach(self.object,'',self._passengers_base_pos[4],{x=0,y=0,z=0})
|
||||||
|
|
||||||
|
self._passengers_base[5]=minetest.add_entity(pos,'ap_airship:stand_base')
|
||||||
|
self._passengers_base[5]:set_attach(self.object,'',self._passengers_base_pos[5],{x=0,y=0,z=0})
|
||||||
|
|
||||||
|
self._control_interactor=minetest.add_entity(pos,'ap_airship:control_interactor')
|
||||||
|
self._control_interactor:set_attach(self.object,'',{x=0,y=-28,z=175},{x=0,y=0,z=0})
|
||||||
|
self._cabin_interactor=minetest.add_entity(pos,'ap_airship:cabin_interactor')
|
||||||
|
self._cabin_interactor:set_attach(self.object,'',{x=-6,y=-28,z=115},{x=0,y=0,z=0})
|
||||||
|
|
||||||
|
--animation load - stoped
|
||||||
|
self.object:set_animation({x = 1, y = 47}, 0, 0, true)
|
||||||
|
|
||||||
|
self.object:set_bone_position("low_rudder_a", {x=0,y=0,z=-40}, {x=-5.35,y=0,z=0})
|
||||||
|
|
||||||
|
self.object:set_armor_groups({immortal=1})
|
||||||
|
|
||||||
|
airutils.actfunc(self, staticdata, dtime_s)
|
||||||
|
|
||||||
|
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, ap_airship.trunk_slots)
|
||||||
|
else
|
||||||
|
self.inv = inv
|
||||||
|
end
|
||||||
|
|
||||||
|
ap_airship.engine_step(self, 0)
|
||||||
|
end,
|
||||||
|
|
||||||
|
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 = function(self)
|
||||||
|
|
||||||
|
local accel_y = self.object:get_acceleration().y
|
||||||
|
local rotation = self.object:get_rotation()
|
||||||
|
local yaw = rotation.y
|
||||||
|
local newyaw=yaw
|
||||||
|
local pitch = rotation.x
|
||||||
|
local newpitch = pitch
|
||||||
|
local roll = rotation.z
|
||||||
|
|
||||||
|
local hull_direction = minetest.yaw_to_dir(yaw)
|
||||||
|
local nhdir = {x=hull_direction.z,y=0,z=-hull_direction.x} -- lateral unit vector
|
||||||
|
local velocity = self.object:get_velocity()
|
||||||
|
|
||||||
|
local longit_speed = ap_airship.dot(velocity,hull_direction)
|
||||||
|
self._longit_speed = longit_speed --for anchor verify
|
||||||
|
local longit_drag = vector.multiply(hull_direction,longit_speed*
|
||||||
|
longit_speed*LONGIT_DRAG_FACTOR*-1*ap_airship.sign(longit_speed))
|
||||||
|
local later_speed = ap_airship.dot(velocity,nhdir)
|
||||||
|
local later_drag = vector.multiply(nhdir,later_speed*later_speed*
|
||||||
|
LATER_DRAG_FACTOR*-1*ap_airship.sign(later_speed))
|
||||||
|
local accel = vector.add(longit_drag,later_drag)
|
||||||
|
|
||||||
|
local vel = self.object:get_velocity()
|
||||||
|
local curr_pos = self.object:get_pos()
|
||||||
|
self._last_pos = curr_pos
|
||||||
|
self.object:move_to(curr_pos)
|
||||||
|
|
||||||
|
--minetest.chat_send_all(self._energy)
|
||||||
|
--local node_bellow = airutils.nodeatpos(airutils.pos_shift(curr_pos,{y=-2.8}))
|
||||||
|
--[[local is_flying = true
|
||||||
|
if node_bellow and node_bellow.drawtype ~= 'airlike' then is_flying = false end]]--
|
||||||
|
|
||||||
|
local is_attached = false
|
||||||
|
local player = nil
|
||||||
|
if self.driver_name then
|
||||||
|
player = minetest.get_player_by_name(self.driver_name)
|
||||||
|
|
||||||
|
if player then
|
||||||
|
is_attached = ap_airship.checkAttach(self, player)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.owner == "" then return end
|
||||||
|
--[[if longit_speed == 0 and is_flying == false and is_attached == false and self._engine_running == false then
|
||||||
|
self.object:move_to(curr_pos)
|
||||||
|
--self.object:set_acceleration({x=0,y=airutils.gravity,z=0})
|
||||||
|
return
|
||||||
|
end]]--
|
||||||
|
|
||||||
|
--detect collision
|
||||||
|
ap_airship.testDamage(self, vel, curr_pos)
|
||||||
|
|
||||||
|
accel = ap_airship.control(self, self.dtime, hull_direction, longit_speed, accel) or vel
|
||||||
|
|
||||||
|
--get disconnected players
|
||||||
|
ap_airship.rescueConnectionFailedPassengers(self)
|
||||||
|
|
||||||
|
local turn_rate = math.rad(9)
|
||||||
|
newyaw = yaw + self.dtime*(1 - 1 / (math.abs(longit_speed) + 1)) *
|
||||||
|
self._rudder_angle / 30 * turn_rate * ap_airship.sign(longit_speed)
|
||||||
|
|
||||||
|
ap_airship.engine_step(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 = ap_airship.dot(snormal,nhdir)
|
||||||
|
local rollfactor = -15
|
||||||
|
local newroll = 0
|
||||||
|
if self._last_roll ~= nil then newroll = self._last_roll end
|
||||||
|
--oscilation when stoped
|
||||||
|
if longit_speed == 0 then
|
||||||
|
local time_correction = (self.dtime/ap_airship.ideal_step)
|
||||||
|
--stoped
|
||||||
|
if self._roll_state == nil then
|
||||||
|
self._roll_state = math.floor(math.random(-1,1))
|
||||||
|
if self._roll_state == 0 then self._roll_state = 1 end
|
||||||
|
self._last_roll = newroll
|
||||||
|
end
|
||||||
|
if math.deg(newroll) >= 1 and self._roll_state == 1 then
|
||||||
|
self._roll_state = -1
|
||||||
|
end
|
||||||
|
if math.deg(newroll) <= -1 and self._roll_state == -1 then
|
||||||
|
self._roll_state = 1
|
||||||
|
end
|
||||||
|
local roll_factor = (self._roll_state * 0.005) * time_correction
|
||||||
|
self._last_roll = self._last_roll + math.rad(roll_factor)
|
||||||
|
else
|
||||||
|
--in movement
|
||||||
|
self._roll_state = nil
|
||||||
|
newroll = (prsr*math.rad(rollfactor))*later_speed
|
||||||
|
self._last_roll = newroll
|
||||||
|
end
|
||||||
|
--minetest.chat_send_all('newroll: '.. newroll)
|
||||||
|
---------------------------------
|
||||||
|
-- end roll
|
||||||
|
local wind = airutils.get_wind(curr_pos, 0.3)
|
||||||
|
local wind_yaw = minetest.dir_to_yaw(wind)
|
||||||
|
--minetest.chat_send_all("x: "..wind.x.. " - z: "..wind.z.." - yaw: "..math.deg(wind_yaw).. " - orig: "..wind_yaw)
|
||||||
|
|
||||||
|
if self.anchored == false then
|
||||||
|
accel = vector.add(accel, wind)
|
||||||
|
else
|
||||||
|
accel = vector.new()
|
||||||
|
end
|
||||||
|
accel.y = accel_y
|
||||||
|
|
||||||
|
newpitch = velocity.y * math.rad(1.5) * (longit_speed/3)
|
||||||
|
self.object:set_acceleration(accel)
|
||||||
|
self.object:set_rotation({x=newpitch,y=newyaw,z=newroll})
|
||||||
|
|
||||||
|
local N_angle = math.deg(newyaw)
|
||||||
|
local S_angle = N_angle + 180
|
||||||
|
|
||||||
|
self.object:set_bone_position("elevator", {x=0,y=60.5919,z=-284.79}, {x=0,y=newpitch,z=0})
|
||||||
|
self.object:set_bone_position("rudder", {x=0,y=60.5919,z=-284.79}, {x=0,y=self._rudder_angle-180,z=0})
|
||||||
|
self.object:set_bone_position("timao", {x=0,y=-22.562,z=176.018}, {x=0,y=0,z=self._rudder_angle*8})
|
||||||
|
self.object:set_bone_position("compass_axis", {x=0,y=-21.8,z=178.757}, {x=0, y=S_angle, z=0})
|
||||||
|
|
||||||
|
--saves last velocy for collision detection (abrupt stop)
|
||||||
|
self._last_vel = self.object:get_velocity()
|
||||||
|
self._last_accell = accel
|
||||||
|
|
||||||
|
ap_airship.move_persons(self)
|
||||||
|
end,
|
||||||
|
|
||||||
|
on_punch = function(self, puncher, ttime, toolcaps, dir, damage)
|
||||||
|
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 = ap_airship.checkAttach(self, puncher)
|
||||||
|
|
||||||
|
local itmstck=puncher:get_wielded_item()
|
||||||
|
local item_name = ""
|
||||||
|
if itmstck then item_name = itmstck:get_name() end
|
||||||
|
|
||||||
|
if is_attached == true then
|
||||||
|
--refuel
|
||||||
|
ap_airship.load_fuel(self, puncher)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- deal with painting or destroying
|
||||||
|
if itmstck then
|
||||||
|
local _,indx = item_name:find('dye:')
|
||||||
|
if indx then
|
||||||
|
|
||||||
|
--lets paint!!!!
|
||||||
|
local color = item_name:sub(indx+1)
|
||||||
|
local colstr = ap_airship.colors[color]
|
||||||
|
--minetest.chat_send_all(color ..' '.. dump(colstr))
|
||||||
|
if colstr and (name == self.owner or minetest.check_player_privs(puncher, {protection_bypass=true})) then
|
||||||
|
local ctrl = puncher:get_player_control()
|
||||||
|
if ctrl.aux1 then
|
||||||
|
ap_airship.paint2(self, colstr)
|
||||||
|
else
|
||||||
|
ap_airship.paint(self, colstr)
|
||||||
|
end
|
||||||
|
itmstck:set_count(itmstck:get_count()-1)
|
||||||
|
puncher:set_wielded_item(itmstck)
|
||||||
|
end
|
||||||
|
-- end painting
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if is_attached == false then
|
||||||
|
local i = 0
|
||||||
|
local has_passengers = false
|
||||||
|
for i = ap_airship.max_seats,1,-1
|
||||||
|
do
|
||||||
|
if self._passengers[i] ~= nil then
|
||||||
|
has_passengers = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if not has_passengers and toolcaps and toolcaps.damage_groups and
|
||||||
|
toolcaps.groupcaps and toolcaps.groupcaps.choppy then
|
||||||
|
|
||||||
|
local is_empty = true --[[false
|
||||||
|
local inventory = airutils.get_inventory(self)
|
||||||
|
if inventory then
|
||||||
|
if inventory:is_empty("main") then is_empty = true end
|
||||||
|
end]]--
|
||||||
|
|
||||||
|
--airutils.make_sound(self,'hit')
|
||||||
|
if is_empty == true then
|
||||||
|
self.hp = self.hp - 10
|
||||||
|
minetest.sound_play("ap_airship_collision", {
|
||||||
|
object = self.object,
|
||||||
|
max_hear_distance = 5,
|
||||||
|
gain = 1.0,
|
||||||
|
fade = 0.0,
|
||||||
|
pitch = 1.0,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.hp <= 0 then
|
||||||
|
ap_airship.destroy(self, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end,
|
||||||
|
|
||||||
|
on_rightclick = right_click_function,
|
||||||
|
})
|
467
forms.lua
Executable file
|
@ -0,0 +1,467 @@
|
||||||
|
|
||||||
|
--------------
|
||||||
|
-- Manual --
|
||||||
|
--------------
|
||||||
|
|
||||||
|
function ap_airship.getPlaneFromPlayer(player)
|
||||||
|
local seat = player:get_attach()
|
||||||
|
if seat then
|
||||||
|
local plane = seat:get_attach()
|
||||||
|
return plane
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.pilot_formspec(name)
|
||||||
|
local basic_form = table.concat({
|
||||||
|
"formspec_version[5]",
|
||||||
|
"size[6,9]",
|
||||||
|
}, "")
|
||||||
|
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
local plane_obj = ap_airship.getPlaneFromPlayer(player)
|
||||||
|
if plane_obj == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local ent = plane_obj:get_luaentity()
|
||||||
|
|
||||||
|
local take_control = "false"
|
||||||
|
if ent._at_control then take_control = "true" end
|
||||||
|
local anchor = "false"
|
||||||
|
if ent.anchored == true then anchor = "true" end
|
||||||
|
|
||||||
|
basic_form = basic_form.."button[1,1.0;4,1;turn_on;Start/Stop the fire]"
|
||||||
|
basic_form = basic_form.."button[1,3.0;4,1;inventory;Open inventory]"
|
||||||
|
basic_form = basic_form.."button[1,4.0;4,1;manual;Show Manual Menu]"
|
||||||
|
|
||||||
|
basic_form = basic_form.."checkbox[1,5.6;take_control;Take the Control;"..take_control.."]"
|
||||||
|
basic_form = basic_form.."checkbox[1,6.2;anchor;Anchor away;"..anchor.."]"
|
||||||
|
|
||||||
|
basic_form = basic_form.."label[1,7.0;Disembark:]"
|
||||||
|
basic_form = basic_form.."button[1,7.2;2,1;disembark_l;<< Left]"
|
||||||
|
basic_form = basic_form.."button[3,7.2;2,1;disembark_r;Right >>]"
|
||||||
|
|
||||||
|
minetest.show_formspec(name, "ap_airship:pilot_main", basic_form)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.pax_formspec(name)
|
||||||
|
local basic_form = table.concat({
|
||||||
|
"formspec_version[3]",
|
||||||
|
"size[6,3]",
|
||||||
|
}, "")
|
||||||
|
|
||||||
|
basic_form = basic_form.."label[1,1.0;Disembark:]"
|
||||||
|
basic_form = basic_form.."button[1,1.2;2,1;disembark_l;<< Left]"
|
||||||
|
basic_form = basic_form.."button[3,1.2;2,1;disembark_r;Right >>]"
|
||||||
|
|
||||||
|
minetest.show_formspec(name, "ap_airship:passenger_main", basic_form)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.logo_formspec(name)
|
||||||
|
local basic_form = table.concat({
|
||||||
|
"formspec_version[3]",
|
||||||
|
"size[6,4]",
|
||||||
|
}, "")
|
||||||
|
|
||||||
|
local logos = {"airship_clover.png","airship_liz.png","airship_shotting_star.png","airship_skull.png", "airship_jack.png",}
|
||||||
|
local logolist = ""
|
||||||
|
for k, v in pairs(logos) do
|
||||||
|
logolist = logolist .. v .. ","
|
||||||
|
end
|
||||||
|
|
||||||
|
basic_form = basic_form.."label[1,1.0;Select a logo:]"
|
||||||
|
basic_form = basic_form.."dropdown[1,1.2;4,0.6;logo;"..logolist..";0;false]"
|
||||||
|
basic_form = basic_form.."button[1,2.2;4,0.8;set_logo;Set Airship Logo]"
|
||||||
|
|
||||||
|
minetest.show_formspec(name, "ap_airship:logo_main", basic_form)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.owner_formspec(name)
|
||||||
|
local basic_form = table.concat({
|
||||||
|
"formspec_version[3]",
|
||||||
|
"size[6,4.2]",
|
||||||
|
}, "")
|
||||||
|
|
||||||
|
basic_form = basic_form.."button[1,1.0;4,1;take;Take the Control Now]"
|
||||||
|
basic_form = basic_form.."label[1,2.2;Disembark:]"
|
||||||
|
basic_form = basic_form.."button[1,2.4;2,1;disembark_l;<< Left]"
|
||||||
|
basic_form = basic_form.."button[3,2.4;2,1;disembark_r;Right >>]"
|
||||||
|
|
||||||
|
minetest.show_formspec(name, "ap_airship:owner_main", basic_form)
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
if formname == "ap_airship:owner_main" then
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local plane_obj = ap_airship.getPlaneFromPlayer(player)
|
||||||
|
if plane_obj == nil then
|
||||||
|
minetest.close_formspec(name, "ap_airship:owner_main")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local ent = plane_obj:get_luaentity()
|
||||||
|
if ent then
|
||||||
|
if fields.disembark_l then
|
||||||
|
ap_airship.dettach_pax(ent, player, "l")
|
||||||
|
end
|
||||||
|
if fields.disembark_r then
|
||||||
|
ap_airship.dettach_pax(ent, player, "r")
|
||||||
|
end
|
||||||
|
if fields.take then
|
||||||
|
ent._at_control = true
|
||||||
|
for i = 5,1,-1
|
||||||
|
do
|
||||||
|
if ent._passengers[i] == name then
|
||||||
|
ent._passengers_base_pos[i] = vector.new(ap_airship.pilot_base_pos)
|
||||||
|
ent._passengers_base[i]:set_attach(ent.object,'',ap_airship.pilot_base_pos,{x=0,y=0,z=0})
|
||||||
|
player:set_attach(ent._passengers_base[i], "", {x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
||||||
|
end
|
||||||
|
if ent._passengers[i] == ent.driver_name then
|
||||||
|
ent._passengers_base_pos[i] = vector.new(ap_airship.passenger_pos[i])
|
||||||
|
ent._passengers_base[i]:set_attach(ent.object,'',ent._passengers_base_pos[i],{x=0,y=0,z=0})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ent.driver_name = name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
minetest.close_formspec(name, "ap_airship:owner_main")
|
||||||
|
end
|
||||||
|
if formname == "ap_airship:passenger_main" then
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local plane_obj = ap_airship.getPlaneFromPlayer(player)
|
||||||
|
if plane_obj == nil then
|
||||||
|
minetest.close_formspec(name, "ap_airship:passenger_main")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local ent = plane_obj:get_luaentity()
|
||||||
|
if ent then
|
||||||
|
if fields.disembark_l then
|
||||||
|
ap_airship.dettach_pax(ent, player, "l")
|
||||||
|
end
|
||||||
|
if fields.disembark_r then
|
||||||
|
ap_airship.dettach_pax(ent, player, "r")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
minetest.close_formspec(name, "ap_airship:passenger_main")
|
||||||
|
end
|
||||||
|
if formname == "ap_airship:logo_main" then
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local plane_obj = ap_airship.getPlaneFromPlayer(player)
|
||||||
|
if plane_obj == nil then
|
||||||
|
minetest.close_formspec(name, "ap_airship:logo_main")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local ent = plane_obj:get_luaentity()
|
||||||
|
if ent then
|
||||||
|
if fields.logo or fields.set_logo then
|
||||||
|
ap_airship.set_logo(ent, fields.logo)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
minetest.close_formspec(name, "ap_airship:logo_main")
|
||||||
|
end
|
||||||
|
if formname == "ap_airship:pilot_main" then
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local plane_obj = ap_airship.getPlaneFromPlayer(player)
|
||||||
|
if plane_obj == nil then
|
||||||
|
minetest.close_formspec(name, "ap_airship:pilot_main")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local ent = plane_obj:get_luaentity()
|
||||||
|
if ent then
|
||||||
|
if fields.turn_on then
|
||||||
|
ap_airship.start_furnace(ent)
|
||||||
|
end
|
||||||
|
if fields.inventory then
|
||||||
|
airutils.show_vehicle_trunk_formspec(ent, player, ap_airship.trunk_slots)
|
||||||
|
end
|
||||||
|
if fields.manual then
|
||||||
|
ap_airship.manual_formspec(name)
|
||||||
|
end
|
||||||
|
if fields.take_control then
|
||||||
|
if fields.take_control == "true" then
|
||||||
|
if ent.driver_name == nil or ent.driver_name == "" then
|
||||||
|
ent._at_control = true
|
||||||
|
for i = 5,1,-1
|
||||||
|
do
|
||||||
|
if ent._passengers[i] == name then
|
||||||
|
ent._passengers_base_pos[i] = vector.new(ap_airship.pilot_base_pos)
|
||||||
|
ent._passengers_base[i]:set_attach(ent.object,'',ap_airship.pilot_base_pos,{x=0,y=0,z=0})
|
||||||
|
player:set_attach(ent._passengers_base[i], "", {x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
||||||
|
ent.driver_name = name
|
||||||
|
--minetest.chat_send_all(">>"..ent.driver_name)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> Impossible. Someone is at the airship control now."))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ent.driver_name = nil
|
||||||
|
ent._at_control = false
|
||||||
|
ap_airship.remove_hud(player)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if fields.disembark_l then
|
||||||
|
--=========================
|
||||||
|
-- dettach player
|
||||||
|
--=========================
|
||||||
|
-- eject passenger if the plane is on ground
|
||||||
|
ent.driver_name = nil
|
||||||
|
ent._at_control = false
|
||||||
|
|
||||||
|
ap_airship.dettach_pax(ent, player, "l")
|
||||||
|
|
||||||
|
end
|
||||||
|
if fields.disembark_r then
|
||||||
|
--=========================
|
||||||
|
-- dettach player
|
||||||
|
--=========================
|
||||||
|
-- eject passenger if the plane is on ground
|
||||||
|
ent.driver_name = nil
|
||||||
|
ent._at_control = false
|
||||||
|
|
||||||
|
ap_airship.dettach_pax(ent, player, "r")
|
||||||
|
|
||||||
|
end
|
||||||
|
if fields.bring then
|
||||||
|
|
||||||
|
end
|
||||||
|
if fields.anchor then
|
||||||
|
if fields.anchor == "true" then
|
||||||
|
local max_speed_anchor = 0.6
|
||||||
|
if ent._longit_speed then
|
||||||
|
if math.abs(ent._longit_speed) < max_speed_anchor then
|
||||||
|
|
||||||
|
ent.anchored = true
|
||||||
|
ent.object:set_acceleration(vector.new())
|
||||||
|
ent.object:set_velocity(vector.new())
|
||||||
|
if name then
|
||||||
|
minetest.chat_send_player(name,core.colorize('#00ff00', " >>> Anchor away!"))
|
||||||
|
end
|
||||||
|
--ent.buoyancy = 0.1
|
||||||
|
else
|
||||||
|
if name then
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> Too fast to set anchor!"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ent.anchored = false
|
||||||
|
if name then
|
||||||
|
minetest.chat_send_player(name,core.colorize('#00ff00', " >>> Weigh anchor!"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--ent._rudder_angle = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
minetest.close_formspec(name, "ap_airship:pilot_main")
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_chatcommand("airship_share", {
|
||||||
|
params = "name",
|
||||||
|
description = "Share ownewrship with your friends",
|
||||||
|
privs = {interact = true},
|
||||||
|
func = function(name, param)
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
local target_player = minetest.get_player_by_name(param)
|
||||||
|
local attached_to = player:get_attach()
|
||||||
|
|
||||||
|
if attached_to ~= nil and target_player ~= nil then
|
||||||
|
local seat = attached_to:get_attach()
|
||||||
|
if seat ~= nil then
|
||||||
|
local entity = seat:get_luaentity()
|
||||||
|
if entity then
|
||||||
|
if entity.name == "ap_airship:airship" then
|
||||||
|
if entity.owner == name then
|
||||||
|
local exists = false
|
||||||
|
for k, v in pairs(entity._shared_owners) do
|
||||||
|
if v == param then
|
||||||
|
exists = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if exists == false then
|
||||||
|
table.insert(entity._shared_owners, param)
|
||||||
|
minetest.chat_send_player(name,core.colorize('#00ff00', " >>> airship shared"))
|
||||||
|
--minetest.chat_send_all(dump(entity._shared_owners))
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> this user is already registered for airship share"))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> only the owner can share this airship"))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> you are not inside a airship to perform this command"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> you are not inside a airship to perform this command"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("airship_remove", {
|
||||||
|
params = "name",
|
||||||
|
description = "Removes ownewrship from someone",
|
||||||
|
privs = {interact = true},
|
||||||
|
func = function(name, param)
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
local attached_to = player:get_attach()
|
||||||
|
|
||||||
|
if attached_to ~= nil then
|
||||||
|
local seat = attached_to:get_attach()
|
||||||
|
if seat ~= nil then
|
||||||
|
local entity = seat:get_luaentity()
|
||||||
|
if entity then
|
||||||
|
if entity.name == "ap_airship:airship" then
|
||||||
|
if entity.owner == name then
|
||||||
|
for k, v in pairs(entity._shared_owners) do
|
||||||
|
if v == param then
|
||||||
|
table.remove(entity._shared_owners,k)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
minetest.chat_send_player(name,core.colorize('#00ff00', " >>> user removed"))
|
||||||
|
--minetest.chat_send_all(dump(entity._shared_owners))
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> only the owner can do this action"))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> you are not inside a airship to perform this command"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> you are not inside a airship to perform this command"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("airship_list", {
|
||||||
|
params = "",
|
||||||
|
description = "Lists the airship shared owners",
|
||||||
|
privs = {interact = true},
|
||||||
|
func = function(name, param)
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
local attached_to = player:get_attach()
|
||||||
|
|
||||||
|
if attached_to ~= nil then
|
||||||
|
local seat = attached_to:get_attach()
|
||||||
|
if seat ~= nil then
|
||||||
|
local entity = seat:get_luaentity()
|
||||||
|
if entity then
|
||||||
|
if entity.name == "ap_airship:airship" then
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ffff00', " >>> Current owners are:"))
|
||||||
|
minetest.chat_send_player(name,core.colorize('#0000ff', entity.owner))
|
||||||
|
for k, v in pairs(entity._shared_owners) do
|
||||||
|
minetest.chat_send_player(name,core.colorize('#00ff00', v))
|
||||||
|
end
|
||||||
|
--minetest.chat_send_all(dump(entity._shared_owners))
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> you are not inside a airship to perform this command"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> you are not inside a airship to perform this command"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("airship_lock", {
|
||||||
|
params = "true/false",
|
||||||
|
description = "Blocks boarding of non-owners. true to lock, false to unlock",
|
||||||
|
privs = {interact = true},
|
||||||
|
func = function(name, param)
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
local attached_to = player:get_attach()
|
||||||
|
|
||||||
|
if attached_to ~= nil then
|
||||||
|
local seat = attached_to:get_attach()
|
||||||
|
if seat ~= nil then
|
||||||
|
local entity = seat:get_luaentity()
|
||||||
|
if entity then
|
||||||
|
if entity.name == "ap_airship:airship" then
|
||||||
|
if param == "true" then
|
||||||
|
entity._passengers_locked = true
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ffff00', " >>> Non owners cannot enter now."))
|
||||||
|
elseif param == "false" then
|
||||||
|
entity._passengers_locked = false
|
||||||
|
minetest.chat_send_player(name,core.colorize('#00ff00', " >>> Non owners are free to enter now."))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> you are not inside a airship to perform this command"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> you are not inside a airship to perform this command"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("airship_logo", {
|
||||||
|
params = "",
|
||||||
|
description = "Changes airship logo",
|
||||||
|
privs = {interact = true},
|
||||||
|
func = function(name, param)
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
local attached_to = player:get_attach()
|
||||||
|
|
||||||
|
if attached_to ~= nil then
|
||||||
|
local seat = attached_to:get_attach()
|
||||||
|
if seat ~= nil then
|
||||||
|
local entity = seat:get_luaentity()
|
||||||
|
if entity then
|
||||||
|
if entity.name == "ap_airship:airship" then
|
||||||
|
if entity.owner == name then
|
||||||
|
ap_airship.logo_formspec(name)
|
||||||
|
--minetest.chat_send_all(dump(entity._shared_owners))
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> only the owner can do this action"))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> you are not inside a airship to perform this command"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> you are not inside a airship to perform this command"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_chatcommand("airship_eject", {
|
||||||
|
params = "",
|
||||||
|
description = "Ejects from the airship - useful for clients before 5.3",
|
||||||
|
privs = {interact = true},
|
||||||
|
func = function(name, param)
|
||||||
|
local colorstring = core.colorize('#ff0000', " >>> you are not inside a airship")
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
local attached_to = player:get_attach()
|
||||||
|
|
||||||
|
if attached_to ~= nil then
|
||||||
|
local seat = attached_to:get_attach()
|
||||||
|
if seat ~= nil then
|
||||||
|
local entity = seat:get_luaentity()
|
||||||
|
if entity then
|
||||||
|
if entity.name == "ap_airship:airship" then
|
||||||
|
for i = 5,1,-1
|
||||||
|
do
|
||||||
|
if entity._passengers[i] == name then
|
||||||
|
ap_airship.dettach_pax(entity, player, "l")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,colorstring)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(name,colorstring)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
58
fuel_management.lua
Executable file
|
@ -0,0 +1,58 @@
|
||||||
|
--
|
||||||
|
-- fuel
|
||||||
|
--
|
||||||
|
ap_airship.MAX_FUEL = minetest.settings:get("ap_airship_max_fuel") or 99
|
||||||
|
ap_airship.FUEL_CONSUMPTION = minetest.settings:get("ap_airship_fuel_consumption") or 6000
|
||||||
|
|
||||||
|
function ap_airship.contains(table, val)
|
||||||
|
for k,v in pairs(table) do
|
||||||
|
if k == val then
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.load_fuel(self, player)
|
||||||
|
local inv = player:get_inventory()
|
||||||
|
|
||||||
|
local itmstck=player:get_wielded_item()
|
||||||
|
local item_name = ""
|
||||||
|
if itmstck then item_name = itmstck:get_name() end
|
||||||
|
|
||||||
|
local grp_wood = minetest.get_item_group(item_name, "wood")
|
||||||
|
local grp_tree = minetest.get_item_group(item_name, "tree")
|
||||||
|
if grp_wood == 1 or grp_tree == 1 then
|
||||||
|
local stack = ItemStack(item_name .. " 1")
|
||||||
|
|
||||||
|
if self._energy < ap_airship.MAX_FUEL then
|
||||||
|
inv:remove_item("main", stack)
|
||||||
|
local amount = 1
|
||||||
|
if grp_tree == 1 then amount = 4 end
|
||||||
|
self._energy = self._energy + amount
|
||||||
|
if self._energy > ap_airship.MAX_FUEL then self._energy = ap_airship.MAX_FUEL end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--minetest.chat_send_all("fuel: ".. dump(item_name))
|
||||||
|
local fuel = ap_airship.contains(ap_airship.fuel, item_name)
|
||||||
|
if fuel then
|
||||||
|
local stack = ItemStack(item_name .. " 1")
|
||||||
|
|
||||||
|
if self._energy < ap_airship.MAX_FUEL then
|
||||||
|
inv:remove_item("main", stack)
|
||||||
|
self._energy = self._energy + fuel.amount
|
||||||
|
if self._energy > ap_airship.MAX_FUEL then self._energy = ap_airship.MAX_FUEL end
|
||||||
|
--minetest.chat_send_all(self.energy)
|
||||||
|
|
||||||
|
--local energy_indicator_angle = ap_airship.get_pointer_angle(self._energy, ap_airship.MAX_FUEL)
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
269
hud.lua
Executable file
|
@ -0,0 +1,269 @@
|
||||||
|
ap_airship.hud_list = {}
|
||||||
|
|
||||||
|
function ap_airship.get_pointer_angle(value, maxvalue)
|
||||||
|
local angle = value/maxvalue * 180
|
||||||
|
--angle = angle - 90
|
||||||
|
--angle = angle * -1
|
||||||
|
return angle
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.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 ap_airship.update_hud(player, coal, water, pressure, power_lever)
|
||||||
|
if player == nil then return end
|
||||||
|
local player_name = player:get_player_name()
|
||||||
|
|
||||||
|
local screen_pos_y = -100
|
||||||
|
local screen_pos_x = 10
|
||||||
|
|
||||||
|
local water_gauge_x = screen_pos_x + 374
|
||||||
|
local water_gauge_y = screen_pos_y
|
||||||
|
local press_gauge_x = screen_pos_x + 85
|
||||||
|
local press_gauge_y = water_gauge_y
|
||||||
|
local coal_1_x = screen_pos_x + 182
|
||||||
|
local coal_1_y = screen_pos_y
|
||||||
|
local coal_2_x = coal_1_x + 60
|
||||||
|
local coal_2_y = screen_pos_y
|
||||||
|
local throttle_x = screen_pos_x + 395
|
||||||
|
local throttle_y = screen_pos_y + 45
|
||||||
|
|
||||||
|
local ids = ap_airship.hud_list[player_name]
|
||||||
|
if ids then
|
||||||
|
player:hud_change(ids["throttle"], "offset", {x = throttle_x, y = throttle_y - power_lever})
|
||||||
|
|
||||||
|
--[[local coal_value = coal
|
||||||
|
if coal_value > 99 then coal_value = 99 end
|
||||||
|
if coal_value < 0 then coal_value = 0 end
|
||||||
|
player:hud_change(ids["coal_1"], "text", "ap_airship_"..(math.floor(coal_value/10))..".png")
|
||||||
|
player:hud_change(ids["coal_2"], "text", "ap_airship_"..(math.floor(coal_value%10))..".png")]]--
|
||||||
|
|
||||||
|
--[[ap_airship.animate_gauge(player, ids, "water_pt_", water_gauge_x, water_gauge_y, water)
|
||||||
|
ap_airship.animate_gauge(player, ids, "press_pt_", press_gauge_x, press_gauge_y, pressure)]]--
|
||||||
|
else
|
||||||
|
ids = {}
|
||||||
|
|
||||||
|
ids["title"] = player:hud_add({
|
||||||
|
hud_elem_type = "text",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = screen_pos_x + 240, y = screen_pos_y - 100},
|
||||||
|
text = "Airship engine state",
|
||||||
|
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 = "ap_airship_hud_panel.png",
|
||||||
|
scale = { x = 0.5, y = 0.5},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
|
||||||
|
ids["throttle"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = throttle_x, y = throttle_y},
|
||||||
|
text = "ap_airship_throttle.png",
|
||||||
|
scale = { x = 0.5, y = 0.5},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
|
||||||
|
--[[ids["coal_1"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = coal_1_x, y = coal_1_y},
|
||||||
|
text = "ap_airship_0.png",
|
||||||
|
scale = { x = 0.5, y = 0.5},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
|
||||||
|
ids["coal_2"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = coal_2_x, y = coal_2_y},
|
||||||
|
text = "ap_airship_0.png",
|
||||||
|
scale = { x = 0.5, y = 0.5},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})]]--
|
||||||
|
|
||||||
|
--[[ids["water_pt_1"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = water_gauge_x, y = water_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
|
||||||
|
ids["water_pt_2"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = water_gauge_x, y = water_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
ids["water_pt_3"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = water_gauge_x, y = water_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
ids["water_pt_4"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = water_gauge_x, y = water_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
ids["water_pt_5"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = water_gauge_x, y = water_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
ids["water_pt_6"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = water_gauge_x, y = water_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
ids["water_pt_7"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = water_gauge_x, y = water_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
|
||||||
|
ids["press_pt_1"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = press_gauge_x, y = press_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
ids["press_pt_2"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = press_gauge_x, y = press_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
ids["press_pt_3"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = press_gauge_x, y = press_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
ids["press_pt_4"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = press_gauge_x, y = press_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
ids["press_pt_5"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = press_gauge_x, y = press_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
ids["press_pt_6"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = press_gauge_x, y = press_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})
|
||||||
|
ids["press_pt_7"] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0, y = 1},
|
||||||
|
offset = {x = press_gauge_x, y = press_gauge_y},
|
||||||
|
text = "ap_airship_ind_box.png",
|
||||||
|
scale = { x = 6, y = 6},
|
||||||
|
alignment = { x = 1, y = 0 },
|
||||||
|
})]]--
|
||||||
|
|
||||||
|
ap_airship.hud_list[player_name] = ids
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ap_airship.remove_hud(player)
|
||||||
|
if player then
|
||||||
|
local player_name = player:get_player_name()
|
||||||
|
--minetest.chat_send_all(player_name)
|
||||||
|
local ids = ap_airship.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["throttle"])
|
||||||
|
--[[
|
||||||
|
player:hud_remove(ids["coal_1"])
|
||||||
|
player:hud_remove(ids["coal_2"])
|
||||||
|
player:hud_remove(ids["water_pt_7"])
|
||||||
|
player:hud_remove(ids["water_pt_6"])
|
||||||
|
player:hud_remove(ids["water_pt_5"])
|
||||||
|
player:hud_remove(ids["water_pt_4"])
|
||||||
|
player:hud_remove(ids["water_pt_3"])
|
||||||
|
player:hud_remove(ids["water_pt_2"])
|
||||||
|
player:hud_remove(ids["water_pt_1"])
|
||||||
|
player:hud_remove(ids["press_pt_7"])
|
||||||
|
player:hud_remove(ids["press_pt_6"])
|
||||||
|
player:hud_remove(ids["press_pt_5"])
|
||||||
|
player:hud_remove(ids["press_pt_4"])
|
||||||
|
player:hud_remove(ids["press_pt_3"])
|
||||||
|
player:hud_remove(ids["press_pt_2"])
|
||||||
|
player:hud_remove(ids["press_pt_1"])]]--
|
||||||
|
end
|
||||||
|
ap_airship.hud_list[player_name] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
228
init.lua
Executable file
|
@ -0,0 +1,228 @@
|
||||||
|
ap_airship={}
|
||||||
|
ap_airship.gravity = tonumber(minetest.settings:get("movement_gravity")) or 9.8
|
||||||
|
ap_airship.trunk_slots = 50
|
||||||
|
ap_airship.fuel = {['biofuel:biofuel'] = {amount=1},['biofuel:bottle_fuel'] = {amount=1},
|
||||||
|
['biofuel:phial_fuel'] = {amount=0.25}, ['biofuel:fuel_can'] = {amount=10}}
|
||||||
|
ap_airship.ideal_step = 0.02
|
||||||
|
ap_airship.rudder_limit = 30
|
||||||
|
ap_airship.iddle_rotation = 50
|
||||||
|
ap_airship.max_engine_acc = 1.5
|
||||||
|
ap_airship.max_speed = 8
|
||||||
|
ap_airship.max_seats = 2
|
||||||
|
ap_airship.pilot_base_pos = {x=0.0,y=-29,z=170}
|
||||||
|
ap_airship.passenger_pos = {
|
||||||
|
[1] = {x=0.0,y=0,z=60},
|
||||||
|
[2] = {x=-11,y=0,z=20},
|
||||||
|
[3] = {x=11,y=0,z=20},
|
||||||
|
[4] = {x=-11,y=0,z=80},
|
||||||
|
[5] = {x=11,y=0,z=80},
|
||||||
|
}
|
||||||
|
|
||||||
|
ap_airship.canvas_texture = "wool_white.png^[colorize:#f4e7c1:128"
|
||||||
|
ap_airship.grey_texture = "ap_airship_base.png^[colorize:#535c5c:128"
|
||||||
|
ap_airship.white_texture = "ap_airship_base.png^[colorize:#a3acac:128"
|
||||||
|
ap_airship.metal_texture = "ap_airship_metal.png"
|
||||||
|
ap_airship.black_texture = "ap_airship_base.png^[colorize:#030303:200"
|
||||||
|
ap_airship.rotor_texture = "ap_airship_helice.png"
|
||||||
|
ap_airship.textures = {
|
||||||
|
ap_airship.grey_texture, --"ap_airship_painting.png", --balao
|
||||||
|
ap_airship.metal_texture, --ponteira nariz
|
||||||
|
ap_airship.black_texture, -- corpo da bussola
|
||||||
|
ap_airship.metal_texture, -- indicador bussola
|
||||||
|
ap_airship.grey_texture, --"ap_airship_painting.png", --empenagem
|
||||||
|
ap_airship.metal_texture, --timao
|
||||||
|
ap_airship.black_texture, --timao
|
||||||
|
"ap_airship_compass.png", --bussola
|
||||||
|
"ap_airship_sup_eng.png", --suporte motores
|
||||||
|
"ap_airship_helice.png", --helice
|
||||||
|
ap_airship.black_texture, --eixo helice
|
||||||
|
ap_airship.grey_texture, --interior cabine
|
||||||
|
"default_ladder_steel.png", --escada
|
||||||
|
ap_airship.white_texture, --interior cabine 2
|
||||||
|
"ap_airship_glass_2.png", --vidros do deck superior
|
||||||
|
ap_airship.grey_texture, -- "ap_airship_painting.png", --motor
|
||||||
|
ap_airship.grey_texture, --"ap_airship_painting.png", --cabine
|
||||||
|
"ap_airship_glass.png", --janelas
|
||||||
|
ap_airship.black_texture, --piso
|
||||||
|
"ap_airship_alpha_logo.png", --logo
|
||||||
|
ap_airship.metal_texture,
|
||||||
|
}
|
||||||
|
|
||||||
|
ap_airship.colors ={
|
||||||
|
black='black',
|
||||||
|
blue='blue',
|
||||||
|
brown='brown',
|
||||||
|
cyan='cyan',
|
||||||
|
dark_green='dark_green',
|
||||||
|
dark_grey='dark_grey',
|
||||||
|
green='green',
|
||||||
|
grey='grey',
|
||||||
|
magenta='magenta',
|
||||||
|
orange='orange',
|
||||||
|
pink='pink',
|
||||||
|
red='red',
|
||||||
|
violet='violet',
|
||||||
|
white='white',
|
||||||
|
yellow='yellow',
|
||||||
|
}
|
||||||
|
|
||||||
|
dofile(minetest.get_modpath("ap_airship") .. DIR_DELIM .. "utilities.lua")
|
||||||
|
dofile(minetest.get_modpath("ap_airship") .. DIR_DELIM .. "control.lua")
|
||||||
|
dofile(minetest.get_modpath("ap_airship") .. DIR_DELIM .. "fuel_management.lua")
|
||||||
|
dofile(minetest.get_modpath("ap_airship") .. DIR_DELIM .. "engine_management.lua")
|
||||||
|
dofile(minetest.get_modpath("ap_airship") .. DIR_DELIM .. "custom_physics.lua")
|
||||||
|
dofile(minetest.get_modpath("ap_airship") .. DIR_DELIM .. "hud.lua")
|
||||||
|
dofile(minetest.get_modpath("ap_airship") .. DIR_DELIM .. "entities.lua")
|
||||||
|
dofile(minetest.get_modpath("ap_airship") .. DIR_DELIM .. "forms.lua")
|
||||||
|
dofile(minetest.get_modpath("ap_airship") .. DIR_DELIM .. "manual.lua")
|
||||||
|
dofile(minetest.get_modpath("ap_airship") .. DIR_DELIM .. "walk_map.lua")
|
||||||
|
|
||||||
|
--
|
||||||
|
-- helpers and co.
|
||||||
|
--
|
||||||
|
|
||||||
|
function ap_airship.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 ap_airship.dot(v1,v2)
|
||||||
|
return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.sign(n)
|
||||||
|
return n>=0 and 1 or -1
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.minmax(v,m)
|
||||||
|
return math.min(math.abs(v),m)*ap_airship.sign(v)
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------
|
||||||
|
-- items
|
||||||
|
-----------
|
||||||
|
|
||||||
|
-- airship
|
||||||
|
minetest.register_craftitem("ap_airship:airship", {
|
||||||
|
description = "Airship",
|
||||||
|
inventory_image = "ap_airship_icon.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+4
|
||||||
|
local airship = minetest.add_entity(pointed_pos, "ap_airship:airship")
|
||||||
|
if airship and placer then
|
||||||
|
local ent = airship:get_luaentity()
|
||||||
|
ent._passengers = ap_airship.copy_vector({[1]=nil, [2]=nil, [3]=nil, [4]=nil, [5]=nil,})
|
||||||
|
--minetest.chat_send_all('passengers: '.. dump(ent._passengers))
|
||||||
|
local owner = placer:get_player_name()
|
||||||
|
ent.owner = owner
|
||||||
|
airship:set_yaw(placer:get_look_horizontal())
|
||||||
|
itemstack:take_item()
|
||||||
|
airutils.create_inventory(ent, ap_airship.trunk_slots, owner)
|
||||||
|
|
||||||
|
local properties = ent.object:get_properties()
|
||||||
|
properties.infotext = owner .. " nice airship"
|
||||||
|
airship:set_properties(properties)
|
||||||
|
--ap_airship.attach_pax(ent, placer)
|
||||||
|
end
|
||||||
|
|
||||||
|
return itemstack
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- crafting
|
||||||
|
--
|
||||||
|
|
||||||
|
if not minetest.settings:get_bool('ap_airship.disable_craftitems') then
|
||||||
|
--[[minetest.register_craft({
|
||||||
|
output = "ap_airship:cylinder_part",
|
||||||
|
recipe = {
|
||||||
|
{"default:stick", "wool:white", "default:stick"},
|
||||||
|
{"wool:white", "group:wood", "wool:white"},
|
||||||
|
{"default:stick", "wool:white", "default:stick"},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "ap_airship:cylinder",
|
||||||
|
recipe = {
|
||||||
|
{"ap_airship:cylinder_part", "ap_airship:cylinder_part", "ap_airship:cylinder_part"},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "ap_airship:rotor",
|
||||||
|
recipe = {
|
||||||
|
{"wool:white", "default:stick", ""},
|
||||||
|
{"wool:white", "default:stick", "default:steelblock"},
|
||||||
|
{"wool:white", "default:stick", ""},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "ap_airship:boiler",
|
||||||
|
recipe = {
|
||||||
|
{"default:steel_ingot","default:steel_ingot"},
|
||||||
|
{"default:steelblock","default:steel_ingot",},
|
||||||
|
{"default:steelblock","default:steel_ingot"},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "ap_airship:boat",
|
||||||
|
recipe = {
|
||||||
|
{"group:wood", "group:wood", "ap_airship:rotor"},
|
||||||
|
{"group:wood", "ap_airship:boiler", "group:wood"},
|
||||||
|
{"group:wood", "group:wood", "ap_airship:rotor"},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "ap_airship:airship",
|
||||||
|
recipe = {
|
||||||
|
{"ap_airship:cylinder",},
|
||||||
|
{"ap_airship:boat",},
|
||||||
|
}
|
||||||
|
})]]--
|
||||||
|
|
||||||
|
-- cylinder section
|
||||||
|
--[[minetest.register_craftitem("ap_airship:cylinder_part",{
|
||||||
|
description = "ap_airship cylinder section",
|
||||||
|
inventory_image = "ap_airship_cylinder_part.png",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- cylinder
|
||||||
|
minetest.register_craftitem("ap_airship:cylinder",{
|
||||||
|
description = "ap_airship cylinder",
|
||||||
|
inventory_image = "ap_airship_cylinder.png",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- boiler
|
||||||
|
minetest.register_craftitem("ap_airship:boiler",{
|
||||||
|
description = "ap_airship boiler",
|
||||||
|
inventory_image = "ap_airship_boiler.png",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- boiler
|
||||||
|
minetest.register_craftitem("ap_airship:rotor",{
|
||||||
|
description = "ap_airship rotor",
|
||||||
|
inventory_image = "ap_airship_rotor.png",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- fuselage
|
||||||
|
minetest.register_craftitem("ap_airship:boat",{
|
||||||
|
description = "ap_airship fuselage",
|
||||||
|
inventory_image = "ap_airship_boat.png",
|
||||||
|
})]]--
|
||||||
|
end
|
||||||
|
|
91
manual.lua
Executable file
|
@ -0,0 +1,91 @@
|
||||||
|
--------------
|
||||||
|
-- Manual --
|
||||||
|
--------------
|
||||||
|
|
||||||
|
function ap_airship.manual_formspec(name)
|
||||||
|
local basic_form = table.concat({
|
||||||
|
"formspec_version[3]",
|
||||||
|
"size[6,6]"
|
||||||
|
}, "")
|
||||||
|
|
||||||
|
basic_form = basic_form.."button[1,1.0;4,1;short;Shortcuts]"
|
||||||
|
basic_form = basic_form.."button[1,2.5;4,1;fuel;Refueling]"
|
||||||
|
basic_form = basic_form.."button[1,4.0;4,1;share;Sharing]"
|
||||||
|
|
||||||
|
minetest.show_formspec(name, "ap_airship:manual_main", basic_form)
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
if formname == "ap_airship:manual_main" then
|
||||||
|
local formspec_color = "#44444466"
|
||||||
|
if fields.short then
|
||||||
|
local text = {
|
||||||
|
"Shortcuts \n\n",
|
||||||
|
"* Right click: enter in / acess the internal menu \n",
|
||||||
|
"* Punch with dye to paint the primary color\n",
|
||||||
|
"* Punch a dye, but holding Aux (E) key to change the secondary color.\n",
|
||||||
|
"* To change the airship logo, call the command \""..core.colorize('#ffff00', "/airship_logo").."\".\n",
|
||||||
|
"* Forward or backward while in drive position: controls the power lever \n",
|
||||||
|
"* Left or right while in drive position: controls the direction \n",
|
||||||
|
"* Jump and sneak: controls the up and down movement \n",
|
||||||
|
"* Aux (E) + right click while inside: acess inventory \n",
|
||||||
|
"* Aux (E) + backward while in drive position: the machine does backward \n",
|
||||||
|
"* Aux (E) + foward while in drive position: extra power \n"
|
||||||
|
}
|
||||||
|
local shortcut_form = table.concat({
|
||||||
|
"formspec_version[3]",
|
||||||
|
"size[16,10]",
|
||||||
|
"no_prepend[]",
|
||||||
|
"bgcolor["..formspec_color..";false]",
|
||||||
|
"label[1.0,2.0;", table.concat(text, ""), "]",
|
||||||
|
}, "")
|
||||||
|
minetest.show_formspec(player:get_player_name(), "ap_airship:manual_shortcut", shortcut_form)
|
||||||
|
end
|
||||||
|
if fields.fuel then
|
||||||
|
local text = {
|
||||||
|
"Fuel \n\n",
|
||||||
|
"To fly it, it is necessary to provide some items, such as fuel to be burned and \n",
|
||||||
|
"water for the boiler. The fuel can be coal, coal block or wood. To supply it, \n",
|
||||||
|
"be on board and punch the necessary items on the airship.\n",
|
||||||
|
"There is another way to load water to the boiler: if it is landed on water, it can load \n",
|
||||||
|
"it through the menu. But the current pressure will be lost. \n"
|
||||||
|
}
|
||||||
|
local fuel_form = table.concat({
|
||||||
|
"formspec_version[3]",
|
||||||
|
"size[16,10]",
|
||||||
|
"no_prepend[]",
|
||||||
|
"bgcolor["..formspec_color..";false]",
|
||||||
|
"label[1.0,2.0;", table.concat(text, ""), "]",
|
||||||
|
}, "")
|
||||||
|
minetest.show_formspec(player:get_player_name(), "ap_airship:fuel", fuel_form)
|
||||||
|
end
|
||||||
|
if fields.share then
|
||||||
|
local text = {
|
||||||
|
"Sharing \n\n",
|
||||||
|
"This vehicle was made to be shared with a team. So the owner can set more users to \n",
|
||||||
|
"operate it. Inside the airship, just use the command \""..core.colorize('#ffff00', "/airship_share <name>").."\" \n",
|
||||||
|
"To remove someone from the sharing, \""..core.colorize('#ffff00', "/airship_remove <name>").."\" \n",
|
||||||
|
"To list the owners, \""..core.colorize('#ffff00', "/airship_list").."\" \n",
|
||||||
|
"Is possible to lock the airship access, so only the owners can enter: \""..core.colorize('#ffff00', "/airship_lock true").."\" \n",
|
||||||
|
"To let anyone enter, \""..core.colorize('#ffff00', "/airship_lock false").."\" \n",
|
||||||
|
"All shared owners can access the airship inventory"
|
||||||
|
}
|
||||||
|
local tips_form = table.concat({
|
||||||
|
"formspec_version[3]",
|
||||||
|
"size[16,10]",
|
||||||
|
"no_prepend[]",
|
||||||
|
"bgcolor["..formspec_color..";false]",
|
||||||
|
"label[1,2;", table.concat(text, ""), "]",
|
||||||
|
}, "")
|
||||||
|
minetest.show_formspec(player:get_player_name(), "ap_airship:share", tips_form)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_chatcommand("airship_manual", {
|
||||||
|
params = "",
|
||||||
|
description = "Airship manual",
|
||||||
|
func = function(name, param)
|
||||||
|
ap_airship.manual_formspec(name)
|
||||||
|
end
|
||||||
|
})
|
6
mod.conf
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
name = ap_airship
|
||||||
|
depends = default,player_api,wool,airutils
|
||||||
|
optional_depends = climate_api
|
||||||
|
author = APercy
|
||||||
|
description = Adds an airship to minetest game
|
||||||
|
title = Airship
|
BIN
models/ap_airship_light.b3d
Executable file
BIN
models/ap_airship_mesh.b3d
Executable file
BIN
models/ap_airship_stand_base.b3d
Executable file
BIN
sounds/ap_airship_collision.ogg
Executable file
BIN
sounds/ap_airship_engine.ogg
Normal file
BIN
textures/ap_airship_alpha.png
Executable file
After Width: | Height: | Size: 4.8 KiB |
BIN
textures/ap_airship_alpha_logo.png
Executable file
After Width: | Height: | Size: 4.8 KiB |
BIN
textures/ap_airship_base.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
textures/ap_airship_compass.png
Normal file
After Width: | Height: | Size: 144 KiB |
BIN
textures/ap_airship_cylinder.png
Executable file
After Width: | Height: | Size: 10 KiB |
BIN
textures/ap_airship_cylinder_part.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
textures/ap_airship_glass.png
Executable file
After Width: | Height: | Size: 5.1 KiB |
BIN
textures/ap_airship_glass_2.png
Executable file
After Width: | Height: | Size: 7.8 KiB |
BIN
textures/ap_airship_helice.png
Executable file
After Width: | Height: | Size: 1.3 KiB |
BIN
textures/ap_airship_hud_panel.png
Executable file
After Width: | Height: | Size: 13 KiB |
BIN
textures/ap_airship_hud_panel.xcf
Normal file
BIN
textures/ap_airship_icon.png
Executable file
After Width: | Height: | Size: 6.6 KiB |
BIN
textures/ap_airship_ind_box.png
Executable file
After Width: | Height: | Size: 5 KiB |
BIN
textures/ap_airship_metal.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
textures/ap_airship_painting.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
textures/ap_airship_rotor.png
Executable file
After Width: | Height: | Size: 9.5 KiB |
BIN
textures/ap_airship_sup_eng.png
Executable file
After Width: | Height: | Size: 13 KiB |
BIN
textures/ap_airship_throttle.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
textures/blimp_clover.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
textures/blimp_jack.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
textures/blimp_liz.png
Executable file
After Width: | Height: | Size: 3.8 KiB |
BIN
textures/blimp_shotting_star.png
Executable file
After Width: | Height: | Size: 14 KiB |
BIN
textures/blimp_skull.png
Executable file
After Width: | Height: | Size: 10 KiB |
419
utilities.lua
Executable file
|
@ -0,0 +1,419 @@
|
||||||
|
function ap_airship.testDamage(self, velocity, position)
|
||||||
|
if self._last_accell == nil then return end
|
||||||
|
local p = position --self.object:get_pos()
|
||||||
|
local collision = false
|
||||||
|
local low_node_pos = -2.5
|
||||||
|
if self._last_vel == nil then return end
|
||||||
|
--lets calculate the vertical speed, to avoid the bug on colliding on floor with hard lag
|
||||||
|
if math.abs(velocity.y - self._last_vel.y) > 2 then
|
||||||
|
local noded = airutils.nodeatpos(airutils.pos_shift(p,{y=low_node_pos}))
|
||||||
|
if (noded and noded.drawtype ~= 'airlike') then
|
||||||
|
collision = true
|
||||||
|
else
|
||||||
|
self.object:set_velocity(self._last_vel)
|
||||||
|
--self.object:set_acceleration(self._last_accell)
|
||||||
|
self.object:set_velocity(vector.add(velocity, vector.multiply(self._last_accell, self.dtime/8)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local impact = math.abs(ap_airship.get_hipotenuse_value(velocity, self._last_vel))
|
||||||
|
if impact > 2 then
|
||||||
|
if self.colinfo then
|
||||||
|
collision = self.colinfo.collides
|
||||||
|
--minetest.chat_send_all(impact)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if collision then
|
||||||
|
--self.object:set_velocity({x=0,y=0,z=0})
|
||||||
|
local damage = impact -- / 2
|
||||||
|
minetest.sound_play("ap_airship_collision", {
|
||||||
|
--to_player = self.driver_name,
|
||||||
|
object = self.object,
|
||||||
|
max_hear_distance = 15,
|
||||||
|
gain = 1.0,
|
||||||
|
fade = 0.0,
|
||||||
|
pitch = 1.0,
|
||||||
|
}, true)
|
||||||
|
if damage > 5 then
|
||||||
|
self._power_lever = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.driver_name then
|
||||||
|
local player_name = self.driver_name
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
local function do_attach(self, player, slot)
|
||||||
|
if slot == 0 then return end
|
||||||
|
if self._passengers[slot] == nil then
|
||||||
|
local name = player:get_player_name()
|
||||||
|
--minetest.chat_send_all(self.driver_name)
|
||||||
|
self._passengers[slot] = name
|
||||||
|
player:set_attach(self._passengers_base[slot], "", {x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
||||||
|
player_api.player_attached[name] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.check_passenger_is_attached(self, name)
|
||||||
|
local is_attached = false
|
||||||
|
if is_attached == false then
|
||||||
|
for i = 5,1,-1
|
||||||
|
do
|
||||||
|
if self._passengers[i] == name then
|
||||||
|
is_attached = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return is_attached
|
||||||
|
end
|
||||||
|
|
||||||
|
--this method checks each 1 second for a disconected player who comes back
|
||||||
|
function ap_airship.rescueConnectionFailedPassengers(self)
|
||||||
|
self._disconnection_check_time = self._disconnection_check_time + self.dtime
|
||||||
|
if self._disconnection_check_time > 1 then
|
||||||
|
--minetest.chat_send_all(dump(self._passengers))
|
||||||
|
self._disconnection_check_time = 0
|
||||||
|
for i = 5,1,-1
|
||||||
|
do
|
||||||
|
if self._passengers[i] then
|
||||||
|
local player = minetest.get_player_by_name(self._passengers[i])
|
||||||
|
if player then --we have a player!
|
||||||
|
if player_api.player_attached[self._passengers[i]] == nil then --but isn't attached?
|
||||||
|
--minetest.chat_send_all("okay")
|
||||||
|
if player:get_hp() > 0 then
|
||||||
|
self._passengers[i] = nil --clear the slot first
|
||||||
|
do_attach(self, player, i) --attach
|
||||||
|
else
|
||||||
|
--ap_airship.dettachPlayer(self, player)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- attach passenger
|
||||||
|
function ap_airship.attach_pax(self, player, slot)
|
||||||
|
slot = slot or 0
|
||||||
|
|
||||||
|
--verify if is locked to non-owners
|
||||||
|
if self._passengers_locked == true then
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local can_bypass = minetest.check_player_privs(player, {protection_bypass=true})
|
||||||
|
local is_shared = false
|
||||||
|
if name == self.owner or can_bypass then is_shared = true end
|
||||||
|
for k, v in pairs(self._shared_owners) do
|
||||||
|
if v == name then
|
||||||
|
is_shared = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if is_shared == false then
|
||||||
|
minetest.chat_send_player(name,core.colorize('#ff0000', " >>> This airship is currently locked for non-owners"))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if slot > 0 then
|
||||||
|
do_attach(self, player, slot)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
--minetest.chat_send_all(dump(self._passengers))
|
||||||
|
|
||||||
|
--now yes, lets attach the player
|
||||||
|
--randomize the seat
|
||||||
|
local t = {1,2,3,4,5}
|
||||||
|
for i = 1, #t*2 do
|
||||||
|
local a = math.random(#t)
|
||||||
|
local b = math.random(#t)
|
||||||
|
t[a],t[b] = t[b],t[a]
|
||||||
|
end
|
||||||
|
|
||||||
|
--minetest.chat_send_all(dump(t))
|
||||||
|
|
||||||
|
local i=0
|
||||||
|
for k,v in ipairs(t) do
|
||||||
|
i = t[k]
|
||||||
|
if self._passengers[i] == nil then
|
||||||
|
do_attach(self, player, i)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.dettach_pax(self, player, side)
|
||||||
|
side = side or "r"
|
||||||
|
if player then
|
||||||
|
local name = player:get_player_name() --self._passenger
|
||||||
|
ap_airship.remove_hud(player)
|
||||||
|
|
||||||
|
-- passenger clicked the object => driver gets off the vehicle
|
||||||
|
for i = 5,1,-1
|
||||||
|
do
|
||||||
|
if self._passengers[i] == name then
|
||||||
|
self._passengers[i] = nil
|
||||||
|
self._passengers_base_pos[i] = ap_airship.copy_vector(ap_airship.passenger_pos[i])
|
||||||
|
--break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- detach the player
|
||||||
|
player:set_detach()
|
||||||
|
player_api.player_attached[name] = nil
|
||||||
|
player_api.set_animation(player, "stand")
|
||||||
|
|
||||||
|
-- move player down
|
||||||
|
minetest.after(0.1, function(pos)
|
||||||
|
local rotation = self.object:get_rotation()
|
||||||
|
local direction = rotation.y
|
||||||
|
|
||||||
|
if side == "l" then
|
||||||
|
direction = direction - math.rad(180)
|
||||||
|
end
|
||||||
|
|
||||||
|
local move = 5
|
||||||
|
pos.x = pos.x + move * math.cos(direction)
|
||||||
|
pos.z = pos.z + move * math.sin(direction)
|
||||||
|
if self.isinliquid then
|
||||||
|
pos.y = pos.y + 1
|
||||||
|
else
|
||||||
|
pos.y = pos.y - 2.5
|
||||||
|
end
|
||||||
|
player:set_pos(pos)
|
||||||
|
end, player:get_pos())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.textures_copy()
|
||||||
|
local tablecopy = {}
|
||||||
|
for k, v in pairs(ap_airship.textures) do
|
||||||
|
tablecopy[k] = v
|
||||||
|
end
|
||||||
|
return tablecopy
|
||||||
|
end
|
||||||
|
|
||||||
|
local function paint(self)
|
||||||
|
local l_textures = ap_airship.textures_copy()
|
||||||
|
for _, texture in ipairs(l_textures) do
|
||||||
|
local indx = texture:find('wool_blue.png')
|
||||||
|
if indx then
|
||||||
|
l_textures[_] = "wool_".. self.color..".png"
|
||||||
|
end
|
||||||
|
indx = texture:find('wool_yellow.png')
|
||||||
|
if indx then
|
||||||
|
l_textures[_] = "wool_".. self.color2..".png"
|
||||||
|
end
|
||||||
|
indx = texture:find('ap_airship_alpha_logo.png')
|
||||||
|
if indx then
|
||||||
|
l_textures[_] = self.logo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.object:set_properties({textures=l_textures})
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.set_logo(self, texture_name)
|
||||||
|
if texture_name == "" or texture_name == nil then
|
||||||
|
self.logo = "ap_airship_alpha_logo.png"
|
||||||
|
elseif texture_name then
|
||||||
|
self.logo = texture_name
|
||||||
|
end
|
||||||
|
paint(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
--painting
|
||||||
|
function ap_airship.paint(self, colstr)
|
||||||
|
if colstr then
|
||||||
|
self.color = colstr
|
||||||
|
paint(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function ap_airship.paint2(self, colstr)
|
||||||
|
if colstr then
|
||||||
|
self.color2 = colstr
|
||||||
|
paint(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- destroy the boat
|
||||||
|
function ap_airship.destroy(self, overload)
|
||||||
|
if self.sound_handle then
|
||||||
|
minetest.sound_stop(self.sound_handle)
|
||||||
|
self.sound_handle = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local pos = self.object:get_pos()
|
||||||
|
if self._passengers_base[1] then self._passengers_base[1]:remove() end
|
||||||
|
if self._passengers_base[2] then self._passengers_base[2]:remove() end
|
||||||
|
if self._passengers_base[3] then self._passengers_base[3]:remove() end
|
||||||
|
if self._passengers_base[4] then self._passengers_base[4]:remove() end
|
||||||
|
if self._passengers_base[5] then self._passengers_base[5]:remove() end
|
||||||
|
|
||||||
|
airutils.destroy_inventory(self)
|
||||||
|
self.object:remove()
|
||||||
|
|
||||||
|
pos.y=pos.y+2
|
||||||
|
--[[for i=1,7 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
|
||||||
|
|
||||||
|
for i=1,7 do
|
||||||
|
minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'default:mese_crystal')
|
||||||
|
end]]--
|
||||||
|
|
||||||
|
--minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'ap_airship:boat')
|
||||||
|
--minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},'default:diamond')
|
||||||
|
|
||||||
|
--[[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]]--
|
||||||
|
if overload then
|
||||||
|
local stack = ItemStack(self.item)
|
||||||
|
local item_def = stack:get_definition()
|
||||||
|
|
||||||
|
if item_def.overload_drop then
|
||||||
|
for _,item in pairs(item_def.overload_drop) do
|
||||||
|
minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5},item)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local stack = ItemStack(self.item)
|
||||||
|
local item_def = stack:get_definition()
|
||||||
|
if self.hull_integrity then
|
||||||
|
local boat_wear = math.floor(65535*(1-(self.hull_integrity/item_def.hull_integrity)))
|
||||||
|
stack:set_wear(boat_wear)
|
||||||
|
end
|
||||||
|
minetest.add_item({x=pos.x+math.random()-0.5,y=pos.y,z=pos.z+math.random()-0.5}, stack)
|
||||||
|
end
|
||||||
|
|
||||||
|
--returns 0 for old, 1 for new
|
||||||
|
function ap_airship.detect_player_api(player)
|
||||||
|
local player_proterties = player:get_properties()
|
||||||
|
local mesh = "character.b3d"
|
||||||
|
if player_proterties.mesh == mesh then
|
||||||
|
local models = player_api.registered_models
|
||||||
|
local character = models[mesh]
|
||||||
|
if character then
|
||||||
|
if character.animations.sit.eye_height then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.checkAttach(self, player)
|
||||||
|
local retVal = false
|
||||||
|
if player then
|
||||||
|
local player_attach = player:get_attach()
|
||||||
|
if player_attach then
|
||||||
|
for i = 5,1,-1
|
||||||
|
do
|
||||||
|
if player_attach == self._passengers_base[i] then
|
||||||
|
retVal = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return retVal
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.engineSoundPlay(self)
|
||||||
|
--sound
|
||||||
|
if self.sound_handle then minetest.sound_stop(self.sound_handle) end
|
||||||
|
if self.sound_handle_engine then minetest.sound_stop(self.sound_handle_engine) end
|
||||||
|
if self.object then
|
||||||
|
self.sound_handle = minetest.sound_play({name = "default_furnace_active"},
|
||||||
|
{object = self.object, gain = 0.2,
|
||||||
|
max_hear_distance = 5,
|
||||||
|
loop = true,})
|
||||||
|
|
||||||
|
self.sound_handle_engine = minetest.sound_play({name = "ap_airship_engine"},--"default_item_smoke"},
|
||||||
|
{object = self.object, gain = 3.0,
|
||||||
|
pitch = 0.4+((math.abs(self._power_lever)/100)/2),
|
||||||
|
max_hear_distance = 32,
|
||||||
|
loop = true,})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.engine_set_sound_and_animation(self)
|
||||||
|
if self._last_applied_power ~= self._power_lever then
|
||||||
|
--minetest.chat_send_all('test2')
|
||||||
|
self._last_applied_power = self._power_lever
|
||||||
|
self.object:set_animation_frame_speed(ap_airship.iddle_rotation + (self._power_lever*100))
|
||||||
|
if self._last_sound_update == nil then self._last_sound_update = self._power_lever end
|
||||||
|
if math.abs(self._last_sound_update - self._power_lever) > 5 then
|
||||||
|
self._last_sound_update = self._power_lever
|
||||||
|
ap_airship.engineSoundPlay(self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if self._engine_running == false then
|
||||||
|
self._power_lever = 0
|
||||||
|
self.object:set_animation_frame_speed(0)
|
||||||
|
if self.sound_handle then
|
||||||
|
minetest.sound_stop(self.sound_handle)
|
||||||
|
self.sound_handle = nil
|
||||||
|
--self.object:set_animation_frame_speed(0)
|
||||||
|
end
|
||||||
|
if self.sound_handle_engine then
|
||||||
|
minetest.sound_stop(self.sound_handle_engine)
|
||||||
|
self.sound_handle_engine = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ap_airship.start_furnace(self)
|
||||||
|
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
|
||||||
|
elseif self._engine_running == false and self._energy > 0 then
|
||||||
|
self._engine_running = true
|
||||||
|
-- sound
|
||||||
|
if self.sound_handle then minetest.sound_stop(self.sound_handle) end
|
||||||
|
if self.object then
|
||||||
|
self.sound_handle = minetest.sound_play({name = "default_furnace_active"},
|
||||||
|
{object = self.object, gain = 0.2,
|
||||||
|
max_hear_distance = 5,
|
||||||
|
loop = true,})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.copy_vector(original_vector)
|
||||||
|
local tablecopy = {}
|
||||||
|
for k, v in pairs(original_vector) do
|
||||||
|
tablecopy[k] = v
|
||||||
|
end
|
||||||
|
return tablecopy
|
||||||
|
end
|
||||||
|
|
205
walk_map.lua
Normal file
|
@ -0,0 +1,205 @@
|
||||||
|
function ap_airship.clamp(value, min, max)
|
||||||
|
local retVal = value
|
||||||
|
if value < min then retVal = min end
|
||||||
|
if value > max then retVal = max end
|
||||||
|
--minetest.chat_send_all(value .. " - " ..retVal)
|
||||||
|
return retVal
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.reclamp(value, min, max)
|
||||||
|
local retVal = value
|
||||||
|
local mid = (max-min)/2
|
||||||
|
if value > min and value <= (min+mid) then retVal = min end
|
||||||
|
if value < max and value > (max-mid) then retVal = max end
|
||||||
|
--minetest.chat_send_all(value .. " - return: " ..retVal .. " - mid: " .. mid)
|
||||||
|
return retVal
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.cabin_map(pos, dpos)
|
||||||
|
local orig_pos = ap_airship.copy_vector(pos)
|
||||||
|
local position = ap_airship.copy_vector(dpos)
|
||||||
|
local new_pos = ap_airship.copy_vector(dpos)
|
||||||
|
|
||||||
|
--limit to the cabin
|
||||||
|
new_pos.z = ap_airship.clamp(new_pos.z, 112, 164)
|
||||||
|
new_pos.y = -29
|
||||||
|
new_pos.x = ap_airship.clamp(new_pos.x, -8.42, 8.42)
|
||||||
|
|
||||||
|
--minetest.chat_send_all("x: "..new_pos.x.." - z: "..new_pos.z)
|
||||||
|
return new_pos
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_cabin_zone(pos)
|
||||||
|
local cabin_zone = false
|
||||||
|
if pos.z > -20 and pos.z <= 200 and pos.x > -8 and pos.x < 8 then cabin_zone = true end
|
||||||
|
return cabin_zone
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_ladder_zone(pos)
|
||||||
|
local ladder_zone = false
|
||||||
|
if pos.z <= 120 and pos.z >= 109 and pos.x > -9 and pos.x < -2 then ladder_zone = true end
|
||||||
|
return ladder_zone
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.passengers_deck_map(pos, dpos)
|
||||||
|
local orig_pos = ap_airship.copy_vector(pos)
|
||||||
|
local position = ap_airship.copy_vector(dpos)
|
||||||
|
local new_pos = ap_airship.copy_vector(dpos)
|
||||||
|
local ladder_zone = is_ladder_zone(pos)
|
||||||
|
|
||||||
|
if ladder_zone then
|
||||||
|
--limiting ladder space
|
||||||
|
new_pos.z = ap_airship.clamp(new_pos.z, 3, 118)
|
||||||
|
new_pos.x = ap_airship.clamp(new_pos.x, -8.42, -2)
|
||||||
|
else
|
||||||
|
--limiting upper deck
|
||||||
|
new_pos.z = ap_airship.clamp(new_pos.z, 3, 109)
|
||||||
|
new_pos.x = ap_airship.clamp(new_pos.x, -43, 43)
|
||||||
|
end
|
||||||
|
new_pos.y = 0
|
||||||
|
|
||||||
|
--minetest.chat_send_all("x: "..new_pos.x.." - z: "..new_pos.z)
|
||||||
|
return new_pos
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.ladder_map(pos, dpos)
|
||||||
|
local orig_pos = steampunk_blimp.copy_vector(pos)
|
||||||
|
local position = steampunk_blimp.copy_vector(dpos)
|
||||||
|
local new_pos = steampunk_blimp.copy_vector(dpos)
|
||||||
|
new_pos.z = steampunk_blimp.clamp(new_pos.z, 112, 118)
|
||||||
|
new_pos.x = steampunk_blimp.clamp(new_pos.x, -8.42, -2)
|
||||||
|
|
||||||
|
return new_pos
|
||||||
|
end
|
||||||
|
|
||||||
|
function ap_airship.navigate_deck(pos, dpos, player)
|
||||||
|
local pos_d = dpos
|
||||||
|
local ladder_zone = is_ladder_zone(pos)
|
||||||
|
|
||||||
|
local upper_deck_y = 0
|
||||||
|
local lower_deck_y = -29
|
||||||
|
local cabin_zone = is_cabin_zone(pos)
|
||||||
|
if player then
|
||||||
|
if pos.y == upper_deck_y then
|
||||||
|
pos_d = ap_airship.passengers_deck_map(pos, dpos)
|
||||||
|
elseif pos.y <= lower_deck_y + 5 then
|
||||||
|
if ladder_zone == false then
|
||||||
|
pos_d = ap_airship.cabin_map(pos, dpos)
|
||||||
|
end
|
||||||
|
elseif pos.y > lower_deck_y and pos.y < 10 then
|
||||||
|
pos_d = ap_airship.ladder_map(pos, dpos)
|
||||||
|
end
|
||||||
|
|
||||||
|
local ctrl = player:get_player_control()
|
||||||
|
if ctrl.jump or ctrl.sneak then --ladder
|
||||||
|
if ladder_zone then
|
||||||
|
--minetest.chat_send_all(dump(pos))
|
||||||
|
if ctrl.jump then
|
||||||
|
pos_d.y = pos_d.y + 0.9
|
||||||
|
if pos_d.y > upper_deck_y then pos_d.y = upper_deck_y end
|
||||||
|
end
|
||||||
|
if ctrl.sneak then
|
||||||
|
pos_d.y = pos_d.y - 0.9
|
||||||
|
if pos_d.y < lower_deck_y then pos_d.y = lower_deck_y end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return pos_d
|
||||||
|
end
|
||||||
|
|
||||||
|
--note: index variable just for the walk
|
||||||
|
--this function was improved by Auri Collings on steampunk_blimp
|
||||||
|
local function get_result_pos(self, player, index)
|
||||||
|
local pos = nil
|
||||||
|
if player then
|
||||||
|
local ctrl = player:get_player_control()
|
||||||
|
|
||||||
|
local direction = player:get_look_horizontal()
|
||||||
|
local rotation = self.object:get_rotation()
|
||||||
|
direction = direction - rotation.y
|
||||||
|
|
||||||
|
pos = vector.new()
|
||||||
|
|
||||||
|
local y_rot = -math.deg(direction)
|
||||||
|
pos.y = y_rot --okay, this is strange to keep here, but as I dont use it anyway...
|
||||||
|
|
||||||
|
|
||||||
|
if ctrl.up or ctrl.down or ctrl.left or ctrl.right then
|
||||||
|
player_api.set_animation(player, "walk", 30)
|
||||||
|
|
||||||
|
local speed = 0.4
|
||||||
|
|
||||||
|
dir = vector.new(ctrl.up and -1 or ctrl.down and 1 or 0, 0, ctrl.left and 1 or ctrl.right and -1 or 0)
|
||||||
|
dir = vector.normalize(dir)
|
||||||
|
dir = vector.rotate(dir, {x = 0, y = -direction, z = 0})
|
||||||
|
|
||||||
|
local time_correction = (self.dtime/ap_airship.ideal_step)
|
||||||
|
local move = speed * time_correction
|
||||||
|
|
||||||
|
pos.x = move * dir.x
|
||||||
|
pos.z = move * dir.z
|
||||||
|
|
||||||
|
--lets fake walk sound
|
||||||
|
if self._passengers_base_pos[index].dist_moved == nil then self._passengers_base_pos[index].dist_moved = 0 end
|
||||||
|
self._passengers_base_pos[index].dist_moved = self._passengers_base_pos[index].dist_moved + move;
|
||||||
|
if math.abs(self._passengers_base_pos[index].dist_moved) > 5 then
|
||||||
|
self._passengers_base_pos[index].dist_moved = 0
|
||||||
|
minetest.sound_play({name = "default_wood_footstep"},
|
||||||
|
{object = self._passengers_base_pos[index].object, gain = 0.1,
|
||||||
|
max_hear_distance = 5,
|
||||||
|
ephemeral = true,})
|
||||||
|
end
|
||||||
|
else
|
||||||
|
player_api.set_animation(player, "stand")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return pos
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function ap_airship.move_persons(self)
|
||||||
|
--self._passenger = nil
|
||||||
|
if self.object == nil then return end
|
||||||
|
for i = 5,1,-1
|
||||||
|
do
|
||||||
|
local player = nil
|
||||||
|
if self._passengers[i] then player = minetest.get_player_by_name(self._passengers[i]) end
|
||||||
|
|
||||||
|
if self.driver_name and self._passengers[i] == self.driver_name then
|
||||||
|
--clean driver if it's nil
|
||||||
|
if player == nil then
|
||||||
|
self._passengers[i] = nil
|
||||||
|
self.driver_name = nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if self._passengers[i] ~= nil then
|
||||||
|
--minetest.chat_send_all("pass: "..dump(self._passengers[i]))
|
||||||
|
--the rest of the passengers
|
||||||
|
if player then
|
||||||
|
local result_pos = get_result_pos(self, player, i)
|
||||||
|
local y_rot = 0
|
||||||
|
if result_pos then
|
||||||
|
y_rot = result_pos.y -- the only field that returns a rotation
|
||||||
|
local new_pos = ap_airship.copy_vector(self._passengers_base_pos[i])
|
||||||
|
new_pos.x = new_pos.x - result_pos.z
|
||||||
|
new_pos.z = new_pos.z - result_pos.x
|
||||||
|
--minetest.chat_send_all(dump(new_pos))
|
||||||
|
--local pos_d = ap_airship.boat_lower_deck_map(self._passengers_base_pos[i], new_pos)
|
||||||
|
local pos_d = ap_airship.navigate_deck(self._passengers_base_pos[i], new_pos, player)
|
||||||
|
--minetest.chat_send_all(dump(height))
|
||||||
|
self._passengers_base_pos[i] = ap_airship.copy_vector(pos_d)
|
||||||
|
self._passengers_base[i]:set_attach(self.object,'',self._passengers_base_pos[i],{x=0,y=0,z=0})
|
||||||
|
end
|
||||||
|
--minetest.chat_send_all(dump(self._passengers_base_pos[i]))
|
||||||
|
player:set_attach(self._passengers_base[i], "", {x = 0, y = 0, z = 0}, {x = 0, y = y_rot, z = 0})
|
||||||
|
else
|
||||||
|
--self._passengers[i] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|