310 lines
10 KiB
Lua
310 lines
10 KiB
Lua
|
|
|
|
------------------------
|
|
-- initialization
|
|
------------------------
|
|
-- only players with this priv are able to expand the platform with the expander
|
|
minetest.register_privilege("skyplatform", { description = "allows to expand the skyplatform", give_to_singleplayer = true});
|
|
|
|
skyplatform = {}
|
|
|
|
dofile(minetest.get_modpath( 'skyplatform' ).."/config.lua")
|
|
|
|
|
|
-- override mapgen and set it to singlenode/air
|
|
minetest.set_mapgen_params( { mgname = 'singlenode', seed = 1, water_level = 0, flags = air});
|
|
|
|
|
|
for k,v in pairs( skyplatform.replacements ) do
|
|
-- make sure the chests are replaced with expanders
|
|
table.insert( skyplatform.replacements[ k ], {'default:chest', 'skyplatform:expand' } );
|
|
end
|
|
|
|
|
|
------------------------
|
|
-- functions
|
|
------------------------
|
|
skyplatform.update_formspec = function( pos )
|
|
if( not( pos )) then
|
|
return;
|
|
end
|
|
|
|
-- create the formspec once
|
|
if( not( skyplatform.formspec )) then
|
|
|
|
skyplatform.formspec = "size[12,10]"..
|
|
"label[3.3,0.0;Land expander for skyplatform]"..
|
|
"textarea[1.0,1.6;10,0.8;info;info;Click on one of the options in order to expand the platform.]";
|
|
local x = 0;
|
|
local y = 0;
|
|
local i = 0;
|
|
for k,v in pairs( skyplatform.replacements ) do
|
|
i = i+1;
|
|
|
|
-- new column
|
|
if( y==8 ) then
|
|
x = x+4;
|
|
y = 0;
|
|
end
|
|
skyplatform.formspec = skyplatform.formspec .."button_exit["..(x)..","..(y+2.5)..";4,0.5;replace;"..k.."]";
|
|
y = y+1;
|
|
end
|
|
end
|
|
|
|
local meta = minetest.get_meta( pos );
|
|
meta:set_string( 'formspec', skyplatform.formspec );
|
|
end
|
|
|
|
|
|
-- TODO: expand the platform if the player pays i.e. a mese block
|
|
skyplatform.on_receive_fields = function(pos, formname, fields, player)
|
|
|
|
local pname = player:get_player_name();
|
|
|
|
if( not( fields[ 'replace' ] ) or not( skyplatform.replacements[ fields[ 'replace' ]] )) then
|
|
return;
|
|
end
|
|
|
|
if( not( minetest.check_player_privs(player:get_player_name(), {skyplatform=true}))) then
|
|
minetest.chat_send_player( pname, 'You need the skyplatform priv in order to expand this platform.');
|
|
return;
|
|
end
|
|
|
|
local p = {x=pos.x, y=pos.y, z=pos.z};
|
|
-- determine the right position for the schematic that contains the platform
|
|
local node = minetest.get_node( pos );
|
|
|
|
local param2 = node.param2;
|
|
if( param2 == 1 ) then
|
|
p = { x=(pos.x), y=(pos.y-skyplatform.HEIGHT), z=(pos.z-math.floor(skyplatform.SIZE/2)+1)};
|
|
|
|
elseif( param2 == 3 ) then
|
|
p = { x=(pos.x - skyplatform.SIZE+1), y=(pos.y-skyplatform.HEIGHT), z=(pos.z-math.floor(skyplatform.SIZE/2))};
|
|
|
|
elseif( param2 == 2 ) then
|
|
p = { x=(pos.x - math.floor(skyplatform.SIZE/2)+1), y=(pos.y-skyplatform.HEIGHT), z=(pos.z- skyplatform.SIZE+1) };
|
|
|
|
elseif( param2 == 0 ) then
|
|
p = { x=(pos.x - math.floor(skyplatform.SIZE/2)), y=(pos.y-skyplatform.HEIGHT), z=(pos.z) };
|
|
|
|
end
|
|
|
|
|
|
-- build walls around the new platform so that water stays inside and players do not fall from the platform
|
|
local pc = {x=p.x, y=p.y, z=(p.z-1)}; -- corner 1
|
|
node = minetest.get_node( {x=math.floor(pc.x+skyplatform.SIZE/2), y=pc.y, z=pc.z });
|
|
if( param2 ~= 0 and node and node.name and node.name == 'air' ) then
|
|
minetest.place_schematic( pc, skyplatform.WALL, "180", {}, true );
|
|
end
|
|
|
|
pc = {x=p.x, y=p.y, z=(p.z+skyplatform.SIZE)};
|
|
node = minetest.get_node( {x=math.floor(pc.x+skyplatform.SIZE/2), y=pc.y, z=pc.z });
|
|
if( param2 ~= 2 and node and node.name and node.name == 'air' ) then
|
|
minetest.place_schematic( pc, skyplatform.WALL, "0", {}, true );
|
|
end
|
|
|
|
pc = {x=(p.x-1), y=p.y, z=p.z};
|
|
node = minetest.get_node( {x=pc.x, y=pc.y, z=math.floor(pc.z+skyplatform.SIZE/2) });
|
|
if( param2 ~= 1 and node and node.name and node.name == 'air' ) then
|
|
minetest.place_schematic( pc, skyplatform.WALL, "270", {}, true );
|
|
end
|
|
|
|
pc = {x=(p.x+skyplatform.SIZE), y=p.y, z=p.z};
|
|
node = minetest.get_node( {x=pc.x, y=pc.y, z=math.floor(pc.z+skyplatform.SIZE/2) });
|
|
if( param2 ~= 3 and node and node.name and node.name == 'air' ) then
|
|
minetest.place_schematic( pc, skyplatform.WALL, "90", {}, true );
|
|
end
|
|
|
|
|
|
-- remove the wall in front of the player
|
|
repl = { { 'default:cloud', 'air'}, { 'skyblock:horizon', 'air' }, { 'skyblock:expand', 'air' } };
|
|
-- place the schematic while not replacing existing nodes
|
|
minetest.place_schematic( p, skyplatform.SCHEMATIC, "0", skyplatform.replacements[ fields[ 'replace' ]], true );
|
|
|
|
-- TODO: update and initialize skyplatform:expand
|
|
end
|
|
|
|
|
|
-- create a new platform
|
|
skyplatform.new_platform = function( player, height, loopcount )
|
|
|
|
if( not( player ) or not( height ) or height<-30000 or height >30000 or height%100>0 ) then
|
|
return;
|
|
end
|
|
local p = {x=math.floor(0-skyplatform.SIZE/2), y=math.floor(height-skyplatform.HEIGHT+1), z=math.floor(0-skyplatform.SIZE/2)};
|
|
player:setpos( {x=0,y=height+3,z=0} );
|
|
|
|
if( not( loopcount )) then
|
|
loopcount = 0;
|
|
end
|
|
local node = minetest.get_node( {x=0,y=height-2,z=0} );
|
|
--if( height ~= 0 ) then
|
|
if( not( node ) or not( node.name ) or node.name == 'ignore' ) then
|
|
-- abort if there's no success after some time
|
|
if( loopcount > 5 ) then
|
|
minetest.chat_send_player( player:get_player_name(),
|
|
'The place where the skyplatform is supposed to spawn is still '..
|
|
'unloaded. Giving up. Try again later!');
|
|
return;
|
|
end
|
|
minetest.after( 1, skyplatform.new_platform, player, height, loopcount+1 );
|
|
return;
|
|
end
|
|
|
|
if( node and node.name and node.name~='air') then
|
|
if( height ~= 0 ) then
|
|
minetest.chat_send_player( player:get_player_name(),
|
|
'Cannot create a new sky platform at height '..tostring( height)..
|
|
'. Please remove the nodes there first!');
|
|
player:setpos( {x=0, y=height, z=0} );
|
|
end
|
|
return;
|
|
end
|
|
--end
|
|
|
|
-- place the initial sky platform
|
|
minetest.place_schematic( p, skyplatform.SCHEMATIC, "0", skyplatform.replacements[ skyplatform.start_platform_type ], true );
|
|
|
|
-- build walls around the new platform so that water stays inside and players do not fall from the platform
|
|
local pc = {x=p.x, y=p.y, z=(p.z-1)}; -- corner 1
|
|
minetest.place_schematic( pc, skyplatform.WALL, "180", {}, true );
|
|
|
|
pc = {x=p.x, y=p.y, z=(p.z+skyplatform.SIZE)};
|
|
minetest.place_schematic( pc, skyplatform.WALL, "0", {}, true );
|
|
|
|
pc = {x=(p.x-1), y=p.y, z=p.z};
|
|
minetest.place_schematic( pc, skyplatform.WALL, "270", {}, true );
|
|
|
|
pc = {x=(p.x+skyplatform.SIZE), y=p.y, z=p.z};
|
|
minetest.place_schematic( pc, skyplatform.WALL, "90", {}, true );
|
|
|
|
p.y = p.y + 1;
|
|
player:setpos( {x=0, y=height+3, z=0 });
|
|
|
|
minetest.chat_send_player( player:get_player_name(),
|
|
'Successfully created a new sky platform at height '..tostring( height )..'.');
|
|
end
|
|
|
|
|
|
------------------------
|
|
-- node definitions
|
|
------------------------
|
|
-- the chest that offers a formspec and allows to expand the sky platform
|
|
minetest.register_node("skyplatform:expand", {
|
|
description = "Land expander for the skyplatform",
|
|
tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png",
|
|
"default_chest_side.png", "default_chest_side.png", "default_chest_lock.png"},
|
|
paramtype2 = "facedir",
|
|
groups = {choppy=2,oddly_breakable_by_hand=2, not_in_creative_inventory=1},
|
|
legacy_facedir_simple = true,
|
|
is_ground_content = false,
|
|
|
|
on_construct = function(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("infotext", "Land expander for skyplatform. Right-click in order to add more land.");
|
|
skyplatform.update_formspec( pos );
|
|
end,
|
|
|
|
-- normal digging is not possible; trying to do so can be used to update the formspec
|
|
can_dig = function(pos,player)
|
|
minetest.chat_send_player( player:get_player_name(),
|
|
'This expander can only be removed by expanding the area. Right-click it in order to do so.');
|
|
skyplatform.update_formspec( pos );
|
|
return false;
|
|
end,
|
|
|
|
on_receive_fields = function( pos, formname, fields, player )
|
|
return skyplatform.on_receive_fields(pos, formname, fields, player);
|
|
end,
|
|
|
|
--[[
|
|
on_rightclick = function(pos, node, clicker)
|
|
|
|
skyplatform.update_formspec( pos );
|
|
minetest.show_formspec(
|
|
clicker:get_player_name(),
|
|
"default:chest_locked",
|
|
get_locked_chest_formspec(pos)
|
|
)
|
|
end,
|
|
--]]
|
|
})
|
|
|
|
|
|
|
|
-- forms the wall around the platform; similar color as the sky
|
|
minetest.register_node("skyplatform:horizon", {
|
|
description = "Horizon",
|
|
tiles = {"default_cloud.png^[colorize:#0099FF:90"},
|
|
groups = {not_in_creative_inventory=1, immortal=1},
|
|
})
|
|
|
|
|
|
|
|
-----------------------------
|
|
-- handle spawning of players
|
|
-----------------------------
|
|
local function spawnplayer(player)
|
|
if( minetest.setting_get("static_spawnpoint")) then
|
|
return;
|
|
end
|
|
|
|
minetest.set_node( skyplatform.spawn_pos, {name='default:brick'});
|
|
player:setpos( skyplatform.spawn_pos );
|
|
skyplatform.new_platform( player, 0, 0 );
|
|
end
|
|
|
|
minetest.register_on_newplayer(function(player)
|
|
spawnplayer(player)
|
|
end)
|
|
|
|
minetest.register_on_respawnplayer(function(player)
|
|
spawnplayer(player)
|
|
return true
|
|
end)
|
|
|
|
|
|
|
|
----------------------------
|
|
-- chat commands
|
|
----------------------------
|
|
-- create a new sky platform at a new height
|
|
minetest.register_chatcommand( 'newskyplatform', {
|
|
description = "Creates a new sky platform at the given height. Requires the skyplatform priv.",
|
|
params = '<height>',
|
|
privs = {skyplatform=true},
|
|
func = function(name, param)
|
|
|
|
if( not( minetest.check_player_privs( name, {skyplatform=true}))) then
|
|
minetest.chat_send_player( name, 'You need the skyplatform priv in order to create a new platform.');
|
|
return;
|
|
end
|
|
|
|
if( not(param) or param=="") then
|
|
minetest.chat_send_player( name, 'At which height do you want your new skyplatform to be? Usage: /skyplatform <height>');
|
|
return;
|
|
end
|
|
|
|
local height = tonumber( param );
|
|
if( height<-30000 or height>30000 or height%100>0 ) then
|
|
minetest.chat_send_player( name, 'Height \''..tostring(height)..
|
|
'\' not supported. Use a value between -30000..30000 that can be divided by 100.');
|
|
return;
|
|
end
|
|
local player = minetest.get_player_by_name( name );
|
|
if( player ) then
|
|
skyplatform.new_platform( player, height, 0 );
|
|
end
|
|
end
|
|
});
|
|
|
|
-- a /spawn command is always useful
|
|
minetest.register_chatcommand( 'spawn', {
|
|
description = "Teleport back to spawn.",
|
|
privs = {},
|
|
func = function(name, param)
|
|
spawnplayer( minetest.get_player_by_name( name ));
|
|
end
|
|
});
|
|
|