From c9adf09e5c41c0a34608a8a4320bb1f7d6a97814 Mon Sep 17 00:00:00 2001 From: darkrose Date: Sun, 23 Jul 2017 16:54:35 +1000 Subject: [PATCH] and now you can seal barrels and pick them up --- src/content_mapnode.h | 6 +- src/content_mapnode_special.cpp | 100 +++++++++++++++++++ src/content_nodemeta.h | 20 +++- src/mapnode.h | 3 + src/nodemeta/content_nodemeta_storage.cpp | 76 +++++++++++++-- src/nodemetadata.h | 3 + src/server.cpp | 114 +++++++++++++++++++++- 7 files changed, 306 insertions(+), 16 deletions(-) diff --git a/src/content_mapnode.h b/src/content_mapnode.h index 1f21997..0171622 100644 --- a/src/content_mapnode.h +++ b/src/content_mapnode.h @@ -124,7 +124,11 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version); #define CONTENT_APPLEWOOD_BARREL 0x043 #define CONTENT_JUNGLEWOOD_BARREL 0x044 #define CONTENT_PINE_BARREL 0x045 -// FREE 0x046-0x07C +#define CONTENT_WOOD_BARREL_SEALED 0x046 +#define CONTENT_APPLEWOOD_BARREL_SEALED 0x047 +#define CONTENT_JUNGLEWOOD_BARREL_SEALED 0x048 +#define CONTENT_PINE_BARREL_SEALED 0x049 +// FREE 0x04A-0x07C // 0x7D-0x7F reserved values, air, ignore, etc #define CONTENT_CHAIR_CENTRE 0x080 #define CONTENT_CHAIR_ENDL 0x081 diff --git a/src/content_mapnode_special.cpp b/src/content_mapnode_special.cpp index 6dbede5..a4070ff 100644 --- a/src/content_mapnode_special.cpp +++ b/src/content_mapnode_special.cpp @@ -979,6 +979,8 @@ void content_mapnode_special(bool repeat) f->initial_metadata = new ReverseCraftGuideNodeMetadata(); f->sound_access = "open-book"; +/* barrels */ + i = CONTENT_WOOD_BARREL; f = &content_features(i); f->description = gettext("Wood Barrel"); @@ -991,6 +993,7 @@ void content_mapnode_special(bool repeat) f->air_equivalent = true; f->flammable = 1; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; + f->special_alternate_node = CONTENT_WOOD_BARREL_SEALED; content_nodebox_barrel(f); f->setInventoryTextureNodeBox(i,"wood.png","wood.png^[transformR90","wood.png^[transformR90"); f->type = CMT_WOOD; @@ -1015,6 +1018,7 @@ void content_mapnode_special(bool repeat) f->air_equivalent = true; f->flammable = 1; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; + f->special_alternate_node = CONTENT_APPLEWOOD_BARREL_SEALED; content_nodebox_barrel(f); f->setInventoryTextureNodeBox(i,"applewood.png","applewood.png^[transformR90","applewood.png^[transformR90"); f->type = CMT_WOOD; @@ -1039,6 +1043,7 @@ void content_mapnode_special(bool repeat) f->air_equivalent = true; f->flammable = 1; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; + f->special_alternate_node = CONTENT_JUNGLEWOOD_BARREL_SEALED; content_nodebox_barrel(f); f->setInventoryTextureNodeBox(i,"junglewood.png","junglewood.png^[transformR90","junglewood.png^[transformR90"); f->type = CMT_WOOD; @@ -1063,6 +1068,7 @@ void content_mapnode_special(bool repeat) f->air_equivalent = true; f->flammable = 1; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; + f->special_alternate_node = CONTENT_PINE_BARREL_SEALED; content_nodebox_barrel(f); f->setInventoryTextureNodeBox(i,"pine.png","pine.png^[transformR90","pine.png^[transformR90"); f->type = CMT_WOOD; @@ -1075,6 +1081,100 @@ void content_mapnode_special(bool repeat) content_list_add("craftguide",i,1,0); content_list_add("creative",i,1,0); +/* sealed barrels */ + + i = CONTENT_WOOD_BARREL_SEALED; + f = &content_features(i); + f->description = gettext("Wood Barrel"); + f->setAllTextures("wood.png^[transformR90"); + f->setAllMetaTextures("water.png",WATER_ALPHA); + f->param_type = CPT_LIGHT; + f->item_param_type = CPT_METADATA; + f->draw_type = CDT_NODEBOX_META; + f->rotate_tile_with_nodebox = true; + f->light_propagates = true; + f->air_equivalent = true; + f->flammable = 1; + f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; + f->special_alternate_node = CONTENT_WOOD_BARREL; + content_nodebox_barrel_sealed(f); + f->setInventoryTextureNodeBox(i,"wood.png","wood.png^[transformR90","wood.png^[transformR90"); + f->type = CMT_WOOD; + f->dig_time = 1.0; + f->pressure_type = CST_SOLID; + f->suffocation_per_second = 0; + if (f->initial_metadata == NULL) + f->initial_metadata = new SealedBarrelNodeMetadata(); + + i = CONTENT_APPLEWOOD_BARREL_SEALED; + f = &content_features(i); + f->description = gettext("Applewood Barrel"); + f->setAllTextures("applewood.png^[transformR90"); + f->setAllMetaTextures("water.png",WATER_ALPHA); + f->param_type = CPT_LIGHT; + f->item_param_type = CPT_METADATA; + f->draw_type = CDT_NODEBOX_META; + f->rotate_tile_with_nodebox = true; + f->light_propagates = true; + f->air_equivalent = true; + f->flammable = 1; + f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; + f->special_alternate_node = CONTENT_APPLEWOOD_BARREL; + content_nodebox_barrel_sealed(f); + f->setInventoryTextureNodeBox(i,"applewood.png","applewood.png^[transformR90","applewood.png^[transformR90"); + f->type = CMT_WOOD; + f->dig_time = 1.0; + f->pressure_type = CST_SOLID; + f->suffocation_per_second = 0; + if (f->initial_metadata == NULL) + f->initial_metadata = new SealedBarrelNodeMetadata(); + + i = CONTENT_JUNGLEWOOD_BARREL_SEALED; + f = &content_features(i); + f->description = gettext("Junglewood Barrel"); + f->setAllTextures("junglewood.png^[transformR90"); + f->setAllMetaTextures("water.png",WATER_ALPHA); + f->param_type = CPT_LIGHT; + f->item_param_type = CPT_METADATA; + f->draw_type = CDT_NODEBOX_META; + f->rotate_tile_with_nodebox = true; + f->light_propagates = true; + f->air_equivalent = true; + f->flammable = 1; + f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; + f->special_alternate_node = CONTENT_JUNGLEWOOD_BARREL; + content_nodebox_barrel_sealed(f); + f->setInventoryTextureNodeBox(i,"junglewood.png","junglewood.png^[transformR90","junglewood.png^[transformR90"); + f->type = CMT_WOOD; + f->dig_time = 1.0; + f->pressure_type = CST_SOLID; + f->suffocation_per_second = 0; + if (f->initial_metadata == NULL) + f->initial_metadata = new SealedBarrelNodeMetadata(); + + i = CONTENT_PINE_BARREL_SEALED; + f = &content_features(i); + f->description = gettext("Pine Barrel"); + f->setAllTextures("pine.png^[transformR90"); + f->setAllMetaTextures("water.png",WATER_ALPHA); + f->param_type = CPT_LIGHT; + f->item_param_type = CPT_METADATA; + f->draw_type = CDT_NODEBOX_META; + f->rotate_tile_with_nodebox = true; + f->light_propagates = true; + f->air_equivalent = true; + f->flammable = 1; + f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; + f->special_alternate_node = CONTENT_PINE_BARREL; + content_nodebox_barrel_sealed(f); + f->setInventoryTextureNodeBox(i,"pine.png","pine.png^[transformR90","pine.png^[transformR90"); + f->type = CMT_WOOD; + f->dig_time = 1.0; + f->pressure_type = CST_SOLID; + f->suffocation_per_second = 0; + if (f->initial_metadata == NULL) + f->initial_metadata = new SealedBarrelNodeMetadata(); + i = CONTENT_FIRE; f = &content_features(i); f->description = gettext("Fire"); diff --git a/src/content_nodemeta.h b/src/content_nodemeta.h index 4bf30ca..07bff7c 100644 --- a/src/content_nodemeta.h +++ b/src/content_nodemeta.h @@ -308,7 +308,6 @@ public: virtual NodeMetadata* clone(); virtual void serializeBody(std::ostream &os); virtual std::wstring infoText(); - virtual bool nodeRemovalDisabled(); virtual std::vector getNodeBoxes(MapNode &n); virtual bool import(NodeMetadata *meta); @@ -316,6 +315,25 @@ public: uint8_t m_water_level; }; +class SealedBarrelNodeMetadata : public NodeMetadata +{ +public: + SealedBarrelNodeMetadata(); + ~SealedBarrelNodeMetadata(); + + virtual u16 typeId() const; + static NodeMetadata* create(std::istream &is); + virtual NodeMetadata* clone(); + virtual void serializeBody(std::ostream &os); + virtual std::wstring infoText(); + virtual uint16_t getData() {return m_water_level;} + virtual void setData(uint16_t v) {m_water_level = v;} + + virtual bool import(NodeMetadata *meta); + + uint8_t m_water_level; +}; + class BorderStoneNodeMetadata : public NodeMetadata { public: diff --git a/src/mapnode.h b/src/mapnode.h index b97ec8c..ed8b9d3 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -147,6 +147,7 @@ enum ContentParamType CPT_DROP, CPT_CONTENT, CPT_BLOCKDATA, + CPT_METADATA, CPT_SPECIAL }; @@ -348,6 +349,7 @@ struct ContentFeatures // Type of MapNode::param1 ContentParamType param_type; ContentParamType param2_type; + ContentParamType item_param_type; // drawtype ContentDrawType draw_type; // True for all ground-like things like stone and mud, false for eg. trees @@ -561,6 +563,7 @@ struct ContentFeatures setAllFaceTexts(FaceText()); param_type = CPT_NONE; param2_type = CPT_NONE; + item_param_type = CPT_NONE; draw_type = CDT_AIRLIKE; is_ground_content = false; light_propagates = false; diff --git a/src/nodemeta/content_nodemeta_storage.cpp b/src/nodemeta/content_nodemeta_storage.cpp index 24d34b0..af03fb5 100644 --- a/src/nodemeta/content_nodemeta_storage.cpp +++ b/src/nodemeta/content_nodemeta_storage.cpp @@ -383,27 +383,20 @@ std::wstring BarrelNodeMetadata::infoText() if (!m_water_level) return narrow_to_wide(gettext("Barrel is empty")); - if (m_water_level > 9) + if (m_water_level > 39) return narrow_to_wide(gettext("Barrel is full")); - if (snprintf(buff,1024,gettext("Barrel is %u%% full"),m_water_level*10) < 1024) + if (snprintf(buff,1024,gettext("Barrel is %u%% full"),(m_water_level*5)/2) < 1024) return narrow_to_wide(buff); return narrow_to_wide(gettext("Barrel")); } -bool BarrelNodeMetadata::nodeRemovalDisabled() -{ - if (!m_water_level) - return false; - - return true; -} std::vector BarrelNodeMetadata::getNodeBoxes(MapNode &n) { std::vector boxes; if (m_water_level) { - float h = -0.375+(0.0625*(float)m_water_level); + float h = -0.375+(0.015625*(float)m_water_level); boxes.push_back(NodeBox( -0.3125*BS,-0.375*BS,-0.3125*BS,0.3125*BS,h*BS,0.3125*BS )); @@ -412,6 +405,69 @@ std::vector BarrelNodeMetadata::getNodeBoxes(MapNode &n) return boxes; } bool BarrelNodeMetadata::import(NodeMetadata *meta) +{ + if (meta->typeId() != CONTENT_WOOD_BARREL_SEALED) + return false; + SealedBarrelNodeMetadata *l = (SealedBarrelNodeMetadata*)meta; + m_water_level = l->m_water_level; + return true; +} + +/* + SealedBarrelNodeMetadata +*/ + +// Prototype +SealedBarrelNodeMetadata proto_SealedBarrelNodeMetadata; + +SealedBarrelNodeMetadata::SealedBarrelNodeMetadata() +{ + NodeMetadata::registerType(typeId(), create); + + m_water_level = 0; +} +SealedBarrelNodeMetadata::~SealedBarrelNodeMetadata() +{ +} +u16 SealedBarrelNodeMetadata::typeId() const +{ + return CONTENT_WOOD_BARREL_SEALED; +} +NodeMetadata* SealedBarrelNodeMetadata::create(std::istream &is) +{ + std::string s; + SealedBarrelNodeMetadata *d = new SealedBarrelNodeMetadata(); + + s = deSerializeString(is); + d->m_water_level = mystoi(s); + + return d; +} +NodeMetadata* SealedBarrelNodeMetadata::clone() +{ + SealedBarrelNodeMetadata *d = new SealedBarrelNodeMetadata(); + d->m_water_level = m_water_level; + return d; +} +void SealedBarrelNodeMetadata::serializeBody(std::ostream &os) +{ + os< 39) + return narrow_to_wide(gettext("Barrel is full")); + + if (snprintf(buff,1024,gettext("Barrel is %u%% full"),(m_water_level*5)/2) < 1024) + return narrow_to_wide(buff); + + return narrow_to_wide(gettext("Barrel")); +} +bool SealedBarrelNodeMetadata::import(NodeMetadata *meta) { if (meta->typeId() != CONTENT_WOOD_BARREL) return false; diff --git a/src/nodemetadata.h b/src/nodemetadata.h index 89fd613..fb64c12 100644 --- a/src/nodemetadata.h +++ b/src/nodemetadata.h @@ -93,6 +93,9 @@ public: virtual bool import(NodeMetadata *meta) {return false;} // get nodeboxes for CDT_NODEBOX_META virtual std::vector getNodeBoxes(MapNode &n) {return std::vector();} + // get a data value for the Meta, can be stored in InventoryItems + virtual uint16_t getData() {return 0;} + virtual void setData(uint16_t v) {}; // used by tnt to arm it, but also for future circuitry // level is the amount of power // powersrc is the generator or such that created the power diff --git a/src/server.cpp b/src/server.cpp index fa454f9..bac2fa5 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2802,7 +2802,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) if (wielded_tool_features.type == TT_BUCKET) { content_t c = wielditem->getData(); if (!c) { - if (!bmeta->m_water_level) + if (bmeta->m_water_level < 4) return; wielditem->setData(CONTENT_WATERSOURCE); InventoryList *mlist = player->inventory.getList("main"); @@ -2810,9 +2810,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) mlist->addDiff(item_i,wielditem); UpdateCrafting(player->peer_id); SendInventory(player->peer_id); - bmeta->m_water_level--; + bmeta->m_water_level -= 4; }else if (c == CONTENT_WATERSOURCE) { - if (bmeta->m_water_level > 9) + if (bmeta->m_water_level > 39) return; wielditem->setData(0); InventoryList *mlist = player->inventory.getList("main"); @@ -2820,7 +2820,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) mlist->addDiff(item_i,wielditem); UpdateCrafting(player->peer_id); SendInventory(player->peer_id); - bmeta->m_water_level++; + bmeta->m_water_level += 4; }else if (c == CONTENT_LAVASOURCE) { return; } @@ -2832,6 +2832,97 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) core::map modified_blocks; modified_blocks.insert(block->getPos(),block); + for(core::map::Iterator + i = m_clients.getIterator(); + i.atEnd()==false; i++) + { + RemoteClient *client = i.getNode()->getValue(); + client->SetBlocksNotSent(modified_blocks); + client->SetBlockNotSent(blockpos); + } + }else if (wielded_tool_features.type == TT_NONE) { + core::list far_players; + core::map modified_blocks; + + meta = m_env.getMap().getNodeMetadata(p_under); + NodeMetadata *ometa = NULL; + if (meta) + ometa = meta->clone(); + m_env.getMap().removeNodeMetadata(p_under); + + selected_node.setContent(selected_node_features.special_alternate_node); + sendAddNode(p_under, selected_node, 0, &far_players, 30); + if (selected_node_features.sound_punch != "") + SendEnvEvent(ENV_EVENT_SOUND,intToFloat(p_under,BS),selected_node_features.sound_punch,NULL); + { + MapEditEventIgnorer ign(&m_ignore_map_edit_events); + + std::string p_name = std::string(player->getName()); + m_env.getMap().addNodeAndUpdate(p_under, selected_node, modified_blocks, p_name); + } + + if (ometa) { + meta = m_env.getMap().getNodeMetadata(p_under); + if (meta) + meta->import(ometa); + + delete ometa; + } + + v3s16 blockpos = getNodeBlockPos(p_under); + MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos); + if (block) + block->setChangedFlag(); + + for(core::map::Iterator + i = m_clients.getIterator(); + i.atEnd()==false; i++) + { + RemoteClient *client = i.getNode()->getValue(); + client->SetBlocksNotSent(modified_blocks); + client->SetBlockNotSent(blockpos); + } + } + }else if ( + selected_content == CONTENT_WOOD_BARREL_SEALED + || selected_content == CONTENT_APPLEWOOD_BARREL_SEALED + || selected_content == CONTENT_JUNGLEWOOD_BARREL_SEALED + || selected_content == CONTENT_PINE_BARREL_SEALED + ) { + if (wielded_tool_features.type == TT_NONE) { + core::list far_players; + core::map modified_blocks; + + meta = m_env.getMap().getNodeMetadata(p_under); + NodeMetadata *ometa = NULL; + if (meta) + ometa = meta->clone(); + m_env.getMap().removeNodeMetadata(p_under); + + selected_node.setContent(selected_node_features.special_alternate_node); + sendAddNode(p_under, selected_node, 0, &far_players, 30); + if (selected_node_features.sound_punch != "") + SendEnvEvent(ENV_EVENT_SOUND,intToFloat(p_under,BS),selected_node_features.sound_punch,NULL); + { + MapEditEventIgnorer ign(&m_ignore_map_edit_events); + + std::string p_name = std::string(player->getName()); + m_env.getMap().addNodeAndUpdate(p_under, selected_node, modified_blocks, p_name); + } + + if (ometa) { + meta = m_env.getMap().getNodeMetadata(p_under); + if (meta) + meta->import(ometa); + + delete ometa; + } + + v3s16 blockpos = getNodeBlockPos(p_under); + MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos); + if (block) + block->setChangedFlag(); + for(core::map::Iterator i = m_clients.getIterator(); i.atEnd()==false; i++) @@ -3508,6 +3599,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) player->inventory.addItem("main", eitem); } } + if (item && selected_node_features.item_param_type == CPT_METADATA) { + NodeMetadata *meta = m_env.getMap().getNodeMetadata(p_under); + if (meta) { + uint16_t v = meta->getData(); + item->setData(v); + } + } }else if (selected_node_features.param2_type == CPT_PLANTGROWTH) { if ( selected_node_features.draw_type == CDT_PLANTLIKE @@ -3918,6 +4016,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) Send to all close-by players */ sendAddNode(p_over, n, 0, &far_players, 30); + uint16_t idata = item->getData(); /* Handle inventory @@ -3957,6 +4056,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) std::string p_name = std::string(player->getName()); m_env.getMap().addNodeAndUpdate(p_over, n, modified_blocks, p_name); } + + if (content_features(addedcontent).item_param_type == CPT_METADATA) { + NodeMetadata *meta = m_env.getMap().getNodeMetadata(p_over); + if (meta) + meta->setData(idata); + sendAddNode(p_over, n, 0, &far_players, 30); + } /* Set blocks not sent to far players */