14 Commits

Author SHA1 Message Date
6c23c135dc Improve interoperability without player_monoids and pova (#24)
* Import noobdigital87's changes

Co-authored-by: noobdigital87 <noobdigital87@gmail.com>

* Fix hud type; remove useless code; style

---------

Co-authored-by: noobdigital87 <noobdigital87@gmail.com>
2025-07-11 08:53:07 +02:00
f970874855 Cleanup HUD code (#21) 2025-05-24 17:49:24 -04:00
071fe93cf5 add pova support (#20)
* Update mod.conf

add pova optional dependency

* Update init.lua

add support for pova

* Update .luacheckrc

---------

Co-authored-by: Luke aka SwissalpS <161979+SwissalpS@users.noreply.github.com>
2025-01-18 17:42:39 +01:00
49a878aa03 Optimize remove_physics_overrides() a bit (#19) 2024-04-28 21:26:12 +02:00
3e304e3e5d Add translation support and ca, de and es translations (#18) 2024-04-25 14:23:20 +10: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
21 changed files with 579 additions and 331 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 name: luacheck
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
build: luacheck:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@master - name: Checkout
- name: apt uses: actions/checkout@master
run: sudo apt-get install -y luarocks - name: Luacheck
- name: luacheck install uses: lunarmodules/luacheck@master
run: luarocks install --local luacheck
- name: luacheck run
run: $HOME/.luarocks/bin/luacheck ./

View File

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

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.

138
crafts.lua Normal file
View File

@ -0,0 +1,138 @@
local S = hangglider.translator
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 translated_colors = {
white = S("White"),
grey = S("Grey"),
dark_grey = S("Dark_grey"),
black = S("Black"),
violet = S("Violet"),
blue = S("Blue"),
cyan = S("Cyan"),
dark_green = S("Dark_green"),
green = S("Green"),
yellow = S("Yellow"),
brown = S("Brown"),
orange = S("Orange"),
red = S("Red"),
magenta = S("Magenta"),
pink = S("Pink"),
}
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:", "")
return translated_colors[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 translated_colors[name]
end
end
end
-- This recipe is just a placeholder
do
local item = ItemStack("hangglider:hangglider")
item:get_meta():set_string("description", S("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", S("@1 Glider", color_name))
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", ""},
}
})

581
init.lua
View File

@ -1,361 +1,314 @@
-- Hangglider mod for Minetest
-- Original code by Piezo_ (orderofthefourthwall@gmail.com)
-- 2018-11-14
-- Modifications by David G (kestral246@gmail.com) hangglider = {
-- 2018-11-24 translator = minetest.get_translator('hangglider'),
-- For Minetest 5.x, glider's set_attach needs to be offset by 1 node }
-- Switch to alternate commented line below with correct offset. local S = hangglider.translator
-- Additional tuning of parameters.
-- Commented out debug hud display code, prefixed with "--debug:".
-- 2018-11-22 local has_player_monoids = minetest.get_modpath("player_monoids")
-- Give visual indication that hangglider is equiped. local has_pova = minetest.get_modpath("pova")
-- Display simple overlay with blurred struts when equiped. local has_areas = minetest.get_modpath("areas")
-- Issue: don't know how to disable overlay in third person view.
-- Also Unequip hangglider when landing on water. local enable_hud_overlay = minetest.settings:get_bool("hangglider.enable_hud_overlay", true)
-- Attempt to linearize parabolic flight path. local enable_flak = has_areas and minetest.settings:get_bool("hangglider.enable_flak", true)
-- Start gravity stronger, but gradually reduce it as descent velocity increases. local flak_warning_time = tonumber(minetest.settings:get("hangglider.flak_warning_time")) or 2
-- Don't use airstopper when equipped from the ground (descent velocity is low). local hangglider_uses = tonumber(minetest.settings:get("hangglider.uses")) or 250
-- Slightly increase flight speed to 1.25.
-- Unequip/equip cycling mid-flight should not fly farther than continuous flight. local flak_warning = S("You have entered restricted airspace!@n"
-- When equipping mid-air (descent velocity higher), use airstopper but increase descent slope afterwards. .. "You will be shot down in @1 seconds by anti-aircraft guns!",
-- Create airbreak flag so all equips mid-flight use faster descent. flak_warning_time)
-- 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, local hanggliding_players = {}
-- not sure if there are other such cases. local physics_overrides = {}
-- Temporarily add hud debug display to show descent velocity, gravity override, and airbreak flag. local hud_overlay_ids = {}
-- Still in process of tuning all the parameters.
-- Modifications by Piezo_ if enable_flak then
-- 2018-11-25 minetest.register_chatcommand("area_flak", {
-- hud overlay and debug can be enabled/disabled params = S("<ID>"),
-- Added blender-rendered overlay for struts using the actual model. description = S("Toggle airspace restrictions for area <ID>."),
-- 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.
-- 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",{
params = "<ID>",
description = "Toggle airspace restrictions for area <ID>",
func = function(name, param) func = function(name, param)
local id = tonumber(param) local id = tonumber(param)
if not id then if not id then
return false, "Invalid usage, see /help area_flak." return false, S("Invalid usage, see /help area_flak.")
end end
if not areas:isAreaOwner(id, name) then if not areas:isAreaOwner(id, name) then
return false, "Area "..id.." does not exist" return false, S("Area @1 does not exist or is not owned by you.", id)
.." or is not owned by you."
end end
local open = not areas.areas[id].flak local open = not areas.areas[id].flak
-- Save false as nil to avoid inflating the DB. -- Save false as nil to avoid inflating the DB.
areas.areas[id].flak = open or nil areas.areas[id].flak = open or nil
areas:save() areas:save()
return true, ("Area's airspace %s."):format(open and "closed" or "opened") return true, S("Area @1 airspace is @2.", id,
open and S("closed") or S("opened"))
end end
}) })
end end
hangglider.can_fly = function (pname, pos) function hangglider.is_gliding(player)
-- Checks if the player will get shot down at the position if not player then
if areas and hangglider.flak then return false
local flak = false end
local owners = {} return hanggliding_players[player:get_player_name()]
for _, area in pairs(areas:getAreasAtPos(pos)) do end
if area.flak then
flak = true local function set_hud_overlay(player, name, show)
end if not enable_hud_overlay then
owners[area.owner] = true return
end
if not hud_overlay_ids[name] and show == true then
hud_overlay_ids[name] = player:hud_add({
[minetest.features.hud_def_type_field and "type" or "hud_elem_type"] = "image",
text = "hangglider_overlay.png",
position = {x = 0, y = 0},
scale = {x = -100, y = -100},
alignment = {x = 1, y = 1},
offset = {x = 0, y = 0},
z_index = -150
})
elseif hud_overlay_ids[name] and show == false then
player:hud_remove(hud_overlay_ids[name])
hud_overlay_ids[name] = nil
end
end
local function set_physics_overrides(player, overrides)
local player_name = player:get_player_name()
if has_player_monoids then
for name, value in pairs(overrides) do
player_monoids[name]:add_change(player, value, "hangglider:glider")
end end
if flak and not owners[pname] then elseif has_pova then
return false pova.add_override(player_name, "hangglider:glider",
{jump = 0, speed = overrides.speed, gravity = overrides.gravity})
pova.do_override(player)
else
local def = player:get_physics_override()
if not physics_overrides[player_name] then
physics_overrides[player_name] = {
physics = {
speed = def.speed,
jump = def.jump,
gravity = def.gravity,
},
deltas = {speed = 0, jump = 0, gravity = 0},
}
end end
-- Compute the new delta to apply (relative to current physics)
local delta = {
speed = (overrides.speed or def.speed) - def.speed,
jump = (overrides.jump or def.jump) - def.jump,
gravity = (overrides.gravity or def.gravity) - def.gravity,
}
-- Track the sum of all deltas for this session.
physics_overrides[player_name].deltas.speed = physics_overrides[player_name].deltas.speed + delta.speed
physics_overrides[player_name].deltas.jump = physics_overrides[player_name].deltas.jump + delta.jump
physics_overrides[player_name].deltas.gravity = physics_overrides[player_name].deltas.gravity + delta.gravity
-- Apply new delta on top of current physics
player:set_physics_override({
speed = def.speed + delta.speed,
jump = def.jump + delta.jump,
gravity = def.gravity + delta.gravity,
})
end
end
local function remove_physics_overrides(player)
local player_name = player:get_player_name()
if has_player_monoids then
for _, name in pairs({"jump", "speed", "gravity"}) do
player_monoids[name]:del_change(player, "hangglider:glider")
end
elseif has_pova then
pova.del_override(player_name, "hangglider:glider")
pova.do_override(player)
else
local def = player:get_physics_override()
if physics_overrides[player_name]
and physics_overrides[player_name].physics
and physics_overrides[player_name].deltas then
-- Subtract total delta from current values
player:set_physics_override({
speed = def.speed - physics_overrides[player_name].deltas.speed,
jump = def.jump - physics_overrides[player_name].deltas.jump,
gravity = def.gravity - physics_overrides[player_name].deltas.gravity,
})
physics_overrides[player_name] = nil
else
player:set_physics_override({speed = 1, jump = 1, gravity = 1})
end
end
end
local function can_fly(pos, name)
if not enable_flak then
return true
end
local flak = false
local owners = {}
for _, area in pairs(areas:getAreasAtPos(pos)) do
if area.flak then
flak = true
end
owners[area.owner] = true
end
if flak and not owners[name] then
return false
end end
return true return true
end 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", { minetest.sound_play("hangglider_flak_shot", {
pos = pos, pos = pos,
max_hear_distance = 30, max_hear_distance = 30,
gain = 10.0, gain = 10.0,
}) }, true)
end end
local physics_attrs = {"jump", "speed", "gravity"} local function hangglider_step(self, dtime)
local function apply_physics_override(player, overrides) local gliding = false
if minetest.get_modpath("player_monoids") then local player = self.object:get_attach("parent")
for _, attr in pairs(physics_attrs) do if player then
if overrides[attr] then local pos = player:get_pos()
player_monoids[attr]:add_change(player, overrides[attr], "hangglider:glider") local name = player:get_player_name()
end if hanggliding_players[name] then
end if not safe_node_below(pos) then
else gliding = true
player:set_physics_override(overrides) local vel = player:get_velocity().y
end if vel < 0 and vel > -3 then
end set_physics_overrides(player, {
speed = math.abs(vel / 2.0) + 1.0,
local function remove_physics_override(player, overrides) gravity = (vel + 3) / 20,
for _, attr in pairs(physics_attrs) do })
if overrides[attr] then elseif vel <= -3 then
if minetest.global_exists("player_monoids") then set_physics_overrides(player, {
player_monoids[attr]:del_change(player, "hangglider:glider") speed = 2.5,
else gravity = -0.1,
player:set_physics_override({[attr] = 1}) })
end if vel < -5 then
end -- Extra airbrake when falling too fast
end player:add_velocity(vector.new(0, math.min(5, math.abs(vel / 10.0)), 0))
end
local step_v
minetest.register_entity("hangglider:glider", {
visual = "mesh",
visual_size = {x = 12, y = 12},
collisionbox = {0,0,0,0,0,0},
mesh = "glider.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:get_pos()
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
step_v = player:get_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 else -- vel > 0
if not hangglider.can_fly(pname,pos) then set_physics_overrides(player, {
if not self.warned then -- warning shot speed = 1.0,
self.warned = 0 gravity = 0.25,
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
remove_physics_override(player, { gravity=1, jump = 1, speed = 1,})
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 end
end if not can_fly(pos, name) then
if not canExist then if not self.flak_timer then
self.object:set_detach() self.flak_timer = 0
self.object:remove() 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, false)
end
end end
end end
}) if not gliding then
self.object:set_detach()
self.object:remove()
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, true)
set_physics_overrides(player, {jump = 0, gravity = 0.25})
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, false)
remove_physics_overrides(player)
hanggliding_players[name] = nil
end
end
minetest.register_on_dieplayer(function(player) minetest.register_on_dieplayer(function(player)
remove_physics_override(player, { local name = player:get_player_name()
gravity = 1, hanggliding_players[name] = nil
jump = 1, remove_physics_overrides(player)
})
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) end)
minetest.register_on_leaveplayer(function(player) minetest.register_on_leaveplayer(function(player)
local pname = player:get_player_name() local name = player:get_player_name()
hangglider.use[pname] = nil hanggliding_players[name] = nil
if HUD_Overlay then hangglider.id[pname] = nil end hud_overlay_ids[name] = nil
if debug then hangglider.debug[pname] = nil end remove_physics_overrides(player)
--hangglider.airbreak[pname] = nil
end) end)
minetest.register_tool("hangglider:hangglider", { minetest.register_on_player_hpchange(function(player, hp_change, reason)
description = "Glider", local name = player:get_player_name()
inventory_image = "glider_item.png", if hanggliding_players[name] and reason.type == "fall" then
stack_max=1, -- Stop all fall damage when hanggliding
on_use = function(itemstack, player) return 0, true
if not player or player.is_fake_player then end
-- player does not exist or is created from an automated machine (fake_player) return hp_change
return end, true)
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.register_entity("hangglider:glider", {
-- minetest.add_entity(player:get_pos(), "hangglider:glider"):set_attach(player, "", {x=0,y=10,z=0}, {x=0,y=0,z=0}) initial_properties = {
itemstack:set_wear(itemstack:get_wear() + 255) visual = "mesh",
return itemstack visual_size = {x = 12, y = 12},
elseif hangglider.use[pname] then --Unequip collisionbox = {0,0,0,0,0,0},
if HUD_Overlay then player:hud_change(hangglider.id[pname], "text", "default_wood.png^[colorize:#0000:255") end mesh = "hangglider.obj",
hangglider.use[pname] = false textures = {"wool_white.png", "default_wood.png"},
end immortal = true,
end, static_save = false,
sound = {breaks = "default_tool_breaks"},
})
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"
}, },
on_step = hangglider_step,
}) })
minetest.register_craft({ minetest.register_tool("hangglider:hangglider", {
output = "hangglider:hangglider", description = S("Glider"),
recipe = { inventory_image = "hangglider_item.png",
{"wool:white", "wool:white", "wool:white"}, sound = {breaks = "default_tool_breaks"},
{"default:stick", "", "default:stick"}, on_use = hangglider_use,
{"", "default:stick", ""},
}
}) })
dofile(minetest.get_modpath("hangglider").."/crafts.lua")

