worked on griefing protection
This commit is contained in:
parent
bd16bb256d
commit
3b5d346e1c
129
random_buildings/griefing_tool.lua
Normal file
129
random_buildings/griefing_tool.lua
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- TODO: town angeben
|
||||||
|
|
||||||
|
minetest.register_tool( "random_buildings:griefing_tool",
|
||||||
|
{
|
||||||
|
description = "building modification liszence",
|
||||||
|
groups = {},
|
||||||
|
inventory_image = "default_tool_steelaxe.png", --TODO
|
||||||
|
wield_image = "",
|
||||||
|
wield_scale = {x=1,y=1,z=1},
|
||||||
|
stack_max = 1, -- it has to store information - thus only one can be stacked
|
||||||
|
liquids_pointable = true, -- it may be necessary to remove water sources
|
||||||
|
-- TODO
|
||||||
|
tool_capabilities = {
|
||||||
|
full_punch_interval = 1.0,
|
||||||
|
max_drop_level=0,
|
||||||
|
groupcaps={
|
||||||
|
-- For example:
|
||||||
|
fleshy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1},
|
||||||
|
snappy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1},
|
||||||
|
choppy={times={[3]=0.90}, maxwear=0.05, maxlevel=0}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
node_placement_prediction = nil,
|
||||||
|
metadata = minetest.serialize( {x=0,y=0,z=0,village='?',usages=5,owner='?'} ), -- information about the village for which this tool is valid
|
||||||
|
|
||||||
|
|
||||||
|
-- give information about the liscense
|
||||||
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
|
|
||||||
|
local name = placer:get_player_name();
|
||||||
|
local item = itemstack:to_table();
|
||||||
|
local data = minetest.deserialize( item[ "metadata" ] or {});
|
||||||
|
|
||||||
|
-- do not replace if there is nothing to be done
|
||||||
|
if( not( data ) or not( data[ village ] )) then
|
||||||
|
|
||||||
|
minetest.chat_send_player( name, "This building modification liscense is invalid! Please destroy it.");
|
||||||
|
|
||||||
|
elseif( data.village ) then
|
||||||
|
|
||||||
|
--minetest.chat_send_player( name, "Node already is '"..( item[ "metadata"] or "?" ).."'. Nothing to do.");
|
||||||
|
minetest.chat_send_player( name, "This special building modification liscense, issued by the the village called "..tostring( data.village )..
|
||||||
|
", located at "..minetest.pos_to_string( {x=data.x, y=data.y, z=data.z} )..", grants "..tostring( data.owner )..
|
||||||
|
" the right to remove up to "..tostring( data.usages ).." blocks in said village.");
|
||||||
|
|
||||||
|
elseif( data.general ) then
|
||||||
|
|
||||||
|
minetest.chat_send_player( name, "This general building modification liscense grants "..tostring( data.owner )..
|
||||||
|
" the right to remove up to "..tostring( data.usages ).." blocks of houses from lumberjacks or clay traders.");
|
||||||
|
|
||||||
|
else
|
||||||
|
minetest.chat_send_player( name, "Error: This building modification liscense is neither special nor general. Please destroy it.");
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- remove the protection on a node and dig it immediately
|
||||||
|
on_use = function(itemstack, user, pointed_thing)
|
||||||
|
|
||||||
|
if( user == nil or pointed_thing == nil) then
|
||||||
|
return nil;
|
||||||
|
end
|
||||||
|
local name = user:get_player_name();
|
||||||
|
|
||||||
|
if( pointed_thing.type ~= "node" ) then
|
||||||
|
minetest.chat_send_player( name, " Error: No node.");
|
||||||
|
return nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
local pos = minetest.get_pointed_thing_position( pointed_thing, above );
|
||||||
|
local node = minetest.env:get_node_or_nil( pos );
|
||||||
|
|
||||||
|
if( node == nil ) then
|
||||||
|
|
||||||
|
minetest.chat_send_player( name, "Error: Target node not yet loaded. Please wait a moment for the server to catch up.");
|
||||||
|
return nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
local item = itemstack:to_table();
|
||||||
|
local data = minetest.deserialize( item[ "metadata" ] or {});
|
||||||
|
|
||||||
|
local meta = minetest.env:get_meta( pos );
|
||||||
|
|
||||||
|
if( not(meta) or not( data ) or (not( data[ village ] ) and not(data[general])) or not( data[ owner ])) then
|
||||||
|
minetest.chat_send_player( name, "This building modification liscense is invalid! Please destroy it.");
|
||||||
|
return nil;
|
||||||
|
end
|
||||||
|
|
||||||
|
local protection = random_buildings.is_protected( pos, node, digger, data );
|
||||||
|
|
||||||
|
if( protection == 0) then
|
||||||
|
|
||||||
|
minetest.chat_send_player( name, "Your building modification liscence is not needed here.");
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
-- the node is protected - and this liscence allows to modifiy it
|
||||||
|
elseif( protection == -1 ) then
|
||||||
|
|
||||||
|
-- remember that this liscense has been used one more times
|
||||||
|
data.usages = data.usages - 1;
|
||||||
|
|
||||||
|
item[ 'metadata' ] = minetest.serialize( data );
|
||||||
|
|
||||||
|
minetest.chat_send_player( name, 'Your building modification liscence allows you to modify this node. You can now dig it.');
|
||||||
|
|
||||||
|
if( data.usages < 1 ) then
|
||||||
|
-- TODO: destroy the liscence if it got used up
|
||||||
|
end
|
||||||
|
|
||||||
|
-- an error occoured or the liszcence is not valid here (random_buildings.is_protected already printed an error message)
|
||||||
|
else
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- mese wrapped in paper - the mese is the payment for the blocks the player will later take
|
||||||
|
minetest.register_craft({
|
||||||
|
output = 'random_buildings:griefing_tool',
|
||||||
|
recipe = {
|
||||||
|
{ 'default:paper' },
|
||||||
|
{ 'default:mese' },
|
||||||
|
}
|
||||||
|
})
|
@ -1,9 +1,25 @@
|
|||||||
|
|
||||||
|
|
||||||
|
-- sends a message to the digger if the node is part of a house owned by an npc
|
||||||
|
-- 2 in case of error
|
||||||
|
-- 1 if the player is not allowed to change the node
|
||||||
|
-- returns 0 if the node is not protected
|
||||||
|
-- -1 if the player is allowed to change the node anyway (due to a liszence)
|
||||||
|
random_buildings.is_protected = function( pos, node, digger, data )
|
||||||
|
|
||||||
|
if( pos == nil ) then
|
||||||
|
minetest.chat_send_player(digger:get_player_name(), 'Error: No position given for house protection check.');
|
||||||
|
return 2; -- error: state could not be determined
|
||||||
|
end
|
||||||
|
|
||||||
random_buildings.orig_node_dig = minetest.node_dig;
|
if( node == nil ) then
|
||||||
function minetest.node_dig(pos, node, digger)
|
node = minetest.env:get_node( pos );
|
||||||
|
end
|
||||||
|
|
||||||
|
if( node == nil or node.name == 'ignore' ) then
|
||||||
|
minetest.chat_send_player(digger:get_player_name(), 'Please wait a moment. Area not yet loaded.');
|
||||||
|
return 2; -- error: state could not be determined
|
||||||
|
end
|
||||||
|
|
||||||
local meta = {};
|
local meta = {};
|
||||||
|
|
||||||
@ -14,38 +30,76 @@ function minetest.node_dig(pos, node, digger)
|
|||||||
meta = minetest.env:get_meta( pos );
|
meta = minetest.env:get_meta( pos );
|
||||||
end
|
end
|
||||||
|
|
||||||
if( meta ) then
|
-- definitely not owned by an npc
|
||||||
|
if( not( meta )) then
|
||||||
|
return 0;
|
||||||
|
end
|
||||||
|
|
||||||
local owner_info = meta:get_string( 'owner_info');
|
-- has meta info bit is not owned by an npc
|
||||||
if( owner_info ~= nil and owner_info ~= '' ) then
|
local owner_info = meta:get_string( 'owner_info');
|
||||||
|
if( not( owner_info ) or owner_info == '' ) then
|
||||||
|
return 0;
|
||||||
|
end
|
||||||
|
|
||||||
local chest_pos = minetest.deserialize( owner_info );
|
-- the information about the owner is stored in the building chest - and there is no guarantee that that area is loaded
|
||||||
|
local chest_pos = minetest.deserialize( owner_info );
|
||||||
|
|
||||||
local chest_node = minetest.env:get_node( chest_pos );
|
local chest_node = minetest.env:get_node( chest_pos );
|
||||||
|
|
||||||
if( chest_node == nil or chest_node.name == 'ignore' ) then
|
if( chest_node == nil or chest_node.name == 'ignore' ) then
|
||||||
minetest.chat_send_player(digger:get_player_name(), 'This building is owned by someone. '..
|
|
||||||
|
minetest.chat_send_player(digger:get_player_name(), 'This building is owned by someone. '..
|
||||||
'Please wait a moment and dig this node again to find out by whom it is owned.');
|
'Please wait a moment and dig this node again to find out by whom it is owned.');
|
||||||
return false;
|
return 1; -- this is protected - even though we don't know yet by whom
|
||||||
end
|
end
|
||||||
|
|
||||||
local chest_meta = minetest.env:get_meta( chest_pos );
|
local chest_meta = minetest.env:get_meta( chest_pos );
|
||||||
local owner_name = chest_meta:get_string( 'owner' );
|
local owner_name = chest_meta:get_string( 'owner' );
|
||||||
local village = chest_meta:get_string( 'village' );
|
local village = chest_meta:get_string( 'village' );
|
||||||
local village_pos = minetest.deserialize( chest_meta:get_string( 'village_pos' ));
|
local village_pos = minetest.deserialize( chest_meta:get_string( 'village_pos' ));
|
||||||
|
|
||||||
|
|
||||||
-- TODO: check if a liscense is in the inv of the player
|
-- lone traders like lumberjacks or clay traders who live on their own outside villages
|
||||||
minetest.chat_send_player(digger:get_player_name(), 'This building is owned by '..( owner_name or ' (someone) ')..
|
if( not( village ) or not( village_pos )) then
|
||||||
|
|
||||||
|
-- check if a general liscense is in the inv of the player (for this, check data )
|
||||||
|
if( data and data.usages > 0 and data.owner == digger:get_player_name()) then
|
||||||
|
|
||||||
|
meta:set_string( 'owner_info', nil ); -- delete the protection
|
||||||
|
return -1; -- this way, the liscence knows that it has been used
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.chat_send_player(digger:get_player_name(), 'This building is owned by '..( owner_name or ' (someone) ')..
|
||||||
|
'. You need a general building modification liscence in order to remove this node.');
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
-- check if a fitting liscense is used (for this, check data )
|
||||||
|
if( data and data.usages > 0 and data.owner == digger:get_player_name()
|
||||||
|
and data.x == village_pos.x and data.y == village_pos.y and data.z == village_pos.z ) then
|
||||||
|
|
||||||
|
meta:set_string( 'owner_info', nil ); -- delete the protection
|
||||||
|
return -1; -- this way, the liscence knows that it has been used
|
||||||
|
end
|
||||||
|
minetest.chat_send_player(digger:get_player_name(), 'This building is owned by '..( owner_name or ' (someone) ')..
|
||||||
', who lives in the village '..( village or '(unknown)' )..
|
', who lives in the village '..( village or '(unknown)' )..
|
||||||
'. You need a special building modification liscence - obtainable at the village center at '..
|
'. You need a special building modification liscence - obtainable at the village center at '..
|
||||||
minetest.pos_to_string( {x=village_pos.x,y=village_pos.y,z=village_pos.z} )..
|
minetest.pos_to_string( {x=village_pos.x,y=village_pos.y,z=village_pos.z} )..
|
||||||
-- ..minetest.pos_to_string( minetest.deserialize( village_pos or {}))
|
-- ..minetest.pos_to_string( minetest.deserialize( village_pos or {}))
|
||||||
' - in order to remove this node.'); --..' chest_pos: '..tostring( minetest.serialize( chest_pos )));
|
' - in order to remove this node.'); --..' chest_pos: '..tostring( minetest.serialize( chest_pos )));
|
||||||
return false;
|
return 1;
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- protect npc houses against griefing
|
||||||
|
random_buildings.orig_node_dig = minetest.node_dig;
|
||||||
|
function minetest.node_dig(pos, node, digger)
|
||||||
|
|
||||||
|
if( random_buildings.is_protected( pos, node, digger )==0) then
|
||||||
|
|
||||||
|
return random_buildings.orig_node_dig(pos, node, digger, nil);
|
||||||
end
|
end
|
||||||
|
|
||||||
return random_buildings.orig_node_dig(pos, node, digger);
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user