diff --git a/minetest.conf.example b/minetest.conf.example index b5466bc..5d58286 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -137,6 +137,8 @@ #default_privs = build, shout # enable a static spawnpoint (default unset) #static_spawnpoint = (0,0,0) +# the protection radius of borderstone +#borderstone_radius = 5 # Profiler data print interval. #0 = disable. #profiler_print_interval = 0 diff --git a/src/content_craft.cpp b/src/content_craft.cpp index cbbdda0..27bcdde 100644 --- a/src/content_craft.cpp +++ b/src/content_craft.cpp @@ -107,7 +107,7 @@ struct CraftDef { */ InventoryItem *craft_get_result(InventoryItem **items) { - static CraftDef defs[32]; + static CraftDef defs[33]; static int defs_init = 0; // only initialise (and hence allocate) these once diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index 8d777ee..d34dc3f 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -345,9 +345,11 @@ void content_mapnode_init() i = CONTENT_BORDERSTONE; f = &content_features(i); f->setAllTextures("borderstone.png"); - f->setInventoryTextureCube("morderstone.png", "borderstone.png", "borderstone.png"); + f->setInventoryTextureCube("borderstone.png", "borderstone.png", "borderstone.png"); f->is_ground_content = true; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; + if(f->initial_metadata == NULL) + f->initial_metadata = new BorderStoneNodeMetadata(); setStoneLikeDiggingProperties(f->digging_properties, 2.0); i = CONTENT_WOOD; diff --git a/src/content_nodemeta.cpp b/src/content_nodemeta.cpp index e15cec9..5ba9e4a 100644 --- a/src/content_nodemeta.cpp +++ b/src/content_nodemeta.cpp @@ -182,6 +182,44 @@ std::string LockingChestNodeMetadata::getInventoryDrawSpecString() "list[current_player;main;0,5;8,4;]"; } +/* + BorderStoneNodeMetadata +*/ + +// Prototype +BorderStoneNodeMetadata proto_BorderStoneNodeMetadata; + +BorderStoneNodeMetadata::BorderStoneNodeMetadata() +{ + NodeMetadata::registerType(typeId(), create); +} +BorderStoneNodeMetadata::~BorderStoneNodeMetadata() +{ +} +u16 BorderStoneNodeMetadata::typeId() const +{ + return CONTENT_BORDERSTONE; +} +NodeMetadata* BorderStoneNodeMetadata::create(std::istream &is) +{ + BorderStoneNodeMetadata *d = new BorderStoneNodeMetadata(); + d->setOwner(deSerializeString(is)); + return d; +} +NodeMetadata* BorderStoneNodeMetadata::clone() +{ + BorderStoneNodeMetadata *d = new BorderStoneNodeMetadata(); + return d; +} +void BorderStoneNodeMetadata::serializeBody(std::ostream &os) +{ + os<setDefault("give_initial_stuff", "false"); settings->setDefault("default_password", ""); settings->setDefault("default_privs", "build, shout"); + settings->setDefault("borderstone_radius","5"); settings->setDefault("profiler_print_interval", "0"); settings->setDefault("enable_mapgen_debug_info", "false"); diff --git a/src/server.cpp b/src/server.cpp index a988a59..1c4dad2 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2477,6 +2477,25 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) <<" because privileges are "<getS16("borderstone_radius"); + v3s16 test_p; + MapNode testnode; + for(s16 z=-max_d; !cannot_remove_node && z<=max_d; z++) { + for(s16 y=-max_d; !cannot_remove_node && y<=max_d; y++) { + for(s16 x=-max_d; !cannot_remove_node && x<=max_d; x++) { + test_p = p_under + v3s16(x,y,z); + NodeMetadata *meta = m_env.getMap().getNodeMetadata(test_p); + if (meta && meta->typeId() == CONTENT_BORDERSTONE) { + BorderStoneNodeMetadata *bsm = (BorderStoneNodeMetadata*)meta; + if (bsm->getOwner() != player->getName()) { + cannot_remove_node = true; + break; + } + } + } + } + } } /* @@ -2727,6 +2746,23 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) if(item == NULL) return; + s16 max_d = g_settings->getS16("borderstone_radius"); + v3s16 test_p; + MapNode testnode; + for(s16 z=-max_d; z<=max_d; z++) { + for(s16 y=-max_d; y<=max_d; y++) { + for(s16 x=-max_d; x<=max_d; x++) { + test_p = p_over + v3s16(x,y,z); + NodeMetadata *meta = m_env.getMap().getNodeMetadata(test_p); + if (meta && meta->typeId() == CONTENT_BORDERSTONE) { + BorderStoneNodeMetadata *bsm = (BorderStoneNodeMetadata*)meta; + if (bsm->getOwner() != player->getName()) + return; + } + } + } + } + /* Handle material items */ @@ -2775,6 +2811,26 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) MapNode n; n.setContent(mitem->getMaterial()); + // don't allow borderstone to be place near another player's borderstone + if (n.getContent() == CONTENT_BORDERSTONE) { + s16 max_d = g_settings->getS16("borderstone_radius")*2; + v3s16 test_p; + MapNode testnode; + for(s16 z=-max_d; z<=max_d; z++) { + for(s16 y=-max_d; y<=max_d; y++) { + for(s16 x=-max_d; x<=max_d; x++) { + test_p = p_over + v3s16(x,y,z); + NodeMetadata *meta = m_env.getMap().getNodeMetadata(test_p); + if (meta && meta->typeId() == CONTENT_BORDERSTONE) { + BorderStoneNodeMetadata *bsm = (BorderStoneNodeMetadata*)meta; + if (bsm->getOwner() != player->getName()) + return; + } + } + } + } + } + actionstream<getName()<<" places material " <<(int)mitem->getMaterial() <<" at "<