28
locale/hangglider.ca.tr Normal file
View File

@ -0,0 +1,28 @@
# textdomain: hangglider
White=blanc
Grey=gris
Dark_grey=gris fosc
Black=negre
Violet=violeta
Blue=blau
Cyan=cian
Dark_green=verd fosc
Green=verd
Yellow=groc
Brown=marró
Orange=taronja
Red=vermell
Magenta=magenta
Pink=rosa
Colored Glider=Planador de color
@1 Glider=Planador @1
You have entered restricted airspace!@@You will be shot down in @1 seconds by anti-aircraft guns!=Has entrat a l'espai aeri restringit!@@Seràs abatut en @1 segons per canons antiaeris!
<ID>=
Toggle airspace restrictions for area <ID>.=Activa o desactiva les restriccions d'espai aeri per a l'àrea <ID>.
Invalid usage, see /help area_flak.=Ús no vàlid, consulta /help area_flak.
Area @1 does not exist or is not owned by you.=L'àrea @1 no existeix o no és propietat teva.
Area @1 airspace is @2.=L'àrea @1 espai aeri és @2.
closed=tancat
opened=obert
Glider=Planador

28
locale/hangglider.de.tr Normal file
View File

@ -0,0 +1,28 @@
# textdomain: hangglider
White=Weisser
Grey=Grauer
Dark_grey=Dunkelgrauer
Black=Schwarzer
Violet=Violeter
Blue=Blauer
Cyan=Cyan farbener
Dark_green=Dunkelgrüner
Green=Grüner
Yellow=Gelber
Brown=Brauner
Orange=Orange farbener
Red=Roter
Magenta=Magenta farbener
Pink=Rosa
Colored Glider=Farbiger Gleitschirm
@1 Glider=@1 Gleitschirm
You have entered restricted airspace!@@You will be shot down in @1 seconds by anti-aircraft guns!=Du bist in eingeschränktem Luftraum eingedrungen!@nDu wirst in @1 Sekunden von FLAK abgeschossen.
<ID>=
Toggle airspace restrictions for area <ID>.=Luftraumbeschränkungen für Gebiet <ID> umschalten.
Invalid usage, see /help area_flak.=Ungültige Verwendung, siehe /help area_flak.=
Area @1 does not exist or is not owned by you.=Gebiet @1 existiert nicht oder es gehört dir nicht.
Area @1 airspace is @2.=Gebiet @1 Luftraum ist @2.
closed=eingeschränkt
opened=geöffnet
Glider=Gleitschirm

