227 lines
5.9 KiB
Lua
227 lines
5.9 KiB
Lua
|
--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 function get_fuel_value(item)
|
||
|
input = {
|
||
|
method = "fuel",
|
||
|
items = {item},
|
||
|
}
|
||
|
return minetest.get_craft_result(input).time or 0
|
||
|
end
|
||
|
|
||
|
local add_heat = function(self, player)
|
||
|
local item_stack = player:get_wielded_item()
|
||
|
local fuelval = get_fuel_value(item_stack)
|
||
|
if not fuelval or fuelval == 0 then
|
||
|
return false
|
||
|
end
|
||
|
local heat = self.heat
|
||
|
heat = heat + 30 * fuelval --for coal lump 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,
|
||
|
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")
|