new mod: air balloon
This commit is contained in:
parent
ad9dc6df7e
commit
8d60282644
57
hot_air_balloons/README.txt
Normal file
57
hot_air_balloons/README.txt
Normal file
@ -0,0 +1,57 @@
|
||||
This mod adds craftable and ridable hot air balloons to minetest.
|
||||
Controls:
|
||||
right click with coal lump: increase heat and buoyancy (*)
|
||||
right click without coal: enter or leave balloon
|
||||
left, right, up, down (default WASD): accelerate the balloon
|
||||
sneak (default shift): decrease heat, lowering buoyancy
|
||||
jump (default space): turn the balloon towards where the player is looking
|
||||
|
||||
|
||||
|
||||
optional dependencies:
|
||||
default, bucket (enable crafting recipe 1 if installed together)
|
||||
mcl_core, mcl_mobitems, mcl_buckets (enable crafting recipe 2 if installed together)
|
||||
|
||||
|
||||
Crafting recipe 1 (Minetest Game and most derivatives):
|
||||
[P] := paper
|
||||
[W] := wood
|
||||
[L] := lava bucket
|
||||
[ ] := nothing
|
||||
|
||||
[P][P][P]
|
||||
[P][L][P]
|
||||
[ ][W][ ]
|
||||
|
||||
Crafting recipe 2 (MineClone 2):
|
||||
[L] := leather
|
||||
[W] := wood
|
||||
[V] := lava bucket
|
||||
[S] := string
|
||||
|
||||
[L][L][L]
|
||||
[L][V][L]
|
||||
[S][W][S]
|
||||
|
||||
(*)any item with the "coal" group works for fuel. Higher coal group means higher heat
|
||||
Note that coal blocks and ore from the default mod don't have the coal group
|
||||
|
||||
See license.txt for proper license information.
|
||||
|
||||
Author of code
|
||||
----------------------------------------
|
||||
NetherEran (LGPL v2.1)
|
||||
|
||||
Authors of media (models, textures)
|
||||
----------------------------------------
|
||||
Textures
|
||||
--------
|
||||
NetherEran (CC BY-SA 3.0):
|
||||
hot_air_balloons_balloon.png
|
||||
hot_air_balloons_balloon_flame.png
|
||||
hot_air_balloons_balloon_model.png --Contains default_wood.png (by BlockMen) and default_aspen_wood.png (by sofar) (derived from default_pine_wood by paramat)
|
||||
|
||||
Models
|
||||
--------
|
||||
NetherEran (CC BY-SA 3.0):
|
||||
ballon.blend (= hot_air_balloons_balloon.obj)
|
101
hot_air_balloons/absent_ballooner_rescuing.lua
Normal file
101
hot_air_balloons/absent_ballooner_rescuing.lua
Normal file
@ -0,0 +1,101 @@
|
||||
--localize things for better performance
|
||||
local serialize = minetest.serialize
|
||||
local add_entity = minetest.add_entity
|
||||
local after = minetest.after
|
||||
|
||||
--for storing which players left while in a balloon
|
||||
local storage = minetest.get_mod_storage()
|
||||
local absent_ballooners = minetest.deserialize(storage:get_string("absent_ballooners")) or {}
|
||||
|
||||
|
||||
--putting leaving people into storage
|
||||
local leave_while_ballooning = function(player)
|
||||
local parent = player:get_attach()
|
||||
if parent and not parent:is_player()
|
||||
then
|
||||
local balloon_type = parent:get_luaentity().balloon_type
|
||||
if balloon_type
|
||||
then
|
||||
--remove() only works if someone else is in the area,
|
||||
--hence the need for mark_for_deletion
|
||||
parent:remove()
|
||||
absent_ballooners[player:get_player_name()] = balloon_type
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--same as on_leave but for all players at once
|
||||
local on_shutdown = function()
|
||||
local connected_players = minetest.get_connected_players()
|
||||
for i, p in ipairs(connected_players)
|
||||
do
|
||||
leave_while_ballooning(p)
|
||||
end
|
||||
storage:set_string("absent_ballooners", serialize(absent_ballooners))
|
||||
end
|
||||
--putting leaving people into storage and saving storage
|
||||
local on_leave = function(player)
|
||||
leave_while_ballooning(player)
|
||||
storage:set_string("absent_ballooners", serialize(absent_ballooners))
|
||||
end
|
||||
|
||||
minetest.register_on_leaveplayer(on_leave)
|
||||
minetest.register_on_shutdown(on_shutdown)
|
||||
|
||||
--checking if player who joined was ballooning when they left
|
||||
--if so spawn a new balloon and set them as attachment
|
||||
local on_join = function(player)
|
||||
if player
|
||||
then
|
||||
local name = player:get_player_name()
|
||||
if absent_ballooners[name]
|
||||
then
|
||||
local pos = player:get_pos()
|
||||
|
||||
--for compatibility with version 1.1 of the mod
|
||||
if absent_ballooners[name] == true
|
||||
then
|
||||
absent_ballooners[name] = "hot_air_balloons:balloon"
|
||||
end
|
||||
--minetest doesn't seem to like add_entity on init so a minetest.after is used
|
||||
--player is set as pilot in on_activate
|
||||
after(2,
|
||||
function()
|
||||
--concatenating "P" with name signals that player should be set as attach
|
||||
add_entity(pos, absent_ballooners[name], "P" .. name)
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
minetest.register_on_joinplayer(on_join)
|
||||
|
||||
|
||||
--called in on_activate if balloon was spawned to rescue an absent ballooner
|
||||
local set_rescue = function(self, playername)
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
self.pilot = playername
|
||||
if not player --player logged off right away
|
||||
then
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
player:set_attach(self.object, "",
|
||||
{x = 0, y = 1, z = 0}, {x = 0, y = 0, z = 0})
|
||||
absent_ballooners[playername] = nil
|
||||
end
|
||||
--set as get_staticdata
|
||||
local mark_for_deletion = function(self)
|
||||
if self.pilot
|
||||
then
|
||||
--pilot logged off while ballooning, deleting balloon on next activation
|
||||
return "R"
|
||||
else
|
||||
--normally save and load balloon
|
||||
return ""
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return set_rescue, mark_for_deletion
|
||||
|
||||
|
30
hot_air_balloons/api.txt
Normal file
30
hot_air_balloons/api.txt
Normal file
@ -0,0 +1,30 @@
|
||||
API functions:
|
||||
hot_air_balloons.get_entity(name, mesh_name, texture_name)
|
||||
arguments:
|
||||
'name': string in the format "modname:entityname"
|
||||
'mesh_name': string in the format "modname_meshFileName"
|
||||
'texture_name': string in the format "modname_textureFileName"
|
||||
Example usage: minetest.register_entity(hot_air_balloons.get_entity(foo, raa, see))
|
||||
you can also store the values in a local variable and change the fields of the entity definition table before registering the entity.
|
||||
passing the entity name to the function is used when a balloon pilot logs off
|
||||
|
||||
|
||||
|
||||
hot_air_balloons.get_item(name, description, texture, object_name)
|
||||
arguments:
|
||||
'name': string in the format "modname:itemname"
|
||||
'description': string that appears in the tooltip. Use minetest.translate with this.
|
||||
'texture': string in the format "modname_textureFileName"
|
||||
'object_name' is the name specified in hot_air_balloons.get_entity
|
||||
Example usage: minetest.register_craftitem(hot_air_balloons.get_item(foo, raa, see, mon))
|
||||
returns an item name and an item definition table
|
||||
as with get_entity you can store the item definition table and change its fields before registering the item.
|
||||
|
||||
|
||||
|
||||
explanation of the custom fields of the entitiy definition table:
|
||||
pilot: stores the player name of the pilot or nil if there is no pilot
|
||||
heat: integer in the interval [0, 12000)
|
||||
Decides wether to fly up or down
|
||||
balloon_type: entity name of the balloon, e.g."hot_air_balloons:balloon".
|
||||
used to make the balloon log off and log back in together with its pilot
|
62
hot_air_balloons/craft.lua
Normal file
62
hot_air_balloons/craft.lua
Normal file
@ -0,0 +1,62 @@
|
||||
--This file adds crafting recipes depending on which dependencies are installed
|
||||
|
||||
|
||||
if minetest.get_modpath("default") and
|
||||
minetest.get_modpath("bucket")
|
||||
then
|
||||
minetest.register_craft(
|
||||
{
|
||||
output = "hot_air_balloons:item",
|
||||
recipe =
|
||||
{
|
||||
{"default:paper", "default:paper", "default:paper"},
|
||||
{"default:paper", "bucket:bucket_lava", "default:paper"},
|
||||
{"", "group:wood", "" },
|
||||
},
|
||||
})
|
||||
minetest.register_craft(
|
||||
{
|
||||
type = "fuel",
|
||||
recipe = "hot_air_balloons:item",
|
||||
burntime = 20,
|
||||
})
|
||||
return
|
||||
end
|
||||
if minetest.get_modpath("mcl_buckets") and
|
||||
minetest.get_modpath("mcl_mobitems") and
|
||||
minetest.get_modpath("mcl_core")
|
||||
then
|
||||
minetest.register_craft(
|
||||
{
|
||||
output = "hot_air_balloons:item",
|
||||
recipe =
|
||||
{
|
||||
{"mcl_mobitems:leather", "mcl_mobitems:leather", "mcl_mobitems:leather"},
|
||||
{"mcl_mobitems:leather", "bucket:bucket_lava", "mcl_mobitems:leather"},
|
||||
{"mcl_mobitems:string", "group:wood", "mcl_mobitems:string" },
|
||||
},
|
||||
})
|
||||
minetest.register_craft(
|
||||
{
|
||||
type = "fuel",
|
||||
recipe = "hot_air_balloons:item",
|
||||
burntime = 20,
|
||||
})
|
||||
return
|
||||
end
|
||||
--[[
|
||||
minetest.register_craft(
|
||||
{
|
||||
type = "aircraft"
|
||||
}
|
||||
]]
|
||||
|
||||
--make balloon work with mcl2 creative mode
|
||||
|
||||
--announce in chat if no crafting recipe was added.
|
||||
minetest.after(2,
|
||||
function()
|
||||
minetest.chat_send_all("Optional dependencies for hot_air_balloons are missing so no crafting recipe was added.\n"..
|
||||
"Install either 'default' and 'bucket' or 'mcl_core', 'mcl_mobitems' 'and mcl_buckets' if this bothers you.\n"..
|
||||
"All other functions of the mod should be unaffected by this.")
|
||||
end)
|
5
hot_air_balloons/depends.txt
Normal file
5
hot_air_balloons/depends.txt
Normal file
@ -0,0 +1,5 @@
|
||||
default?
|
||||
bucket?
|
||||
mcl_buckets?
|
||||
mcl_mobitems?
|
||||
mcl_core?
|
221
hot_air_balloons/init.lua
Normal file
221
hot_air_balloons/init.lua
Normal file
@ -0,0 +1,221 @@
|
||||
--localize functions for better performance
|
||||
local string_byte = string.byte
|
||||
local string_sub = string.sub
|
||||
local get_item_group = minetest.get_item_group
|
||||
local add_particlespawner = minetest.add_particlespawner
|
||||
local add_item = minetest.add_item
|
||||
local get_node = minetest.get_node
|
||||
local add_entity = minetest.add_entity
|
||||
|
||||
local modpath = minetest.get_modpath("hot_air_balloons")
|
||||
local set_rescue, mark_for_deletion_if_piloted = dofile(modpath .. "/absent_ballooner_rescuing.lua")
|
||||
local handle_movement = dofile(modpath .. "/movement.lua")
|
||||
|
||||
local is_in_creative = function(name)
|
||||
return creative and creative.is_enabled_for
|
||||
and creative.is_enabled_for(name)
|
||||
end
|
||||
|
||||
local get_fire_particle = function (pos)
|
||||
pos.y = pos.y + 3
|
||||
return {
|
||||
amount = 3,
|
||||
time = 1,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = {x = 0, y = 1, z = 0},
|
||||
maxvel = {x = 0, y = 1, z = 0},
|
||||
minexptime = 1,
|
||||
maxexptime = 1,
|
||||
minsize = 10,
|
||||
maxsize = 5,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "hot_air_balloons_flame.png"
|
||||
}
|
||||
end
|
||||
|
||||
local add_heat = function(self, player)
|
||||
local item_stack = player:get_wielded_item()
|
||||
local item_name = item_stack:get_name()
|
||||
local group_coal = get_item_group(item_name, "coal")
|
||||
if group_coal == 0
|
||||
then
|
||||
return false
|
||||
end
|
||||
local heat = self.heat
|
||||
heat = heat + 1200 * group_coal --1 min until heat is back to original
|
||||
if heat < 12000 --cap heat at 12000 (10 min)
|
||||
then
|
||||
self.heat = heat
|
||||
--adding particle effect
|
||||
local pos = self.object:get_pos()
|
||||
add_particlespawner(get_fire_particle(pos))
|
||||
if not is_in_creative(player:get_player_name())
|
||||
then
|
||||
item_stack:take_item()
|
||||
player:set_wielded_item(item_stack)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--global table, has fields get_entity_def and get_item_def
|
||||
--custom balloons right now turn into normal ones when the pilot leaves
|
||||
hot_air_balloons = {}
|
||||
hot_air_balloons.get_entity = function(name, mesh_name, texture_name)
|
||||
return
|
||||
name,
|
||||
{
|
||||
initial_properties =
|
||||
{
|
||||
hp_max = 1,
|
||||
physical = true,
|
||||
weight = 5,
|
||||
collisionbox = {-0.65, -0.01, -0.65, 0.65, 1.11, 0.65},
|
||||
visual = "mesh",
|
||||
mesh = "hot_air_balloons_balloon.obj",
|
||||
textures = {"hot_air_balloons_balloon_model.png"},
|
||||
is_visible = true,
|
||||
makes_footstep_sound = false,
|
||||
automatic_rotate = false,
|
||||
backface_culling = false,
|
||||
},
|
||||
heat = 0,
|
||||
balloon_type = name,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
--decrease heat, move
|
||||
if self.heat > 0
|
||||
then
|
||||
self.heat = self.heat - 1
|
||||
end
|
||||
handle_movement(self)
|
||||
end,
|
||||
on_rightclick = function (self, clicker)
|
||||
--if hoding coal, increase heat, else mount/dismount
|
||||
if not clicker or not clicker:is_player()
|
||||
then
|
||||
return
|
||||
end
|
||||
--checking if clicker is holding coal
|
||||
--heating balloon and returning if yes
|
||||
if add_heat(self, clicker)
|
||||
then
|
||||
return
|
||||
end
|
||||
|
||||
--if not holding coal:
|
||||
local playername = clicker:get_player_name()
|
||||
if self.pilot and self.pilot == playername
|
||||
then
|
||||
self.pilot = nil
|
||||
clicker:set_detach()
|
||||
elseif not self.pilot
|
||||
then
|
||||
--attach
|
||||
self.pilot = playername
|
||||
clicker:set_attach(self.object, "",
|
||||
{x = 0, y = 1, z = 0}, {x = 0, y = 0, z = 0})
|
||||
end
|
||||
end,
|
||||
--if pilot leaves start sinking and prepare for next pilot
|
||||
on_detach_child = function(self, child)
|
||||
self.heat = 0
|
||||
self.object:setvelocity({x = 0, y = 0, z = 0})
|
||||
end,
|
||||
|
||||
on_activate = function(self, staticdata, dtime_s)
|
||||
self.object:set_armor_groups({punch_operable = 1})
|
||||
--so balloons don't get lost
|
||||
self.object:setvelocity({x = 0, y = 0, z = 0})
|
||||
|
||||
--checking if balloon was spawned from item or unloaded without pilot
|
||||
if staticdata == ""
|
||||
then
|
||||
return
|
||||
end
|
||||
--checking if balloon should despawn when pilot logged off
|
||||
local first_char = string_byte(staticdata)
|
||||
--ballooner logged off, balloon will respawn when ballooner logs back in
|
||||
if first_char == 82 --chr 82 = R
|
||||
then
|
||||
self.object:remove()
|
||||
return
|
||||
--absent ballooner logged back in
|
||||
elseif first_char == 80 --chr 80 = P
|
||||
then
|
||||
set_rescue(self, string_sub(staticdata, 2))
|
||||
end
|
||||
end,
|
||||
|
||||
get_staticdata = mark_for_deletion_if_piloted,
|
||||
|
||||
|
||||
on_punch = function(self, puncher) --drop balloon item
|
||||
if self.pilot
|
||||
then
|
||||
return
|
||||
elseif not (puncher and puncher:is_player())
|
||||
then
|
||||
return
|
||||
else
|
||||
self.object:remove()
|
||||
local inv = puncher:get_inventory()
|
||||
if not is_in_creative(puncher:get_player_name())
|
||||
or not inv:contains_item("main", "hot_air_balloons:item")
|
||||
then
|
||||
local leftover = inv:add_item("main", "hot_air_balloons:item")
|
||||
if not leftover:is_empty()
|
||||
then
|
||||
add_item(self.object:get_pos(), leftover)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
hot_air_balloons.get_item = function(name, description, texture, object_name)
|
||||
return
|
||||
name,
|
||||
{
|
||||
description = description,
|
||||
inventory_image = texture,
|
||||
stack_max = 1,
|
||||
liquids_pointable = true,
|
||||
groups = {flammable = 2},
|
||||
on_place =
|
||||
function (itemstack, placer, pointed_thing)
|
||||
--places balloon if the clicked thing is a node and the above node is air
|
||||
if pointed_thing.type == "node"
|
||||
and get_node (pointed_thing.above).name == "air"
|
||||
then
|
||||
if not is_in_creative(placer:get_player_name())
|
||||
then
|
||||
itemstack:take_item()
|
||||
end
|
||||
local pos_to_place = pointed_thing.above
|
||||
pos_to_place.y = pos_to_place.y - 0.5 --subtracting 0.5 to place on ground
|
||||
add_entity(pointed_thing.above, object_name)
|
||||
end
|
||||
--add remaining items to inventory
|
||||
return itemstack
|
||||
end
|
||||
}
|
||||
end
|
||||
--registering the balloon entity, item and recepies
|
||||
|
||||
minetest.register_entity(hot_air_balloons.get_entity(
|
||||
"hot_air_balloons:balloon",
|
||||
"hot_air_balloons_balloon.obj",
|
||||
"hot_air_balloons_balloon_model.png"))
|
||||
|
||||
minetest.register_craftitem(hot_air_balloons.get_item(
|
||||
"hot_air_balloons:item",
|
||||
minetest.translate("hot_air_balloons", "Hot Air Balloon"),
|
||||
"hot_air_balloons_balloon.png",
|
||||
"hot_air_balloons:balloon"))
|
||||
|
||||
|
||||
dofile(modpath .. "/craft.lua")
|
54
hot_air_balloons/license.txt
Normal file
54
hot_air_balloons/license.txt
Normal file
@ -0,0 +1,54 @@
|
||||
License of source code
|
||||
----------------------
|
||||
|
||||
GNU Lesser General Public License, version 2.1
|
||||
Copyright (C) 2019 NetherEran
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms
|
||||
of the GNU Lesser General Public License as published by the Free Software Foundation;
|
||||
either version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details:
|
||||
https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
|
||||
|
||||
|
||||
Licenses of media (textures, models and sounds)
|
||||
-----------------------------------------------
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
Copyright (C) 2010-2018:
|
||||
|
||||
NetherEran
|
||||
BlockMen
|
||||
sofar
|
||||
paramat
|
||||
|
||||
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/
|
2
hot_air_balloons/locale/hot_air_balloons.de.tr
Normal file
2
hot_air_balloons/locale/hot_air_balloons.de.tr
Normal file
@ -0,0 +1,2 @@
|
||||
# textdomain:hot_air_balloons
|
||||
Hot Air Balloon=Heißluftballon
|
2
hot_air_balloons/locale/hot_air_balloons.es.tr
Normal file
2
hot_air_balloons/locale/hot_air_balloons.es.tr
Normal file
@ -0,0 +1,2 @@
|
||||
# textdomain:hot_air_balloons
|
||||
Hot Air Balloon=Globo Aerostático
|
2
hot_air_balloons/locale/hot_air_balloons.ro.tr
Normal file
2
hot_air_balloons/locale/hot_air_balloons.ro.tr
Normal file
@ -0,0 +1,2 @@
|
||||
# textdomain:hot_air_balloons
|
||||
Hot Air Balloon=Balon cu aer cald
|
4
hot_air_balloons/mod.conf
Normal file
4
hot_air_balloons/mod.conf
Normal file
@ -0,0 +1,4 @@
|
||||
name = hot_air_balloons
|
||||
author = Eran
|
||||
description = Adds craftable and controllable hot air balloons.
|
||||
optional_depends = default, bucket, mcl_buckets, mcl_mobitems, mcl_core
|
BIN
hot_air_balloons/models/balloon.blend
Normal file
BIN
hot_air_balloons/models/balloon.blend
Normal file
Binary file not shown.
485
hot_air_balloons/models/hot_air_balloons_balloon.obj
Normal file
485
hot_air_balloons/models/hot_air_balloons_balloon.obj
Normal file
@ -0,0 +1,485 @@
|
||||
# Blender v2.79 (sub 0) OBJ File: 'balloon.blend'
|
||||
# www.blender.org
|
||||
mtllib hot_air_balloons_balloon.mtl
|
||||
o Cube.001
|
||||
v -19.500000 44.216793 19.500000
|
||||
v -19.500000 83.216797 19.500000
|
||||
v -19.500000 44.216793 -19.500000
|
||||
v -19.500000 83.216797 -19.500000
|
||||
v 19.500000 44.216793 19.500000
|
||||
v 19.500000 83.216797 19.500000
|
||||
v 19.500000 44.216793 -19.500000
|
||||
v 19.500000 83.216797 -19.500000
|
||||
v -6.500000 0.016788 6.500000
|
||||
v 6.500000 0.016788 6.500000
|
||||
v -6.500000 0.016788 -6.500000
|
||||
v 6.500000 0.016788 -6.500000
|
||||
v -6.500000 1.441189 6.500000
|
||||
v 6.500000 1.441189 6.500000
|
||||
v -6.500000 1.441189 -6.500000
|
||||
v 6.500000 1.441189 -6.500000
|
||||
v -6.500000 0.016788 -4.550000
|
||||
v -6.500000 0.016788 4.550000
|
||||
v 6.500000 0.016788 4.550000
|
||||
v 6.500000 0.016788 -4.550000
|
||||
v -6.500000 1.441189 -4.550000
|
||||
v -6.500000 1.441189 4.550000
|
||||
v 6.500000 1.441189 4.550000
|
||||
v 6.500000 1.441189 -4.550000
|
||||
v -4.550000 0.016788 6.500000
|
||||
v 4.550000 0.016788 6.500000
|
||||
v 4.550000 0.016788 -6.500000
|
||||
v -4.550000 0.016788 -6.500000
|
||||
v -4.550000 1.441189 6.500000
|
||||
v 4.550000 1.441189 6.500000
|
||||
v 4.550000 1.441189 -6.500000
|
||||
v -4.550000 1.441189 -6.500000
|
||||
v 4.550000 1.441189 4.550000
|
||||
v -4.550000 1.441189 4.550000
|
||||
v -4.550000 1.441189 -4.550000
|
||||
v -4.550000 0.016788 4.550000
|
||||
v 4.550000 0.016788 4.550000
|
||||
v -4.550000 0.016788 -4.550000
|
||||
v 4.550000 0.016788 -4.550000
|
||||
v 6.500000 11.077995 6.500000
|
||||
v -6.500000 11.077995 6.500000
|
||||
v 6.500000 11.077995 6.500000
|
||||
v -6.500000 11.077995 -6.500000
|
||||
v -6.500000 11.077995 6.500000
|
||||
v 6.500000 11.077995 -6.500000
|
||||
v 4.550000 11.077995 4.550000
|
||||
v 4.550000 11.077995 -4.550000
|
||||
v -4.550000 11.077995 -4.550000
|
||||
v -4.550000 11.077995 -4.550000
|
||||
v -4.550000 1.441189 -4.550000
|
||||
v 4.550000 1.441189 -4.550000
|
||||
v 4.550000 11.077995 -4.550000
|
||||
v -4.550000 11.077995 4.550000
|
||||
v 4.550000 1.441189 4.550000
|
||||
v 6.500000 1.441189 -6.500000
|
||||
v 4.550000 11.077995 4.550000
|
||||
v -4.550000 11.077995 -6.500000
|
||||
v -6.500000 1.441189 -6.500000
|
||||
v 4.550000 11.077995 -6.500000
|
||||
v 4.550000 11.077995 6.500000
|
||||
v -4.550000 11.077995 6.500000
|
||||
v 6.500000 11.077995 -4.550000
|
||||
v 6.500000 1.441189 6.500000
|
||||
v 6.500000 11.077995 4.550000
|
||||
v -6.500000 11.077995 4.550000
|
||||
v -6.500000 11.077995 -4.550000
|
||||
v -6.500000 1.441189 6.500000
|
||||
v 6.500000 11.077995 -6.500000
|
||||
v -6.500000 11.077995 -6.500000
|
||||
v 5.586319 8.609333 -5.559702
|
||||
v 11.988016 44.915165 -12.060156
|
||||
v 5.537368 8.331722 -7.158404
|
||||
v 11.939065 44.637550 -13.658857
|
||||
v 7.185020 8.327442 -5.559702
|
||||
v 13.586718 44.633270 -12.060156
|
||||
v 7.136070 8.049831 -7.158404
|
||||
v 13.537767 44.355656 -13.658857
|
||||
v -5.586318 8.609333 -5.559702
|
||||
v -11.988014 44.915165 -12.060155
|
||||
v -5.537367 8.331722 -7.158404
|
||||
v -11.939065 44.637554 -13.658857
|
||||
v -7.185020 8.327442 -5.559702
|
||||
v -13.586717 44.633270 -12.060155
|
||||
v -7.136071 8.049831 -7.158404
|
||||
v -13.537764 44.355656 -13.658857
|
||||
v 5.586319 8.609337 5.559702
|
||||
v 11.988015 44.915161 12.060157
|
||||
v 5.537368 8.331722 7.158404
|
||||
v 11.939065 44.637547 13.658860
|
||||
v 7.185020 8.327442 5.559702
|
||||
v 13.586717 44.633270 12.060157
|
||||
v 7.136070 8.049831 7.158404
|
||||
v 13.537766 44.355652 13.658860
|
||||
v -5.586318 8.609337 5.559702
|
||||
v -11.988016 44.915161 12.060155
|
||||
v -5.537367 8.331722 7.158405
|
||||
v -11.939065 44.637550 13.658857
|
||||
v -7.185019 8.327442 5.559704
|
||||
v -13.586717 44.633266 12.060157
|
||||
v -7.136071 8.049831 7.158405
|
||||
v -13.537766 44.355652 13.658860
|
||||
vt 0.666667 0.666667
|
||||
vt 0.333333 0.666667
|
||||
vt 0.333333 0.333333
|
||||
vt 0.666667 0.333333
|
||||
vt 0.000000 1.000000
|
||||
vt 0.000000 0.666667
|
||||
vt 0.333333 0.666667
|
||||
vt 0.333333 1.000000
|
||||
vt 0.333333 0.333333
|
||||
vt 0.000000 0.333333
|
||||
vt 0.000000 0.000000
|
||||
vt 0.333333 0.000000
|
||||
vt 0.333333 0.333333
|
||||
vt 0.333333 0.000000
|
||||
vt 0.666667 0.000000
|
||||
vt 0.666667 0.333333
|
||||
vt 0.000000 0.666667
|
||||
vt 0.000000 0.333333
|
||||
vt 0.333333 0.666667
|
||||
vt 0.666667 0.000000
|
||||
vt 1.000000 0.000000
|
||||
vt 1.000000 0.333333
|
||||
vt 0.666667 0.333333
|
||||
vt 0.350615 0.683822
|
||||
vt 0.333949 0.683822
|
||||
vt 0.333949 0.667155
|
||||
vt 0.350615 0.667155
|
||||
vt 0.761207 0.649225
|
||||
vt 0.761207 0.665892
|
||||
vt 0.749033 0.665892
|
||||
vt 0.749033 0.649225
|
||||
vt 0.761207 0.427778
|
||||
vt 0.761207 0.444444
|
||||
vt 0.749033 0.444444
|
||||
vt 0.749033 0.427778
|
||||
vt 0.538985 0.761111
|
||||
vt 0.538985 0.777778
|
||||
vt 0.526810 0.777778
|
||||
vt 0.526810 0.761111
|
||||
vt 0.667442 0.461111
|
||||
vt 0.667442 0.444444
|
||||
vt 0.679616 0.444444
|
||||
vt 0.679616 0.461111
|
||||
vt 0.667442 0.555556
|
||||
vt 0.667442 0.538889
|
||||
vt 0.679616 0.538889
|
||||
vt 0.679616 0.555556
|
||||
vt 0.761207 0.555556
|
||||
vt 0.761207 0.572222
|
||||
vt 0.749033 0.572222
|
||||
vt 0.749033 0.555556
|
||||
vt 0.761207 0.650000
|
||||
vt 0.749033 0.650000
|
||||
vt 0.749420 0.427778
|
||||
vt 0.749420 0.444444
|
||||
vt 0.667054 0.444444
|
||||
vt 0.667054 0.427778
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.445060 0.683822
|
||||
vt 0.428393 0.683822
|
||||
vt 0.428393 0.667155
|
||||
vt 0.445060 0.667155
|
||||
vt 0.428393 0.777778
|
||||
vt 0.350615 0.777778
|
||||
vt 0.350615 0.761111
|
||||
vt 0.428393 0.761111
|
||||
vt 0.350615 0.683333
|
||||
vt 0.428393 0.683333
|
||||
vt 0.445060 0.777778
|
||||
vt 0.445060 0.761111
|
||||
vt 0.445060 0.683333
|
||||
vt 0.749420 0.555556
|
||||
vt 0.749420 0.572222
|
||||
vt 0.667054 0.572222
|
||||
vt 0.667054 0.555556
|
||||
vt 0.616763 0.749521
|
||||
vt 0.538985 0.749521
|
||||
vt 0.538985 0.667155
|
||||
vt 0.616763 0.667155
|
||||
vt 0.750035 0.334724
|
||||
vt 0.750035 0.351390
|
||||
vt 0.667669 0.351390
|
||||
vt 0.667669 0.334724
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.538985 0.667362
|
||||
vt 0.538985 0.684029
|
||||
vt 0.526810 0.684029
|
||||
vt 0.526810 0.667362
|
||||
vt 0.538985 0.683333
|
||||
vt 0.526810 0.683333
|
||||
vt 0.761822 0.334724
|
||||
vt 0.761822 0.351390
|
||||
vt 0.749648 0.351390
|
||||
vt 0.749648 0.334724
|
||||
vt 0.761207 0.350000
|
||||
vt 0.749033 0.350000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.333949 0.777778
|
||||
vt 0.333949 0.761111
|
||||
vt 0.333949 0.683333
|
||||
vt 0.744444 0.749033
|
||||
vt 0.666667 0.749033
|
||||
vt 0.666667 0.666667
|
||||
vt 0.744444 0.666667
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.744444 0.666667
|
||||
vt 0.822222 0.666667
|
||||
vt 0.822222 0.749033
|
||||
vt 0.744444 0.749033
|
||||
vt 0.444445 0.777778
|
||||
vt 0.444445 0.761111
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.616763 0.777778
|
||||
vt 0.616763 0.666667
|
||||
vt 0.633429 0.666667
|
||||
vt 0.633429 0.777778
|
||||
vt 0.616763 0.831398
|
||||
vt 0.538985 0.831398
|
||||
vt 0.538985 0.749033
|
||||
vt 0.616763 0.749033
|
||||
vt 0.444445 0.683333
|
||||
vt 0.749420 0.650000
|
||||
vt 0.667054 0.650000
|
||||
vt 0.678841 0.538889
|
||||
vt 0.678841 0.461111
|
||||
vt 0.761207 0.461111
|
||||
vt 0.761207 0.538889
|
||||
vt 0.749420 0.649225
|
||||
vt 0.749420 0.665892
|
||||
vt 0.667054 0.665892
|
||||
vt 0.667054 0.649225
|
||||
vt 0.678841 0.555556
|
||||
vt 0.761207 0.555556
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.678841 0.444444
|
||||
vt 0.761207 0.444444
|
||||
vt 0.749420 0.350000
|
||||
vt 0.667054 0.350000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.444445 0.684029
|
||||
vt 0.444445 0.667362
|
||||
vt 0.633429 0.666667
|
||||
vt 0.650096 0.666667
|
||||
vt 0.650096 0.777778
|
||||
vt 0.633429 0.777778
|
||||
vt 0.744444 0.749033
|
||||
vt 0.761111 0.749033
|
||||
vt 0.761111 0.826810
|
||||
vt 0.744444 0.826810
|
||||
vt 0.777778 0.749033
|
||||
vt 0.777778 0.826810
|
||||
vt 0.761111 0.826810
|
||||
vt 0.761111 0.749033
|
||||
vt 0.666667 0.749033
|
||||
vt 0.744444 0.749033
|
||||
vt 0.744444 0.826810
|
||||
vt 0.666667 0.826810
|
||||
vt 0.858286 0.648647
|
||||
vt 0.858286 0.333406
|
||||
vt 0.872154 0.333333
|
||||
vt 0.872154 0.648574
|
||||
vt 0.941529 0.333333
|
||||
vt 0.941529 0.648427
|
||||
vt 0.927654 0.648427
|
||||
vt 0.927654 0.333333
|
||||
vt 0.844417 0.333406
|
||||
vt 0.844417 0.648647
|
||||
vt 0.830549 0.648574
|
||||
vt 0.830549 0.333333
|
||||
vt 0.955404 0.333333
|
||||
vt 0.955404 0.648427
|
||||
vt 0.941529 0.648427
|
||||
vt 0.941529 0.333333
|
||||
vt 0.650096 0.694844
|
||||
vt 0.663754 0.695262
|
||||
vt 0.663754 0.708933
|
||||
vt 0.650096 0.708515
|
||||
vt 0.663754 0.722603
|
||||
vt 0.650096 0.723022
|
||||
vt 0.650096 0.709351
|
||||
vt 0.663754 0.708933
|
||||
vt 0.844417 0.333333
|
||||
vt 0.858286 0.333406
|
||||
vt 0.858286 0.648647
|
||||
vt 0.844417 0.648574
|
||||
vt 0.913779 0.333333
|
||||
vt 0.927654 0.333333
|
||||
vt 0.927654 0.648427
|
||||
vt 0.913779 0.648427
|
||||
vt 0.830549 0.648574
|
||||
vt 0.816681 0.648647
|
||||
vt 0.816681 0.333406
|
||||
vt 0.830549 0.333333
|
||||
vt 0.886029 0.648427
|
||||
vt 0.872154 0.648427
|
||||
vt 0.872154 0.333333
|
||||
vt 0.886029 0.333333
|
||||
vt 0.650096 0.694844
|
||||
vt 0.650096 0.681174
|
||||
vt 0.663754 0.680755
|
||||
vt 0.663754 0.694426
|
||||
vt 0.650096 0.750781
|
||||
vt 0.650096 0.737110
|
||||
vt 0.663754 0.737528
|
||||
vt 0.663754 0.751199
|
||||
vt 0.802812 0.648647
|
||||
vt 0.788944 0.648574
|
||||
vt 0.788944 0.333333
|
||||
vt 0.802812 0.333406
|
||||
vt 0.886029 0.648427
|
||||
vt 0.899904 0.648427
|
||||
vt 0.899904 0.963520
|
||||
vt 0.886029 0.963520
|
||||
vt 0.762184 0.333406
|
||||
vt 0.776052 0.333333
|
||||
vt 0.776052 0.648574
|
||||
vt 0.762183 0.648647
|
||||
vt 0.913779 0.648426
|
||||
vt 0.899904 0.648427
|
||||
vt 0.899904 0.333333
|
||||
vt 0.913779 0.333333
|
||||
vt 0.650096 0.765288
|
||||
vt 0.650096 0.751617
|
||||
vt 0.663754 0.751199
|
||||
vt 0.663754 0.764869
|
||||
vt 0.650096 0.680337
|
||||
vt 0.650096 0.666667
|
||||
vt 0.663754 0.667085
|
||||
vt 0.663754 0.680755
|
||||
vt 0.816681 0.333333
|
||||
vt 0.816681 0.648574
|
||||
vt 0.802812 0.648647
|
||||
vt 0.802812 0.333406
|
||||
vt 0.886029 0.648427
|
||||
vt 0.886029 0.333333
|
||||
vt 0.899904 0.333333
|
||||
vt 0.899904 0.648426
|
||||
vt 0.788944 0.333406
|
||||
vt 0.788944 0.648647
|
||||
vt 0.775075 0.648574
|
||||
vt 0.775075 0.333333
|
||||
vt 0.872154 0.963520
|
||||
vt 0.872154 0.648427
|
||||
vt 0.886029 0.648427
|
||||
vt 0.886029 0.963520
|
||||
vt 0.650096 0.723022
|
||||
vt 0.663754 0.723440
|
||||
vt 0.663754 0.737110
|
||||
vt 0.650096 0.736692
|
||||
vt 0.774865 0.662317
|
||||
vt 0.761207 0.662735
|
||||
vt 0.761207 0.649065
|
||||
vt 0.774865 0.648647
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
vn -0.9848 0.1736 0.0000
|
||||
vn -0.0302 -0.1710 -0.9848
|
||||
vn 0.9848 -0.1736 0.0000
|
||||
vn 0.0302 0.1710 0.9848
|
||||
vn -0.1710 -0.9698 0.1736
|
||||
vn 0.1710 0.9698 -0.1736
|
||||
vn 0.9848 0.1736 -0.0000
|
||||
vn 0.0302 -0.1710 -0.9848
|
||||
vn -0.9848 -0.1736 -0.0000
|
||||
vn -0.0302 0.1710 0.9848
|
||||
vn 0.1710 -0.9698 0.1736
|
||||
vn -0.1710 0.9698 -0.1737
|
||||
vn -0.0302 -0.1710 0.9848
|
||||
vn 0.0302 0.1710 -0.9848
|
||||
vn -0.1710 -0.9698 -0.1736
|
||||
vn 0.1710 0.9698 0.1737
|
||||
vn 0.0302 -0.1710 0.9848
|
||||
vn -0.0302 0.1710 -0.9848
|
||||
vn 0.1710 -0.9698 -0.1736
|
||||
vn -0.1710 0.9698 0.1736
|
||||
usemtl None
|
||||
s off
|
||||
f 1/1/1 2/2/1 4/3/1 3/4/1
|
||||
f 3/5/2 4/6/2 8/7/2 7/8/2
|
||||
f 7/9/3 8/10/3 6/11/3 5/12/3
|
||||
f 5/13/4 6/14/4 2/15/4 1/16/4
|
||||
f 3/17/5 7/18/5 5/13/5 1/19/5
|
||||
f 8/20/6 4/21/6 2/22/6 6/23/6
|
||||
f 39/24/5 27/25/5 12/26/5 20/27/5
|
||||
f 18/28/1 9/29/1 13/30/1 22/31/1
|
||||
f 28/32/2 11/33/2 15/34/2 32/35/2
|
||||
f 26/36/4 10/37/4 14/38/4 30/39/4
|
||||
f 20/40/3 12/41/3 16/42/3 24/43/3
|
||||
f 10/44/3 19/45/3 23/46/3 14/47/3
|
||||
f 19/45/3 20/40/3 24/43/3 23/46/3
|
||||
f 11/48/1 17/49/1 21/50/1 15/51/1
|
||||
f 17/49/1 18/52/1 22/53/1 21/50/1
|
||||
f 32/54/2 15/55/2 69/56/2 57/57/2
|
||||
f 15/58/4 58/59/4 43/60/4 69/61/4
|
||||
f 26/62/5 37/63/5 19/64/5 10/65/5
|
||||
f 37/63/5 39/24/5 20/27/5 19/64/5
|
||||
f 18/66/5 17/67/5 38/68/5 36/69/5
|
||||
f 36/69/5 38/68/5 39/70/5 37/71/5
|
||||
f 9/72/5 18/66/5 36/69/5 25/73/5
|
||||
f 25/73/5 36/69/5 37/71/5 26/74/5
|
||||
f 15/75/1 21/76/1 66/77/1 69/78/1
|
||||
f 51/79/2 50/80/2 48/81/2 47/82/2
|
||||
f 16/83/2 31/84/2 59/85/2 68/86/2
|
||||
f 52/87/4 56/88/4 46/89/4 47/90/4
|
||||
f 9/91/4 25/92/4 29/93/4 13/94/4
|
||||
f 25/95/4 26/36/4 30/39/4 29/96/4
|
||||
f 12/97/2 27/98/2 31/99/2 16/100/2
|
||||
f 27/101/2 28/32/2 32/35/2 31/102/2
|
||||
f 49/103/4 52/87/4 47/90/4 48/104/4
|
||||
f 17/67/5 11/105/5 28/106/5 38/68/5
|
||||
f 38/68/5 28/106/5 27/107/5 39/70/5
|
||||
f 34/108/4 33/109/4 56/110/4 53/111/4
|
||||
f 13/112/4 67/113/4 41/114/4 44/115/4
|
||||
f 16/116/4 55/117/4 45/118/4 68/119/4
|
||||
f 54/120/3 51/121/3 47/122/3 46/123/3
|
||||
f 30/39/4 14/38/4 40/124/4 60/125/4
|
||||
f 14/126/4 63/127/4 42/128/4 40/129/4
|
||||
f 44/130/6 42/131/6 64/132/6 65/133/6
|
||||
f 35/134/1 34/135/1 53/136/1 49/137/1
|
||||
f 29/96/4 30/39/4 60/125/4 61/138/4
|
||||
f 21/76/1 22/139/1 65/140/1 66/77/1
|
||||
f 23/141/3 24/142/3 62/143/3 64/144/3
|
||||
f 22/145/1 13/146/1 44/147/1 65/148/1
|
||||
f 14/149/3 23/141/3 64/144/3 40/150/3
|
||||
f 50/151/4 35/152/4 49/103/4 48/104/4
|
||||
f 24/142/3 16/153/3 68/154/3 62/143/3
|
||||
f 31/155/2 32/54/2 57/57/2 59/156/2
|
||||
f 33/157/4 54/158/4 46/89/4 56/88/4
|
||||
f 13/94/4 29/93/4 61/159/4 44/160/4
|
||||
f 62/161/6 68/162/6 69/163/6 66/164/6
|
||||
f 62/165/6 52/166/6 56/167/6 64/168/6
|
||||
f 66/169/6 65/170/6 53/171/6 49/172/6
|
||||
f 51/173/5 54/174/5 34/175/5 50/176/5
|
||||
f 70/177/7 71/178/7 73/179/7 72/180/7
|
||||
f 72/181/8 73/182/8 77/183/8 76/184/8
|
||||
f 76/185/9 77/186/9 75/187/9 74/188/9
|
||||
f 74/189/10 75/190/10 71/191/10 70/192/10
|
||||
f 72/193/11 76/194/11 74/195/11 70/196/11
|
||||
f 77/197/12 73/198/12 71/199/12 75/200/12
|
||||
f 78/201/13 80/202/13 81/203/13 79/204/13
|
||||
f 80/205/14 84/206/14 85/207/14 81/208/14
|
||||
f 84/209/15 82/210/15 83/211/15 85/212/15
|
||||
f 82/213/16 78/214/16 79/215/16 83/216/16
|
||||
f 80/217/17 78/218/17 82/219/17 84/220/17
|
||||
f 85/221/18 83/222/18 79/223/18 81/224/18
|
||||
f 86/225/7 88/226/7 89/227/7 87/228/7
|
||||
f 88/229/19 92/230/19 93/231/19 89/232/19
|
||||
f 92/233/9 90/234/9 91/235/9 93/236/9
|
||||
f 90/237/20 86/238/20 87/239/20 91/240/20
|
||||
f 88/241/21 86/242/21 90/243/21 92/244/21
|
||||
f 93/245/22 91/246/22 87/247/22 89/248/22
|
||||
f 94/249/13 95/250/13 97/251/13 96/252/13
|
||||
f 96/253/23 97/254/23 101/255/23 100/256/23
|
||||
f 100/257/15 101/258/15 99/259/15 98/260/15
|
||||
f 98/261/24 99/262/24 95/263/24 94/264/24
|
||||
f 96/265/25 100/266/25 98/267/25 94/268/25
|
||||
f 101/269/26 97/270/26 95/271/26 99/272/26
|
209
hot_air_balloons/movement.lua
Normal file
209
hot_air_balloons/movement.lua
Normal file
@ -0,0 +1,209 @@
|
||||
--localize global functions
|
||||
local vector_new = vector.new
|
||||
local math_hypot = math.hypot
|
||||
local atan = math.atan
|
||||
local cos = math.cos
|
||||
local sin = math.sin
|
||||
local abs = math.abs
|
||||
local pi = math.pi
|
||||
local min = math.min
|
||||
|
||||
--max speed settings
|
||||
local max_ballooning_vertical_speed = 1
|
||||
local max_ballooning_horizontal_speed = 3
|
||||
|
||||
local function is_water_is_air(pos)
|
||||
local node_name = minetest.get_node(pos).name
|
||||
return minetest.get_item_group(node_name, "water") > 0,
|
||||
node_name == "air"
|
||||
end
|
||||
local function get_vertical_acceleration(self)
|
||||
local heat = self.heat
|
||||
local vel_y = self.object:getvelocity().y
|
||||
local acc_candidate = heat / 1000 - 0.5
|
||||
|
||||
--enforce max speed
|
||||
if vel_y > max_ballooning_vertical_speed
|
||||
and acc_candidate * vel_y > 0
|
||||
then
|
||||
return 0
|
||||
else
|
||||
return acc_candidate
|
||||
end
|
||||
end
|
||||
|
||||
--if balloon is submerged
|
||||
local function float_up(self, vel)
|
||||
self.submerged = true
|
||||
vel.y = 1
|
||||
return vel
|
||||
end
|
||||
|
||||
local function swim(self, vel)
|
||||
--allow controls, allow up
|
||||
local pos = self.object:get_pos()
|
||||
--keep y constant or rising
|
||||
local acc_y = get_vertical_acceleration(self)
|
||||
|
||||
if self.submerged or acc_y < 0
|
||||
then
|
||||
self.submerged = false
|
||||
vel.y = 0
|
||||
return 0, vel
|
||||
else
|
||||
return acc_y, vel
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local tau = pi * 2
|
||||
--returns the radian equivalent of a in the range [0, tau)
|
||||
local function to_radian(a)
|
||||
if a < 0
|
||||
then
|
||||
return to_radian(a + tau)
|
||||
elseif a >= tau
|
||||
then
|
||||
return to_radian(a - tau)
|
||||
else
|
||||
return a
|
||||
end
|
||||
end
|
||||
--decides which is the shortest way to rotate towards where the player is looking
|
||||
local function get_rotate_direction(a, b)
|
||||
return to_radian(a - b) < to_radian(b - a)
|
||||
end
|
||||
|
||||
--rotates the balloon towards where the player is looking
|
||||
local pi_192ths = pi / 192 --radians to turn each step
|
||||
local function rotate(self, player)
|
||||
-- + pi so it finishes rotating when looking towards where the player is looking
|
||||
local player_yaw = player:get_look_horizontal() + pi
|
||||
local self_yaw = self.object:getyaw()
|
||||
|
||||
if get_rotate_direction(player_yaw, self_yaw)
|
||||
then
|
||||
self.object:setyaw(to_radian(self_yaw - pi_192ths))
|
||||
else
|
||||
self.object:setyaw(to_radian(self_yaw + pi_192ths))
|
||||
end
|
||||
end
|
||||
|
||||
--takes wasd and turns it into a 2d vector
|
||||
local pi_halves = pi / 2
|
||||
function get_direction(right, left, up, down)
|
||||
local inline, cross = 0, 0
|
||||
local move = right or left or up or down
|
||||
if left then cross = 1 end
|
||||
if right then cross = cross - 1 end
|
||||
if up then inline = 1 end
|
||||
if down then inline = inline - 1 end
|
||||
local arg
|
||||
if inline < 0
|
||||
then
|
||||
return atan(cross / inline) + pi, move
|
||||
elseif inline > 0
|
||||
then
|
||||
return atan(cross / inline), move
|
||||
else
|
||||
return pi_halves * cross, move
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
space to rotate where the player is looking
|
||||
wasd to apply acceleration
|
||||
shift to let out hot air, cooling the balloon
|
||||
]]
|
||||
local function handle_control(self, vel)
|
||||
if not self.pilot
|
||||
then
|
||||
return 0, 0
|
||||
end
|
||||
local player = minetest.get_player_by_name(self.pilot)
|
||||
if not player --player left, balloon should get deleted
|
||||
then
|
||||
return 0, 0
|
||||
end
|
||||
local control = player:get_player_control()
|
||||
if control.sneak --lowering heat quickly
|
||||
then
|
||||
local heat = self.heat - 30
|
||||
if heat < 0
|
||||
then
|
||||
self.heat = 0
|
||||
else
|
||||
self.heat = heat
|
||||
end
|
||||
end
|
||||
|
||||
if control.jump --rotate towards player yaw
|
||||
then
|
||||
rotate(self, player)
|
||||
end
|
||||
|
||||
--taking direction from get_direction
|
||||
--and turning it into radians.
|
||||
--if max speed is reached, only acceleration in the opposite direction is applied.
|
||||
local dir_radians, move = get_direction(control.right, control.left, control.up, control.down)
|
||||
if move and math_hypot(vel.x, vel.z)
|
||||
then
|
||||
dir_radians = dir_radians + player:get_look_horizontal()
|
||||
local x, z = -sin(dir_radians), cos(dir_radians)
|
||||
if math_hypot(vel.x, vel.z) > max_ballooning_horizontal_speed
|
||||
then
|
||||
if x * vel.x > 0
|
||||
then
|
||||
x = 0
|
||||
end
|
||||
if z * vel.z > 0
|
||||
then
|
||||
z = 0
|
||||
end
|
||||
end
|
||||
return x, z
|
||||
end
|
||||
return 0, 0
|
||||
end
|
||||
|
||||
--[[handle movement in different cases
|
||||
movement restrictions:
|
||||
-on ground: only vertical movement
|
||||
-on water: free movement, though vertical only if up
|
||||
-submerged: free movement, vertical goes up automatically
|
||||
-in air: completely free movement
|
||||
]]
|
||||
|
||||
return function(self)
|
||||
local pos_in = self.object:get_pos()
|
||||
local pos_under = vector_new(pos_in.x, pos_in.y - 0.1, pos_in.z)
|
||||
local on_water, in_air = is_water_is_air(pos_under)
|
||||
local acc = vector_new(0, 0, 0)
|
||||
local vel = self.object:getvelocity()
|
||||
|
||||
|
||||
if is_water_is_air(pos_in) --if submerged
|
||||
then
|
||||
vel = float_up(self, vel)
|
||||
acc.x, acc.z = handle_control(self, vel)
|
||||
self.object:setvelocity(vel)
|
||||
elseif on_water --if on water
|
||||
then
|
||||
acc.y, vel = swim(self, vel)
|
||||
self.object:setvelocity(vel)
|
||||
acc.x, acc.z = handle_control(self, vel)
|
||||
elseif in_air
|
||||
then
|
||||
--allow controls and height change
|
||||
acc.y = get_vertical_acceleration(self)
|
||||
acc.x, acc.z = handle_control(self, vel)
|
||||
else --if on ground
|
||||
--only allow height change
|
||||
acc.y = get_vertical_acceleration(self)
|
||||
vel.x = 0
|
||||
vel.z = 0
|
||||
self.object:setvelocity(vel)
|
||||
end
|
||||
self.object:setacceleration(acc)
|
||||
end
|
BIN
hot_air_balloons/screenshot.png
Normal file
BIN
hot_air_balloons/screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 678 KiB |
BIN
hot_air_balloons/textures/hot_air_balloons_balloon.png
Normal file
BIN
hot_air_balloons/textures/hot_air_balloons_balloon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 299 B |
BIN
hot_air_balloons/textures/hot_air_balloons_balloon_model.png
Normal file
BIN
hot_air_balloons/textures/hot_air_balloons_balloon_model.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 114 KiB |
BIN
hot_air_balloons/textures/hot_air_balloons_flame.png
Normal file
BIN
hot_air_balloons/textures/hot_air_balloons_flame.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 248 B |
Loading…
x
Reference in New Issue
Block a user