28
locale/hangglider.es.tr Normal file
View File

@ -0,0 +1,28 @@
# textdomain: hangglider
White=blanco
Grey=gris
Dark_grey=gris oscuro
Black=negro
Violet=violeta
Blue=azul
Cyan=cian
Dark_green=verde oscuro
Green=verde
Yellow=amarillo
Brown=marrón
Orange=naranja
Red=rojo
Magenta=magenta
Pink=rosa
Colored Glider=Planeador Colorizado
@1 Glider=Planeador @1
You have entered restricted airspace!@@You will be shot down in @1 seconds by anti-aircraft guns!=¡Has entrado en espacio aéreo restringido!@n¡Serás derribado en @1 segundos por cañones antiaéreos!
<ID>=
Toggle airspace restrictions for area <ID>.=Alternar restricciones de espacio aéreo para el área <ID>.
Invalid usage, see /help area_flak.=Uso no válido, consulta /help area_flak.
Area @1 does not exist or is not owned by you.=El área @1 no existe o no es tuya.
Area @1 airspace is @2.=Área @1 espacio aéreo está @2.
closed=cerrado
opened=abierto
Glider=Planeador

28
locale/template.txt Normal file
View File

@ -0,0 +1,28 @@
# textdomain: hangglider
White=
Grey=
Dark_grey=
Black=
Violet=
Blue=
Cyan=
Dark_green=
Green=
Yellow=
Brown=
Orange=
Red=
Magenta=
Pink=
Colored Glider=
@1 Glider=
You have entered restricted airspace!@@You will be shot down in @1 seconds by anti-aircraft guns!=
<ID>=
Toggle airspace restrictions for area <ID>.=
Invalid usage, see /help area_flak.=
Area @1 does not exist or is not owned by you.=
Area @1 airspace is @2.=
closed=
opened=
Glider=

View File

@ -1,4 +1,5 @@
name = hangglider name = hangglider
depends = default, wool description = Adds a functional hang glider for exploring
optional_depends = areas, player_monoids depends = default, wool, dye
min_minetest_version = 5.0 optional_depends = areas, player_monoids, pova, unifieddyes
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