X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fnodemetadata.cpp;h=9b60cf33e1a39d8d92f461b06528d8f9ba5b193b;hb=6658ad3d94c053eeed12bb79e255cdfa46831e19;hp=f9468e4fa14f2a3dcc21f08788fdb734b2d24712;hpb=75f3e6845187b539a82f8a5e66c2aa48caa0dca8;p=minetest.git diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp index f9468e4fa..9b60cf33e 100644 --- a/src/nodemetadata.cpp +++ b/src/nodemetadata.cpp @@ -1,512 +1,216 @@ /* -Minetest-c55 -Copyright (C) 2010-2011 celeron55, Perttu Ahola +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. +GNU Lesser General Public License for more details. -You should have received a copy of the GNU General Public License along +You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "nodemetadata.h" -#include "utility.h" -#include "mapnode.h" #include "exceptions.h" +#include "gamedef.h" #include "inventory.h" +#include "log.h" +#include "util/serialize.h" +#include "constants.h" // MAP_BLOCKSIZE #include /* NodeMetadata */ -core::map NodeMetadata::m_types; - -NodeMetadata::NodeMetadata() -{ -} +NodeMetadata::NodeMetadata(IItemDefManager *item_def_mgr): + m_inventory(new Inventory(item_def_mgr)) +{} NodeMetadata::~NodeMetadata() { + delete m_inventory; } -NodeMetadata* NodeMetadata::deSerialize(std::istream &is) +void NodeMetadata::serialize(std::ostream &os) const { - // Read id - u8 buf[2]; - is.read((char*)buf, 2); - s16 id = readS16(buf); - - // Read data - std::string data = deSerializeString(is); - - // Find factory function - core::map::Node *n; - n = m_types.find(id); - if(n == NULL) - { - // If factory is not found, just return. - dstream<<"WARNING: NodeMetadata: No factory for typeId=" - <getValue(); - NodeMetadata *meta = (*f)(iss); - return meta; + int num_vars = m_stringvars.size(); + writeU32(os, num_vars); + for (StringMap::const_iterator + it = m_stringvars.begin(); + it != m_stringvars.end(); ++it) { + os << serializeString(it->first); + os << serializeLongString(it->second); } - catch(SerializationError &e) - { - dstream<<"WARNING: NodeMetadata: ignoring SerializationError"<serialize(os); } -void NodeMetadata::registerType(u16 id, Factory f) +void NodeMetadata::deSerialize(std::istream &is) { - core::map::Node *n; - n = m_types.find(id); - if(n) - return; - m_types.insert(id, f); -} - -/* - SignNodeMetadata -*/ - -// Prototype -SignNodeMetadata proto_SignNodeMetadata(""); + m_stringvars.clear(); + int num_vars = readU32(is); + for(int i=0; ideSerialize(is); } -u16 SignNodeMetadata::typeId() const -{ - return CONTENT_SIGN_WALL; -} -NodeMetadata* SignNodeMetadata::create(std::istream &is) -{ - std::string text = deSerializeString(is); - return new SignNodeMetadata(text); -} -NodeMetadata* SignNodeMetadata::clone() -{ - return new SignNodeMetadata(m_text); -} -void SignNodeMetadata::serializeBody(std::ostream &os) + +void NodeMetadata::clear() { - os<clear(); } -std::string SignNodeMetadata::infoText() + +bool NodeMetadata::empty() const { - return std::string("\"")+m_text+"\""; + return Metadata::empty() && m_inventory->getLists().size() == 0; } /* - ChestNodeMetadata + NodeMetadataList */ -// Prototype -ChestNodeMetadata proto_ChestNodeMetadata; - -ChestNodeMetadata::ChestNodeMetadata() -{ - NodeMetadata::registerType(typeId(), create); - - m_inventory = new Inventory(); - m_inventory->addList("0", 8*4); -} -ChestNodeMetadata::~ChestNodeMetadata() -{ - delete m_inventory; -} -u16 ChestNodeMetadata::typeId() const -{ - return CONTENT_CHEST; -} -NodeMetadata* ChestNodeMetadata::create(std::istream &is) -{ - ChestNodeMetadata *d = new ChestNodeMetadata(); - d->m_inventory->deSerialize(is); - return d; -} -NodeMetadata* ChestNodeMetadata::clone() -{ - ChestNodeMetadata *d = new ChestNodeMetadata(); - *d->m_inventory = *m_inventory; - return d; -} -void ChestNodeMetadata::serializeBody(std::ostream &os) -{ - m_inventory->serialize(os); -} -std::string ChestNodeMetadata::infoText() -{ - return "Chest"; -} -bool ChestNodeMetadata::nodeRemovalDisabled() +void NodeMetadataList::serialize(std::ostream &os) const { /* - Disable removal if chest contains something + Version 0 is a placeholder for "nothing to see here; go away." */ - InventoryList *list = m_inventory->getList("0"); - if(list == NULL) - return false; - if(list->getUsedSlots() == 0) - return false; - return true; -} - -/* - FurnaceNodeMetadata -*/ -// Prototype -FurnaceNodeMetadata proto_FurnaceNodeMetadata; + u16 count = countNonEmpty(); + if (count == 0) { + writeU8(os, 0); // version + return; + } -FurnaceNodeMetadata::FurnaceNodeMetadata() -{ - NodeMetadata::registerType(typeId(), create); - - m_inventory = new Inventory(); - m_inventory->addList("fuel", 1); - m_inventory->addList("src", 1); - m_inventory->addList("dst", 4); - - m_step_accumulator = 0; - m_fuel_totaltime = 0; - m_fuel_time = 0; - m_src_totaltime = 0; - m_src_time = 0; -} -FurnaceNodeMetadata::~FurnaceNodeMetadata() -{ - delete m_inventory; -} -u16 FurnaceNodeMetadata::typeId() const -{ - return CONTENT_FURNACE; -} -NodeMetadata* FurnaceNodeMetadata::clone() -{ - FurnaceNodeMetadata *d = new FurnaceNodeMetadata(); - *d->m_inventory = *m_inventory; - return d; -} -NodeMetadata* FurnaceNodeMetadata::create(std::istream &is) -{ - FurnaceNodeMetadata *d = new FurnaceNodeMetadata(); + writeU8(os, 1); // version + writeU16(os, count); - d->m_inventory->deSerialize(is); + for(std::map::const_iterator + i = m_data.begin(); + i != m_data.end(); ++i) + { + v3s16 p = i->first; + NodeMetadata *data = i->second; + if (data->empty()) + continue; - int temp; - is>>temp; - d->m_fuel_totaltime = (float)temp/10; - is>>temp; - d->m_fuel_time = (float)temp/10; + u16 p16 = p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE + p.Y * MAP_BLOCKSIZE + p.X; + writeU16(os, p16); - return d; -} -void FurnaceNodeMetadata::serializeBody(std::ostream &os) -{ - m_inventory->serialize(os); - os<= m_fuel_totaltime) - { - InventoryList *src_list = m_inventory->getList("src"); - assert(src_list); - InventoryItem *src_item = src_list->getItem(0); - - if(src_item) - return "Furnace is out of fuel"; - else - return "Furnace is inactive"; - } - else - { - std::string s = "Furnace is active ("; - s += itos(m_fuel_time/m_fuel_totaltime*100); - s += "%)"; - return s; + data->serialize(os); } } -void FurnaceNodeMetadata::inventoryModified() -{ - dstream<<"Furnace inventory modification callback"< 60.0) - dstream<<"Furnace stepping a long time ("< interval) - { - m_step_accumulator -= interval; - dtime = interval; - - //dstream<<"Furnace step dtime="<getList("dst"); - assert(dst_list); - - InventoryList *src_list = m_inventory->getList("src"); - assert(src_list); - InventoryItem *src_item = src_list->getItem(0); - - // Start only if there are free slots in dst, so that it can - // accomodate any result item - if(dst_list->getFreeSlots() > 0 && src_item && src_item->isCookable()) - { - m_src_totaltime = 3; - } - else - { - m_src_time = 0; - m_src_totaltime = 0; - } + clear(); - if(m_fuel_time < m_fuel_totaltime) - { - //dstream<<"Furnace is active"<= m_src_totaltime && m_src_totaltime > 0.001 - && src_item) - { - InventoryItem *cookresult = src_item->createCookResult(); - dst_list->addItem(cookresult); - src_list->decrementMaterials(1); - m_src_time = 0; - m_src_totaltime = 0; - } - changed = true; - continue; - } - - if(src_item == NULL || m_src_totaltime < 0.001) - { - continue; - } - - //dstream<<"Furnace is out of fuel"<getList("fuel"); - assert(fuel_list); - InventoryItem *fuel_item = fuel_list->getItem(0); - - if(ItemSpec(ITEM_MATERIAL, CONTENT_TREE).checkItem(fuel_item)) - { - m_fuel_totaltime = 30; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; - } - else if(ItemSpec(ITEM_MATERIAL, CONTENT_WOOD).checkItem(fuel_item)) - { - m_fuel_totaltime = 30/4; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; - } - else if(ItemSpec(ITEM_CRAFT, "Stick").checkItem(fuel_item)) - { - m_fuel_totaltime = 30/4/4; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; - } - else if(ItemSpec(ITEM_CRAFT, "lump_of_coal").checkItem(fuel_item)) - { - m_fuel_totaltime = 40; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; - } - else - { - //dstream<<"No fuel found"<::Iterator - i = m_data.getIterator(); - i.atEnd()==false; i++) - { - v3s16 p = i.getNode()->getKey(); - NodeMetadata *data = i.getNode()->getValue(); - - u16 p16 = p.Z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + p.Y*MAP_BLOCKSIZE + p.X; - writeU16(buf, p16); - os.write((char*)buf, 2); + u16 count = readU16(is); - data->serialize(os); - } - -} -void NodeMetadataList::deSerialize(std::istream &is) -{ - m_data.clear(); + for (u16 i=0; i < count; i++) { + u16 p16 = readU16(is); - u8 buf[6]; - - is.read((char*)buf, 2); - u16 version = readU16(buf); + v3s16 p; + p.Z = p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE; + p16 &= MAP_BLOCKSIZE * MAP_BLOCKSIZE - 1; + p.Y = p16 / MAP_BLOCKSIZE; + p16 &= MAP_BLOCKSIZE - 1; + p.X = p16; - if(version > 1) - { - dstream<<__FUNCTION_NAME<<": version "<deSerialize(is); + m_data[p] = data; } } - + NodeMetadataList::~NodeMetadataList() { - for(core::map::Iterator - i = m_data.getIterator(); - i.atEnd()==false; i++) - { - delete i.getNode()->getValue(); - } + clear(); } -NodeMetadata* NodeMetadataList::get(v3s16 p) +std::vector NodeMetadataList::getAllKeys() { - core::map::Node *n; - n = m_data.find(p); - if(n == NULL) + std::vector keys; + + std::map::const_iterator it; + for (it = m_data.begin(); it != m_data.end(); ++it) + keys.push_back(it->first); + + return keys; +} + +NodeMetadata *NodeMetadataList::get(v3s16 p) +{ + std::map::const_iterator n = m_data.find(p); + if (n == m_data.end()) return NULL; - return n->getValue(); + return n->second; } void NodeMetadataList::remove(v3s16 p) { NodeMetadata *olddata = get(p); - if(olddata) - { + if (olddata) { delete olddata; - m_data.remove(p); + m_data.erase(p); } } void NodeMetadataList::set(v3s16 p, NodeMetadata *d) { remove(p); - m_data.insert(p, d); + m_data.insert(std::make_pair(p, d)); } -bool NodeMetadataList::step(float dtime) +void NodeMetadataList::clear() { - bool something_changed = false; - for(core::map::Iterator - i = m_data.getIterator(); - i.atEnd()==false; i++) - { - v3s16 p = i.getNode()->getKey(); - NodeMetadata *meta = i.getNode()->getValue(); - bool changed = meta->step(dtime); - if(changed) - something_changed = true; - /*if(res.inventory_changed) - { - std::string inv_id; - inv_id += "nodemeta:"; - inv_id += itos(p.X); - inv_id += ","; - inv_id += itos(p.Y); - inv_id += ","; - inv_id += itos(p.Z); - InventoryContext c; - c.current_player = NULL; - inv_mgr->inventoryModified(&c, inv_id); - }*/ + std::map::iterator it; + for (it = m_data.begin(); it != m_data.end(); ++it) { + delete it->second; } - return something_changed; + m_data.clear(); } +int NodeMetadataList::countNonEmpty() const +{ + int n = 0; + std::map::const_iterator it; + for (it = m_data.begin(); it != m_data.end(); ++it) { + if (!it->second->empty()) + n++; + } + return n; +}