12 Commits

Author SHA1 Message Date
86c7d34d50 add area FLAK for priv and xp protected areas 2024-04-18 12:08:33 +02:00
8fc1f596d2 Preserve colour on repair by crafting (#15) 2024-04-13 19:18:52 +02:00
2c708abd88 fix pattern to match dye name with underscores
fixes #12
2023-08-06 00:49:16 +10:00
f4a297eb30 new screenshot 2023-08-05 16:15:26 +10:00
c2f339c0a4 Hangglider rewrite and improvements (#11)
* hangglider rewrite

* correct job name and use faster luacheck action

* more powerful airbrake and less antigravity

* optimize textures

* Update .luacheckrc

* update item texture to match actual appearance

* up to 256 colors of glider with only one recipe

* fix mtg dye colors not working

* almost forgot to add a readme

* export ignore

* Update mod.conf

* Update README.md
2023-08-03 08:33:36 +02:00
6f837e9e44 Revert "fix fly upwards" workaround (#10) 2023-08-01 17:59:11 +10:00
cd48ef801f Fix mixed spaces+tabs 2023-03-27 15:34:03 +13:00
e923729c9c Make areas warning time configurable (#8) 2023-03-26 22:29:18 -04:00
fd357093e5 fix fly upwards (#7) 2023-03-24 14:55:35 +01:00
3c2618437a [WIP] cleanup, remove old 0.4 code (#6) 2023-01-06 21:50:44 +01:00
cd67eb2d19 fixes #1 (#5)
* partially fixes #1

* remove support for "minetestmd" and "wardzones"
2022-07-04 21:48:01 +02:00
bbde71805a Replace deprecated functions (#4)
* Replace deprecated functions

* add min_minetest_version
2022-06-18 21:15:23 +02:00
18 changed files with 425 additions and 359 deletions

5
.gitattributes vendored Normal file
View File

@ -0,0 +1,5 @@
# Auto detect text files and perform LF normalization
* text=auto
# Exclusions for release export
.* export-ignore

View File

@ -1,13 +1,10 @@
name: luacheck
on: [push, pull_request]
jobs:
build:
luacheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: apt
run: sudo apt-get install -y luarocks
- name: luacheck install
run: luarocks install --local luacheck
- name: luacheck run
run: $HOME/.luarocks/bin/luacheck ./
- name: Checkout
uses: actions/checkout@master
- name: Luacheck
uses: lunarmodules/luacheck@master

View File

@ -1,15 +1,13 @@
globals = {
"hangglider",
"areas"
"areas",
}
read_globals = {
-- Minetest
"minetest",
"vector", "ItemStack",
-- Mod deps
"wardzones",
"minetestd",
"player_monoids"
"player_monoids",
"priv_protector",
"unifieddyes",
"xp_redo",
}

33
README.md Normal file
View File

@ -0,0 +1,33 @@
# Hang Glider [hangglider]
[![luacheck](https://github.com/mt-mods/hangglider/workflows/luacheck/badge.svg)](https://github.com/mt-mods/hangglider/actions)
[![ContentDB](https://content.minetest.net/packages/mt-mods/hangglider/shields/downloads/)](https://content.minetest.net/packages/mt-mods/hangglider/)
Adds a functional hang glider for exploring. Also works as a parachute to save yourself when falling.
Rewritten and improved fork of https://notabug.org/Piezo_/minetest-hangglider.
![](screenshot.png?raw=true)
## Usage
To deploy the hang glider, hold the item in your hand and use it (left-click). The same action also closes the hang glider when it's deployed.
While deployed you can glide around just like walking in the air. Your decent will be slowed until you land on a safe node, which can be any solid node, or a safe liquid like water. Upon landing the hang glider will automatically close.
## Coloring
You can color the hang glider by crafting it with any dye. Also supports all `unifieddyes` colors.
Note that the color will only be visible on the item if you are using Minetest 5.8.0 or above.
## Repairing
The hang glider will wear out every time you use it. The hang glider can be repaired by crafting it with wool or paper, or any other method used to repair tools.
## Area Flak
If the `areas` mod is installed, airspace restrictions can be added to areas using the `/area_flak` command.
When using a hang glider in an area with flak enabled, you will get shot down a few seconds after entering the area, this reduces your HP to 1 and destroys your hang glider.

120
crafts.lua Normal file
View File

@ -0,0 +1,120 @@
local has_unifieddyes = minetest.get_modpath("unifieddyes")
local dye_colors = {
white = "ffffff",
grey = "888888",
dark_grey = "444444",
black = "111111",
violet = "8000ff",
blue = "0000ff",
cyan = "00ffff",
dark_green = "005900",
green = "00ff00",
yellow = "ffff00",
brown = "592c00",
orange = "ff7f00",
red = "ff0000",
magenta = "ff00ff",
pink = "ff7f9f",
}
local function get_dye_color(name)
local color
if has_unifieddyes then
color = unifieddyes.get_color_from_dye_name(name)
end
if not color then
color = string.match(name, "^dye:(.+)$")
if color then
color = dye_colors[color]
end
end
return color
end
local function get_color_name(name)
name = string.gsub(name, "^dye:", "")
name = string.gsub(name, "_", " ")
name = string.gsub(name, "(%l)(%w*)", function(a, b) return string.upper(a)..b end)
return name
end
local function get_color_name_from_color(color)
for name, color_hex in pairs(dye_colors) do
if color == color_hex then
return name
end
end
end
-- This recipe is just a placeholder
do
local item = ItemStack("hangglider:hangglider")
item:get_meta():set_string("description", "Colored Glider")
minetest.register_craft({
output = item:to_string(),
recipe = {"hangglider:hangglider", "group:dye"},
type = "shapeless",
})
end
-- This is what actually creates the colored hangglider
minetest.register_on_craft(function(crafted_item, _, old_craft_grid)
if crafted_item:get_name() ~= "hangglider:hangglider" then
return
end
local wear, color, color_name
for _,stack in ipairs(old_craft_grid) do
local name = stack:get_name()
if name == "hangglider:hangglider" then
wear = stack:get_wear()
color = stack:get_meta():get("hangglider_color")
color_name = get_color_name_from_color(color)
elseif minetest.get_item_group(name, "dye") ~= 0 then
color = get_dye_color(name)
color_name = get_color_name(name)
elseif "wool:white" == stack:get_name()
or "default:paper" == stack:get_name()
then
wear = 0
end
end
if wear and color and color_name then
if color == "ffffff" then
return ItemStack({name = "hangglider:hangglider", wear = wear})
end
local meta = crafted_item:get_meta()
meta:set_string("description", color_name.." Glider")
meta:set_string("inventory_image", "hangglider_item.png^(hangglider_color.png^[multiply:#"..color..")")
meta:set_string("hangglider_color", color)
crafted_item:set_wear(wear)
return crafted_item
end
end)
-- Repairing
minetest.register_craft({
output = "hangglider:hangglider",
recipe = {
{"default:paper", "default:paper", "default:paper"},
{"default:paper", "hangglider:hangglider", "default:paper"},
{"default:paper", "default:paper", "default:paper"},
},
})
minetest.register_craft({
output = "hangglider:hangglider",
recipe = {
{"hangglider:hangglider", "wool:white"},
},
})
-- Main craft
minetest.register_craft({
output = "hangglider:hangglider",
recipe = {
{"wool:white", "wool:white", "wool:white"},
{"default:stick", "", "default:stick"},
{"", "default:stick", ""},
}
})

View File

@ -1,5 +0,0 @@
default
wool
minetest_systemd?
areas?
player_monoids?

581
init.lua
View File

@ -1,111 +1,28 @@
-- Hangglider mod for Minetest
-- Original code by Piezo_ (orderofthefourthwall@gmail.com)
-- 2018-11-14
-- Modifications by David G (kestral246@gmail.com)
-- 2018-11-24
-- For Minetest 5.x, glider's set_attach needs to be offset by 1 node
-- Switch to alternate commented line below with correct offset.
-- Additional tuning of parameters.
-- Commented out debug hud display code, prefixed with "--debug:".
local has_player_monoids = minetest.get_modpath("player_monoids")
local has_areas = minetest.get_modpath("areas")
local has_priv_protector = minetest.get_modpath("priv_protector")
and minetest.global_exists("priv_protector")
and priv_protector.get_area_priv
-- older versions of priv_protector and xp_redo don't have
-- the global and/or the functions yet
local has_xp_redo = minetest.get_modpath("xp_redo")
and minetest.global_exists("xp_redo")
and xp_redo.get_area_xp_limits and xp_redo.get_xp
-- 2018-11-22
-- Give visual indication that hangglider is equiped.
-- Display simple overlay with blurred struts when equiped.
-- Issue: don't know how to disable overlay in third person view.
-- Also Unequip hangglider when landing on water.
-- Attempt to linearize parabolic flight path.
-- Start gravity stronger, but gradually reduce it as descent velocity increases.
-- Don't use airstopper when equipped from the ground (descent velocity is low).
-- Slightly increase flight speed to 1.25.
-- Unequip/equip cycling mid-flight should not fly farther than continuous flight.
-- When equipping mid-air (descent velocity higher), use airstopper but increase descent slope afterwards.
-- Create airbreak flag so all equips mid-flight use faster descent.
-- Reset airbreak flag only when land (canExist goes false).
-- Issue: it wouldn't reset if land in water, use fly, and launch from air, before I added test for water,
-- not sure if there are other such cases.
-- Temporarily add hud debug display to show descent velocity, gravity override, and airbreak flag.
-- Still in process of tuning all the parameters.
local enable_hud_overlay = minetest.settings:get_bool("hangglider.enable_hud_overlay", true)
local enable_flak = has_areas and minetest.settings:get_bool("hangglider.enable_flak", true)
local flak_warning_time = tonumber(minetest.settings:get("hangglider.flak_warning_time")) or 2
local hangglider_uses = tonumber(minetest.settings:get("hangglider.uses")) or 250
local flak_warning = "You have entered restricted airspace!\n"..
"You will be shot down in "..flak_warning_time.." seconds by anti-aircraft guns!"
-- Modifications by Piezo_
-- 2018-11-25
-- hud overlay and debug can be enabled/disabled
-- Added blender-rendered overlay for struts using the actual model.
-- Reduced airbreak penalty severity
-- gave glider limited durability.
-- Improved gravity adjustment function.
-- Changed airbreaking process
-- Removed airbreak penalty, as any 'advantage' seems minimal after new adjustments
-- Removed airbreak until minetest devs are smart enough to implement better serverside players.
-- Simplified liquid check.
local hanggliding_players = {}
local hud_overlay_ids = {}
-- Modifications by gpcf
-- 2018-12-09
-- get shot down while flying over protected areas marked as no-fly-zones (flak, from German Flugabwehrkanone)
-- set these areas with the /area_flak command
-- Modifications by SpaghettiToastBook
-- 2018-12-29
-- Physics overrides use player_monoids mod if available
-- Modifications by SwissalpS
-- 2022-05-16
-- Add Z-index to theoretically be behind hotbar and practically behind other HUDs
local HUD_Overlay = true --show glider struts as overlay on HUD
local debug = false --show debug info in top-center of hud
local moveModelUp = false
if tonumber(string.sub(minetest.get_version().string, 1, 1)) and
tonumber(string.sub(minetest.get_version().string, 1, 1)) > 4 then
moveModelUp = true
end
hangglider = {} --Make this global, so other mods can tell if hangglider exists.
hangglider.use = {}
if HUD_Overlay then
hangglider.id = {} -- hud id for displaying overlay with struts
end
if debug then hangglider.debug = {} end -- hud id for debug data
--hangglider.airbreak = {} -- true if falling fast when equip
--[[
minetest.register_entity("hangglider:airstopper", { --A one-instant entity that catches the player and stops them.
is_visible = false,
physical = false,
immortal = true,
attach = nil,
on_step = function(self, _)
local canExist = false
if self.attach then
local player = self.attach
if player:is_player() then
local pname = player:get_player_name()
canExist = true
if player:get_player_velocity().y < 0.5 and player:get_player_velocity().y > -0.5 then
--Let go when the player actually stops, as that's the whole point.
if hangglider.use[pname] then
if moveModelUp then
minetest.add_entity(player:get_pos(), "hangglider:glider"):set_attach(player, "", {x=0,y=10,z=0}, {x=0,y=0,z=0})
else
minetest.add_entity(player:get_pos(), "hangglider:glider"):set_attach(player, "", {x=0,y=0,z=0}, {x=0,y=0,z=0})
end
end
canExist = false
end
end
if not canExist then
player:set_detach()
end
end
if not canExist then
self.object:remove()
end
end
})]]
if minetest.global_exists("areas") then
hangglider.flak = true
-- chat command definition essentially copied from areas mod.
minetest.register_chatcommand("area_flak",{
if enable_flak then
minetest.register_chatcommand("area_flak", {
params = "<ID>",
description = "Toggle airspace restrictions for area <ID>",
func = function(name, param)
@ -113,282 +30,268 @@ if minetest.global_exists("areas") then
if not id then
return false, "Invalid usage, see /help area_flak."
end
if not areas:isAreaOwner(id, name) then
return false, "Area "..id.." does not exist"
.." or is not owned by you."
return false, "Area "..id.." does not exist or is not owned by you."
end
local open = not areas.areas[id].flak
-- Save false as nil to avoid inflating the DB.
areas.areas[id].flak = open or nil
areas:save()
return true, ("Area's airspace %s."):format(open and "closed" or "opened")
return true, "Area "..id.." airspace "..(open and "closed" or "opened")
end
})
end
if minetest.global_exists("minetestd") and minetestd.services.physicsctl.enabled then
minetestd.physicsctl.register_physics_effect("hangglider",
function(player) -- check
return hangglider.use[player:get_player_name()]
end,
function(phys, player) -- blend
local vel_y = player:get_player_velocity().y
phys.gravity = phys.gravity*((vel_y + 3)/20)
if vel_y < 0 and vel_y > -3 then
phys.speed = (math.abs(vel_y/2) + 0.75)
elseif vel_y <= -3 then --Cap our gliding movement speed.
phys.speed = 2.25
end
phys.jump = 0
end,
7 -- effect order
)
local function set_hud_overlay(player, name, image)
if not enable_hud_overlay then
return
end
if not hud_overlay_ids[name] then
hud_overlay_ids[name] = player:hud_add({
hud_elem_type = "image",
text = image,
position = {x = 0, y = 0},
scale = {x = -100, y = -100},
alignment = {x = 1, y = 1},
offset = {x = 0, y = 0},
z_index = -150
})
else
player:hud_change(hud_overlay_ids[name], "text", image)
end
end
hangglider.can_fly = function (pname, pos)
-- Checks if the player will get shot down at the position
if wardzones then
local zone = wardzones.getZone(pos)
if zone then
return (minetest.check_player_privs(pname, {protection_bypass=true}) or
wardzones.checkPlayerZoneAccess(pname, zone) or not zone["data"]["no_fly"])
local function set_physics_overrides(player, overrides)
if has_player_monoids then
for name, value in pairs(overrides) do
player_monoids[name]:add_change(player, value, "hangglider:glider")
end
else
player:set_physics_override(overrides)
end
end
local function remove_physics_overrides(player)
for _, name in pairs({"jump", "speed", "gravity"}) do
if has_player_monoids then
player_monoids[name]:del_change(player, "hangglider:glider")
else
player:set_physics_override({[name] = 1})
end
end
if areas and hangglider.flak then
local flak = false
local owners = {}
for _, area in pairs(areas:getAreasAtPos(pos)) do
if area.flak then
flak = true
end
local function can_fly(pos, name, player_xp, player_privs)
if not enable_flak then
return true
end
local flak, open = false, false
local priv_excemption, xp_limit = false, false
local xp_area, priv_area
local owners = {}
for id, area in pairs(areas:getAreasAtPos(pos)) do
-- open areas are friendly airspace(?)
if area.open then
open = true
end
if player_privs then
priv_area = priv_protector.get_area_priv(id)
if player_privs[priv_area] then
priv_excemption = true
end
owners[area.owner] = true
end
if flak and not owners[pname] then
return false
if player_xp then
xp_area = xp_redo.get_area_xp_limits(id)
if xp_area then
if (xp_area.min and player_xp < xp_area.min)
or (xp_area.max and player_xp > xp_area.max)
then
xp_limit = true
end
end
end
if area.flak then
flak = true
end
owners[area.owner] = true
end
return true
-- none of the areas has FLAK set -> friendly
-- any of the overlapping areas is open -> friendly
-- owners of overlapping areas -> safe
if not flak or open or owners[name] then
return true
end
-- privilaged players -> safe
if player_privs and priv_excemption then
return true
end
-- xp limits -> unfriendly
if player_xp and not xp_limit then
return true
end
return false
end
hangglider.shot_sound = function (pos)
local function safe_node_below(pos)
local node = minetest.get_node_or_nil(vector.new(pos.x, pos.y - 0.5, pos.z))
if not node then
return false
end
local def = minetest.registered_nodes[node.name]
if def and (def.walkable or (def.liquidtype ~= "none" and def.damage_per_second <= 0)) then
return true
end
return false
end
local function shoot_flak_sound(pos)
minetest.sound_play("hangglider_flak_shot", {
pos = pos,
max_hear_distance = 30,
gain = 10.0,
})
}, true)
end
local physics_attrs = {"jump", "speed", "gravity"}
local function apply_physics_override(player, overrides)
if player_monoids then
for _, attr in pairs(physics_attrs) do
if overrides[attr] then
player_monoids[attr]:add_change(player, overrides[attr], "hangglider:glider")
end
end
else
player:set_physics_override(overrides)
end
local function hangglider_step(self, dtime)
local gliding = false
local player = self.object:get_attach("parent")
if player then
local pos = player:get_pos()
local name = player:get_player_name()
if hanggliding_players[name] then
if not safe_node_below(pos) then
gliding = true
local vel = player:get_velocity().y
if vel < 0 and vel > -3 then
set_physics_overrides(player, {
speed = math.abs(vel / 2.0) + 1.0,
gravity = (vel + 3) / 20,
})
elseif vel <= -3 then
set_physics_overrides(player, {
speed = 2.5,
gravity = -0.1,
})
if vel < -5 then
-- Extra airbrake when falling too fast
player:add_velocity(vector.new(0, math.min(5, math.abs(vel / 10.0)), 0))
end
else -- vel > 0
set_physics_overrides(player, {
speed = 1.0,
gravity = 0.25,
})
end
end
if not can_fly(pos, name, self.xp, self.privs) then
if not self.flak_timer then
self.flak_timer = 0
shoot_flak_sound(pos)
minetest.chat_send_player(name, flak_warning)
else
self.flak_timer = self.flak_timer + dtime
end
if self.flak_timer > flak_warning_time then
player:set_hp(1, {type = "set_hp", cause = "hangglider:flak"})
player:get_inventory():remove_item("main", ItemStack("hangglider:hangglider"))
shoot_flak_sound(pos)
gliding = false
end
end
if not gliding then
remove_physics_overrides(player)
hanggliding_players[name] = nil
set_hud_overlay(player, name, "blank.png")
end
end
end
if not gliding then
self.object:set_detach()
self.object:remove()
end
end
local function remove_physics_override(player, overrides)
for _, attr in pairs(physics_attrs) do
if overrides[attr] then
if minetest.global_exists("player_monoids") then
player_monoids[attr]:del_change(player, "hangglider:glider")
else
player:set_physics_override({[attr] = 1})
end
end
end
local function hangglider_use(stack, player)
if type(player) ~= "userdata" then
return -- Real players only
end
local pos = player:get_pos()
local name = player:get_player_name()
if not hanggliding_players[name] then
minetest.sound_play("hanggliger_equip", {pos = pos, max_hear_distance = 8, gain = 1.0}, true)
local entity = minetest.add_entity(pos, "hangglider:glider")
if entity then
entity:set_attach(player, "", vector.new(0, 10, 0), vector.new(0, 0, 0))
local color = stack:get_meta():get("hangglider_color")
if color then
entity:set_properties({
textures = {"wool_white.png^[multiply:#"..color, "default_wood.png"}
})
end
set_hud_overlay(player, name, "hangglider_overlay.png")
set_physics_overrides(player, {jump = 0, gravity = 0.25})
local luaentity = entity:get_luaentity()
if has_xp_redo then
luaentity.xp = xp_redo.get_xp(name)
end
if has_priv_protector then
luaentity.privs = minetest.get_player_privs(name)
end
hanggliding_players[name] = true
if hangglider_uses > 0 then
stack:add_wear(65535 / hangglider_uses)
end
return stack
end
else
set_hud_overlay(player, name, "blank.png")
remove_physics_overrides(player)
hanggliding_players[name] = nil
end
end
local step_v
minetest.register_on_dieplayer(function(player)
local name = player:get_player_name()
hanggliding_players[name] = nil
remove_physics_overrides(player)
end)
minetest.register_on_leaveplayer(function(player)
local name = player:get_player_name()
hanggliding_players[name] = nil
hud_overlay_ids[name] = nil
remove_physics_overrides(player)
end)
minetest.register_on_player_hpchange(function(player, hp_change, reason)
local name = player:get_player_name()
if hanggliding_players[name] and reason.type == "fall" then
-- Stop all fall damage when hanggliding
return 0, true
end
return hp_change
end, true)
minetest.register_entity("hangglider:glider", {
visual = "mesh",
visual_size = {x = 12, y = 12},
collisionbox = {0,0,0,0,0,0},
mesh = "glider.obj",
mesh = "hangglider.obj",
immortal = true,
static_save = false,
textures = {"wool_white.png","default_wood.png"},
on_step = function(self, dtime)
local canExist = false
if self.object:get_attach() then
local player = self.object:get_attach("parent")
if player then
local pos = player:getpos()
local pname = player:get_player_name()
if hangglider.use[pname] then
local mrn_name = minetest.registered_nodes[minetest.get_node(vector.new(pos.x, pos.y-0.5, pos.z)).name]
if mrn_name then
if not (mrn_name.walkable or mrn_name.liquidtype ~= "none") then
canExist = true
if not minetestd then
step_v = player:get_player_velocity().y
if step_v < 0 and step_v > -3 then
apply_physics_override(player, {speed=math.abs(step_v/2) + 0.75})
elseif step_v <= -3 then --Cap our gliding movement speed.
apply_physics_override(player, {speed=2.25})
else
remove_physics_override(player, {speed=1})
end
if debug then
player:hud_change(hangglider.debug[pname].id, "text", step_v..', '..
player:get_physics_override().gravity..', '..tostring(hangglider.airbreak[pname]))
end
apply_physics_override(player, {gravity=((step_v + 3)/20)})
end
end
end
end
if not hangglider.can_fly(pname,pos) then
if not self.warned then -- warning shot
self.warned = 0
hangglider.shot_sound(pos)
minetest.chat_send_player(pname, "Protected area! You will be shot down in two seconds by anti-aircraft guns!")
end
self.warned = self.warned + dtime
if self.warned > 2 then -- shoot down
player:set_hp(1)
player:get_inventory():remove_item("main", ItemStack("hangglider:hangglider"))
hangglider.shot_sound(pos)
canExist = false
end
end
if not canExist then
if not minetestd then
remove_physics_override(player, {
gravity=1,
jump = 1,
speed = 1,})
end
hangglider.use[pname] = false
if HUD_Overlay then
player:hud_change(hangglider.id[pname], "text", "blank.png")
end
--hangglider.airbreak[pname] = false
end
end
end
if not canExist then
self.object:set_detach()
self.object:remove()
end
end
textures = {"wool_white.png", "default_wood.png"},
on_step = hangglider_step,
})
minetest.register_on_dieplayer(function(player)
remove_physics_override(player, {
gravity = 1,
jump = 1,
})
hangglider.use[player:get_player_name()] = false
end)
minetest.register_on_joinplayer(function(player)
local pname = player:get_player_name()
remove_physics_override(player, {
gravity = 1,
jump = 1,
})
hangglider.use[pname] = false
if HUD_Overlay then
hangglider.id[pname] = player:hud_add({
hud_elem_type = "image",
text = "blank.png",
position = {x=0, y=0},
scale = {x=-100, y=-100},
alignment = {x=1, y=1},
offset = {x=0, y=0},
z_index = -150
})
end
if debug then
hangglider.debug[pname] = {id = player:hud_add({hud_elem_type = "text",
position = {x=0.5, y=0.1},
text = "-",
number = 0xFF0000}), -- red text
-- ht = {50,50,50},
}
end
--hangglider.airbreak[pname] = false
end)
minetest.register_on_leaveplayer(function(player)
local pname = player:get_player_name()
hangglider.use[pname] = nil
if HUD_Overlay then hangglider.id[pname] = nil end
if debug then hangglider.debug[pname] = nil end
--hangglider.airbreak[pname] = nil
end)
minetest.register_tool("hangglider:hangglider", {
description = "Glider",
inventory_image = "glider_item.png",
stack_max=1,
on_use = function(itemstack, player)
if not player or player.is_fake_player then
-- player does not exist or is created from an automated machine (fake_player)
return
end
local pos = player:get_pos()
local pname = player:get_player_name()
if not hangglider.use[pname] then --Equip
minetest.sound_play("bedsheet", {pos=pos, max_hear_distance = 8, gain = 1.0})
if HUD_Overlay then player:hud_change(hangglider.id[pname], "text", "glider_struts.png") end
local airbreak = false
--[[if vel < -1.5 then -- engage mid-air, falling fast, so stop but ramp velocity more quickly
--hangglider.airbreak[pname] = true
airbreak = true
local stopper = minetest.add_entity(pos, "hangglider:airstopper")
minetest.after(0, function(stopper, player) --"Extreme Measures"
stopper:set_pos(player:get_pos())
stopper:get_luaentity().attach = player
player:set_attach( stopper, "", {x=0,y=0,z=0}, {x=0,y=0,z=0})
end, stopper, player)
end]]
if not airbreak then
if moveModelUp then
minetest.add_entity(pos, "hangglider:glider"):set_attach(player, "", {x=0,y=10,z=0}, {x=0,y=0,z=0})
else
minetest.add_entity(pos, "hangglider:glider"):set_attach(player, "", {x=0,y=0,z=0}, {x=0,y=0,z=0})
end
end
hangglider.use[pname] = true
apply_physics_override(player, {jump = 0})
-- if minetest 0.4.x use this:
-- if minetest 5.x use this:
-- minetest.add_entity(player:get_pos(), "hangglider:glider"):set_attach(player, "", {x=0,y=10,z=0}, {x=0,y=0,z=0})
itemstack:set_wear(itemstack:get_wear() + 255)
return itemstack
elseif hangglider.use[pname] then --Unequip
if HUD_Overlay then player:hud_change(hangglider.id[pname], "text", "default_wood.png^[colorize:#0000:255") end
hangglider.use[pname] = false
end
end,
inventory_image = "hangglider_item.png",
sound = {breaks = "default_tool_breaks"},
on_use = hangglider_use,
})
minetest.register_craft({
type = "shapeless",
output = "hangglider:hangglider",
recipe = {"default:paper", "default:paper", "default:paper",
"default:paper", "hangglider:hangglider", "default:paper",
"default:paper", "default:paper", "default:paper"
},
})
minetest.register_craft({
output = "hangglider:hangglider",
recipe = {
{"wool:white", "wool:white", "wool:white"},
{"default:stick", "", "default:stick"},
{"", "default:stick", ""},
}
})
dofile(minetest.get_modpath("hangglider").."/crafts.lua")

View File

@ -1 +1,5 @@
name = hangglider
description = Adds a functional hang glider for exploring
depends = default, wool, dye
optional_depends = areas, player_monoids, priv_protector, unifieddyes, xp_redo
min_minetest_version = 5.0

0
models/glider.obj → models/hangglider.obj Executable file → Normal file
View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 346 KiB

11
settingtypes.txt Normal file
View File

@ -0,0 +1,11 @@
# The number of times the hangglider can be used before breaking. Set to 0 for infinite uses.
hangglider.uses (Hangglider uses) int 250
# If true, an image of the hangglider struts is shown on the hud when gliding.
hangglider.enable_hud_overlay (Enable overlay) bool true
# If enabled, and the `areas` mod is installed, enables airspace restrictions to be added to areas.
hangglider.enable_flak (Enable flak) bool true
# Time in seconds before hanggliders get shot down when flying in restricted airspace
hangglider.flak_warning_time (Flak warning time) float 2

Binary file not shown.

BIN
sounds/hanggliger_equip.ogg Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB