Camas/mods/parachute/init.lua

195 lines
5.4 KiB
Lua
Raw Normal View History

2015-10-26 20:50:02 +01:00
--
-- Parachute mod
2019-08-28 17:47:30 +02:00
-- By webdesigner97 (license of original mod: WTFPL)
2015-10-26 20:50:02 +01:00
-- Tweaked by Kaadmy, for Pixture
--
2019-08-28 17:31:41 +02:00
local S = minetest.get_translator("parachute")
2019-08-29 14:42:50 +02:00
local function air_physics(v)
2015-10-26 20:50:02 +01:00
local m = 80 -- Weight of player, kg
local g = -9.81 -- Earth Acceleration, m/s^2
local cw = 1.25 -- Drag coefficient
2015-10-26 20:50:02 +01:00
local rho = 1.2 -- Density of air (on ground, not accurate), kg/m^3
local A = 25 -- Surface of the parachute, m^2
return ((m * g + 0.5 * cw * rho * A * v * v) / m)
end
minetest.register_craftitem(
2015-10-26 20:50:02 +01:00
"parachute:parachute", {
2019-08-28 17:31:41 +02:00
description = S("Parachute"),
2019-12-05 10:30:46 +01:00
_tt_help = S("Lets you glide safely to the ground when falling"),
2015-10-26 20:50:02 +01:00
inventory_image = "parachute_inventory.png",
wield_image = "parachute_inventory.png",
2015-10-31 22:56:51 +01:00
stack_max = 1,
2019-09-15 12:55:39 +02:00
on_activate = function(self)
self.object:set_armor_groups({immortal=1})
end,
2015-10-26 20:50:02 +01:00
on_use = function(itemstack, player, pointed_thing)
local name = player:get_player_name()
local pos = player:get_pos()
2015-10-26 20:50:02 +01:00
local on = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z})
2015-10-26 20:50:02 +01:00
if default.player_attached[name] then
return
end
if on.name == "air" then
-- Spawn parachute
pos.y = pos.y + 3
2015-10-26 20:50:02 +01:00
local ent = minetest.add_entity(pos, "parachute:entity")
2021-08-08 13:42:27 +02:00
minetest.sound_play({name="parachute_open", pos=pos}, {gain=0.5}, true)
2015-10-26 20:50:02 +01:00
ent:set_velocity(
{
x = 0,
2021-02-24 03:22:05 +01:00
y = math.min(0, player:get_velocity().y),
z = 0
})
2015-10-26 20:50:02 +01:00
2021-08-08 13:42:52 +02:00
player:set_attach(ent, "", {x = 0, y = -8, z = 0}, {x = 0, y = 0, z = 0}, true)
2015-10-26 20:50:02 +01:00
ent:set_yaw(player:get_look_horizontal())
ent = ent:get_luaentity()
ent.attached = name
2015-10-26 20:50:02 +01:00
default.player_attached[player:get_player_name()] = true
if not minetest.settings:get_bool("creative_mode") then
itemstack:take_item()
end
return itemstack
else
minetest.chat_send_player(
player:get_player_name(),
2019-08-29 23:24:35 +02:00
minetest.colorize("#FFFF00", S("Cannot open parachute on ground!")))
end
end
})
2015-10-26 20:50:02 +01:00
minetest.register_entity(
2015-10-26 20:50:02 +01:00
"parachute:entity",
{
visual = "mesh",
mesh = "parachute.b3d",
textures = {"parachute_mesh.png"},
2019-08-31 15:23:39 +02:00
physical = false,
pointable = false,
2015-10-26 20:50:02 +01:00
automatic_face_movement_dir = -90,
2019-09-22 04:20:40 +02:00
2015-10-26 20:50:02 +01:00
attached = nil,
2019-09-22 04:20:40 +02:00
start_y = nil,
on_activate = function(self, staticdata, dtime_s)
if dtime_s == 0 then
local pos = self.object:get_pos()
self.start_y = pos.y
end
end,
2015-10-26 20:50:02 +01:00
on_step = function(self, dtime)
local pos = self.object:get_pos()
local under = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z})
2015-11-18 01:53:09 +01:00
if self.attached ~= nil then
local player = minetest.get_player_by_name(self.attached)
local vel = self.object:get_velocity()
2015-10-26 20:50:02 +01:00
local accel = {x = 0, y = 0, z = 0}
2015-10-26 20:50:02 +01:00
local lookyaw = math.pi - player:get_look_horizontal()
if lookyaw < 0 then
lookyaw = lookyaw + (math.pi * 2)
end
if lookyaw >= (math.pi * 2) then
lookyaw = lookyaw - (math.pi * 2)
end
-- self.object:set_yaw(lookyaw)
2015-10-26 20:50:02 +01:00
local s = math.sin(lookyaw)
local c = math.cos(lookyaw)
2015-10-26 20:50:02 +01:00
local sr = math.sin(lookyaw - (math.pi / 2))
local cr = math.cos(lookyaw - (math.pi / 2))
2015-10-26 20:50:02 +01:00
local controls = player:get_player_control()
2015-10-26 20:50:02 +01:00
local speed = 4.0
2015-10-26 20:50:02 +01:00
if controls.down then
accel.x = s * speed
accel.z = c * speed
elseif controls.up then
accel.x = s * -speed
accel.z = c * -speed
end
2015-10-26 20:50:02 +01:00
if controls.right then
accel.x = sr * speed
accel.z = cr * speed
elseif controls.left then
accel.x = sr * -speed
accel.z = cr * -speed
end
2015-10-26 20:50:02 +01:00
accel.y = accel.y + air_physics(vel.y) * 0.25
2015-10-26 20:50:02 +01:00
self.object:set_acceleration(accel)
2015-11-18 01:53:09 +01:00
if under.name ~= "air" then
default.player_attached[self.attached] = false
end
end
2015-10-26 20:50:02 +01:00
if under.name ~= "air" then
if self.attached ~= nil then
default.player_attached[self.attached] = false
2019-09-22 04:20:40 +02:00
local player = minetest.get_player_by_name(self.attached)
if player and self.start_y ~= nil then
if self.start_y - self.object:get_pos().y > 100 then
achievements.trigger_achievement(player, "sky_diver")
end
end
self.object:set_detach()
end
2021-08-08 13:42:27 +02:00
minetest.sound_play({name="parachute_close", pos=self.object:get_pos()}, {gain=0.5}, true)
self.object:remove()
end
end
})
2015-10-26 20:50:02 +01:00
-- Crafting
crafting.register_craft(
2015-10-26 20:50:02 +01:00
{
output = "parachute:parachute",
items = {
"group:fuzzy 3",
"default:rope 4",
"default:stick 6",
2015-10-26 20:50:02 +01:00
}
})
2015-10-26 20:50:02 +01:00
-- Achievements
achievements.register_achievement(
"sky_diver",
{
2019-08-28 20:49:04 +02:00
title = S("Skydiver"),
2019-09-22 04:20:40 +02:00
description = S("Descend over 100 blocks with a parachute."),
times = 1,
})
default.log("mod:parachute", "loaded")