2019-03-10 18:46:46 +01:00
-- aviator, place block and fly, now also TNT resistant
2017-02-06 20:32:11 +07:00
aviation = { }
2017-02-07 15:26:30 +07:00
aviator_hud_id = { }
2017-02-13 15:12:46 +07:00
2019-03-10 18:46:46 +01:00
local getsetting = tonumber ( ( minetest.settings : get ( " active_block_range " ) ) or 1 ) * 32
2017-05-10 13:29:07 +02:00
local flength = 1800 -- how many seconds you can fly
2018-11-11 15:57:37 +01:00
local checktime = 1 -- check interval
local maxdistance = 50 -- maxradius
2017-02-06 20:32:11 +07:00
local timer = 0
2019-01-12 17:33:22 +01:00
local trans = true -- no permanent forceload block if server shuts down
2018-11-11 15:57:37 +01:00
local force = false
2019-03-10 18:46:46 +01:00
if minetest.get_modpath ( " mesecons_mvps " ) then -- pull and push resistant
mesecon.register_mvps_stopper ( " aviator:aviator " )
end
2018-11-11 15:57:37 +01:00
if maxdistance > getsetting then force = true end
2017-05-10 13:29:07 +02:00
2017-02-06 20:32:11 +07:00
2017-02-13 15:12:46 +07:00
local function aviator_remove ( pos , player )
local name = player : get_player_name ( )
if aviation [ name ] ~= nil then
local items = ItemStack ( " aviator:aviator 1 " )
local meta = minetest.deserialize ( items : get_metadata ( ) ) or { }
local ntime = minetest.get_node_timer ( aviation [ name ] )
local timeout = ntime : get_timeout ( )
local elapsed = ntime : get_elapsed ( )
local inv = minetest.get_inventory ( { type = " player " , name = name } )
local privs = minetest.get_player_privs ( name )
if vector.distance ( pos , aviation [ name ] ) == 0 then
meta.runtime = timeout - elapsed
items : set_metadata ( minetest.serialize ( meta ) )
inv : add_item ( " main " , items )
ntime : stop ( )
if aviator_hud_id [ name ] then
player : hud_remove ( aviator_hud_id [ name ] )
end
privs.fly = nil
minetest.set_player_privs ( name , privs )
minetest.set_node ( aviation [ name ] , { name = " air " } )
aviation [ name ] = nil
2018-11-11 15:57:37 +01:00
if force then core.forceload_free_block ( pos , trans ) end
2017-02-13 15:12:46 +07:00
end
end
return
end
2017-02-14 15:22:56 +07:00
if minetest.get_modpath ( " technic " ) and minetest.get_modpath ( " moreores " ) then
minetest.register_craft ( {
output = ' aviator:aviator ' ,
recipe = {
{ " moreores:mithril_ingot " , ' default:diamond ' , " moreores:mithril_ingot " } ,
{ ' default:diamond ' , " technic:uranium35_ingot " , ' default:diamond ' } ,
{ " moreores:mithril_ingot " , ' default:diamond ' , " moreores:mithril_ingot " } ,
}
} )
2018-11-11 15:57:37 +01:00
elseif minetest.get_modpath ( " basic_machines " ) then
-- do it with constructor !
basic_machines.craft_recipes [ " aviator " ] = { item = " aviator:aviator " , description = " let you fly " .. math.floor ( flength / 60 ) .. " min in an area of " .. maxdistance .. " nodes " , craft = { " default:diamondblock 256 " , " basic_machines:power_rod 25 " , " default:mese 256 " , " basic_machines:keypad " } , tex = " aviator_aviator_side " }
table.insert ( basic_machines.craft_recipe_order , " aviator " )
basic_machines.hardness [ " aviator:aviator " ] = 999999
2017-02-14 15:22:56 +07:00
else
minetest.register_craft ( {
output = ' aviator:aviator ' ,
recipe = {
{ " default:gold_ingot " , ' default:diamond ' , " default:gold_ingot " } ,
{ ' default:diamond ' , " default:diamondblock " , ' default:diamond ' } ,
{ " default:gold_ingot " , ' default:diamond ' , " default:gold_ingot " } ,
}
} )
end
2017-02-06 20:32:11 +07:00
minetest.register_node ( " aviator:aviator " , {
2017-05-03 19:22:32 +02:00
description = " aviation device, fly priv for " .. ( flength / 60 ) .. " min " ,
2017-02-09 13:34:03 +07:00
tiles = { " aviator_aviator_top.png " ,
" aviator_aviator_bottom.png " ,
" aviator_aviator_side.png " ,
" aviator_aviator_side.png " ,
" aviator_aviator_side.png " ,
" aviator_aviator_side.png " } ,
2017-02-06 20:32:11 +07:00
is_ground_content = false ,
2017-02-13 15:12:46 +07:00
diggable = true ,
groups = { oddly_breakable_by_hand = 3 } ,
2017-02-09 13:34:03 +07:00
light_source = 12 ,
2019-03-10 18:46:46 +01:00
on_blast = function ( ) end , -- TNT resistant
2017-02-06 20:32:11 +07:00
on_place = function ( itemstack , placer , pointed_thing )
local name = placer : get_player_name ( )
2017-02-13 15:12:46 +07:00
local meta = minetest.deserialize ( itemstack : get_metadata ( ) ) or { }
2017-02-06 20:32:11 +07:00
if not aviation [ name ] then
local timer = minetest.get_node_timer ( pointed_thing.above )
minetest.set_node ( pointed_thing.above , { name = " aviator:aviator " } )
itemstack : take_item ( )
aviation [ name ] = pointed_thing.above
2018-11-11 15:57:37 +01:00
if force then
if core.forceload_block ( pointed_thing.above , trans ) == false then
-- minetest.chat_send_all("Forceload Error")
end
2017-05-10 13:29:07 +02:00
end
2017-02-13 15:12:46 +07:00
if not meta.runtime then
timer : start ( flength )
else
timer : start ( meta.runtime )
meta = { }
itemstack : set_metadata ( minetest.serialize ( meta ) )
end
2017-02-06 20:32:11 +07:00
else
2017-02-07 15:26:30 +07:00
minetest.chat_send_player ( name , core.colorize ( ' #eeee00 ' , " You placed already one Aviator at: " .. aviation [ name ] . x .. " , " .. aviation [ name ] . y .. " , " .. aviation [ name ] . z ) )
2017-02-06 20:32:11 +07:00
end
return itemstack
2017-02-13 15:12:46 +07:00
end ,
2017-02-06 20:32:11 +07:00
2017-02-13 15:12:46 +07:00
on_dig = function ( pos , node , player )
aviator_remove ( pos , player )
end ,
2017-02-06 20:32:11 +07:00
2017-02-13 15:12:46 +07:00
after_dig_node = function ( pos , oldnode , oldmetadata , digger )
local name = digger : get_player_name ( )
local ctime = minetest.get_node_timer ( pos )
if aviation [ name ] ~= nil or ctime : is_started ( ) then
local inv = minetest.get_inventory ( { type = " player " , name = name } )
local items = ItemStack ( " aviator:aviator 1 " )
inv : remove_item ( " main " , items )
minetest.set_node ( pos , oldnode )
end
2017-02-14 15:22:56 +07:00
end
2017-02-06 20:32:11 +07:00
} )
2017-02-14 15:22:56 +07:00
2017-02-06 20:32:11 +07:00
minetest.register_globalstep ( function ( dtime )
timer = timer + dtime
if timer >= checktime then
2017-02-13 15:12:46 +07:00
local players = minetest.get_connected_players ( ) ;
2017-02-06 20:32:11 +07:00
for _ , player in pairs ( players ) do
2017-02-13 15:12:46 +07:00
local name = player : get_player_name ( )
if aviation [ name ] ~= nil and aviation [ name ] ~= { } then
2017-02-06 20:32:11 +07:00
local pos = player : getpos ( )
local ntime = minetest.get_node_timer ( aviation [ name ] )
local timeout = ntime : get_timeout ( )
local elapsed = ntime : get_elapsed ( )
local leftover = timeout - elapsed
local distance = math.floor ( vector.distance ( pos , aviation [ name ] ) )
local privs = minetest.get_player_privs ( name )
2017-02-07 15:26:30 +07:00
if aviator_hud_id [ name ] then
player : hud_remove ( aviator_hud_id [ name ] )
end
2017-02-06 20:32:11 +07:00
if timeout > 0 then
if distance <= maxdistance then
2017-02-13 15:12:46 +07:00
privs.fly = true
minetest.set_player_privs ( name , privs )
2017-02-06 20:32:11 +07:00
else
2017-02-13 15:12:46 +07:00
if distance > maxdistance and distance < ( maxdistance + 10 ) then
2017-02-14 15:22:56 +07:00
player : hud_remove ( aviator_hud_id [ name ] )
aviator_hud_id [ name ] = player : hud_add ( {
hud_elem_type = " text " ;
position = { x = 0.5 , y = 0.80 } ;
text = " >>> Warning, you left fly area <<< " ; number = 0xFFFF00 ; } )
leftover = - 1
end
if distance > ( maxdistance + 10 ) then
player : hud_remove ( aviator_hud_id [ name ] )
aviator_remove ( aviation [ name ] , player )
leftover = - 1
2017-02-13 15:12:46 +07:00
end
privs.fly = nil
minetest.set_player_privs ( name , privs )
2017-02-06 20:32:11 +07:00
end
2017-02-07 15:26:30 +07:00
if leftover > 10 then
2017-02-14 15:22:56 +07:00
if aviator_hud_id [ name ] then
player : hud_remove ( aviator_hud_id [ name ] )
end
2017-02-07 15:26:30 +07:00
aviator_hud_id [ name ] = player : hud_add ( {
hud_elem_type = " text " ;
position = { x = 0.5 , y = 0.80 } ;
2017-02-13 15:12:46 +07:00
text = " >>> " .. math.floor ( leftover / 60 ) .. " minutes left, Distance: " .. distance .. " <<< " ; number = 0xFFFF00 ; } )
2017-02-07 15:26:30 +07:00
end
2017-02-14 15:22:56 +07:00
if leftover <= 10 and leftover > 0 then
2017-02-07 15:26:30 +07:00
aviator_hud_id [ name ] = player : hud_add ( {
hud_elem_type = " text " ;
position = { x = 0.5 , y = 0.45 } ;
text = " >>> " .. leftover .. " <<< " ;
number = 0xFFFF00 ; } )
2017-02-13 15:12:46 +07:00
end
2017-02-06 20:32:11 +07:00
else
2017-02-07 15:26:30 +07:00
if aviator_hud_id [ name ] then
player : hud_remove ( aviator_hud_id [ name ] )
end
2017-02-06 20:32:11 +07:00
privs.fly = nil
minetest.set_player_privs ( name , privs )
minetest.set_node ( aviation [ name ] , { name = " air " } )
aviation [ name ] = nil
2017-02-13 15:12:46 +07:00
end
end
end
2017-02-06 20:32:11 +07:00
timer = 0
end
end )
2017-02-14 15:22:56 +07:00
-- add aviator to inventory if any
2017-02-06 20:32:11 +07:00
minetest.register_on_leaveplayer ( function ( player )
local name = player : get_player_name ( )
if aviation [ name ] ~= nil then
local privs = minetest.get_player_privs ( name )
privs.fly = nil
minetest.set_player_privs ( name , privs )
2017-02-13 15:12:46 +07:00
aviator_remove ( aviation [ name ] , player )
2017-02-06 20:32:11 +07:00
aviation [ name ] = nil
end
end )
2017-02-13 15:12:46 +07:00
2017-02-14 15:22:56 +07:00
-- still someone with fly priv ? strange.
2017-02-07 15:26:30 +07:00
minetest.register_on_joinplayer ( function ( player )
local name = player : get_player_name ( )
local privs = minetest.get_player_privs ( name )
2017-02-13 15:12:46 +07:00
2017-02-07 15:26:30 +07:00
if privs.fly and not privs.server then
privs.fly = nil
minetest.set_player_privs ( name , privs )
end
end )
2017-02-13 15:12:46 +07:00
2017-02-14 15:22:56 +07:00
-- add aviator to inventory if any
2017-02-13 15:12:46 +07:00
minetest.register_on_shutdown ( function ( )
local players = minetest.get_connected_players ( )
for _ , player in pairs ( players ) do
local name = player : get_player_name ( )
if aviation [ name ] ~= nil then
local privs = minetest.get_player_privs ( name )
privs.fly = nil
minetest.set_player_privs ( name , privs )
aviator_remove ( aviation [ name ] , player )
aviation [ name ] = nil
end
end
end )
2017-05-03 19:22:32 +02:00
-- add chatcommand to call back aviator
minetest.register_chatcommand ( " 7 " , {
params = " " ,
description = " Calls your aviator back to inventory " ,
privs = { interact = true } ,
func = function ( name , param )
local player = minetest.get_player_by_name ( name )
if aviation [ name ] ~= nil then
2018-11-11 15:57:37 +01:00
2017-05-03 19:22:32 +02:00
aviator_remove ( aviation [ name ] , player )
2018-11-11 15:57:37 +01:00
2017-05-03 19:22:32 +02:00
else
2018-11-11 15:57:37 +01:00
local colorstring = core.colorize ( ' #ff0000 ' , " >>> you did not place an aviator " )
minetest.chat_send_player ( name , colorstring )
2017-05-03 19:22:32 +02:00
end
end
} )
2017-02-13 15:12:46 +07:00