X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fcontent_nodemeta.cpp;h=b36d57c89fc73654021ababc29ccf9232bc68c4d;hb=2de8f915f877e3b6779576c19e523c854966c7cd;hp=e79ff6d54c14762772542612f403f8588cdea34b;hpb=0ccc0ac927bdbfcc97c1b5c9d5dc64754946f817;p=dragonfireclient.git diff --git a/src/content_nodemeta.cpp b/src/content_nodemeta.cpp index e79ff6d54..b36d57c89 100644 --- a/src/content_nodemeta.cpp +++ b/src/content_nodemeta.cpp @@ -18,33 +18,159 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "content_nodemeta.h" + +#include #include "inventory.h" -#include "content_mapnode.h" +#include "log.h" +#include "utility.h" +#include "craftdef.h" +#include "gamedef.h" + +class Inventory; + +#define NODEMETA_GENERIC 1 +#define NODEMETA_SIGN 14 +#define NODEMETA_CHEST 15 +#define NODEMETA_FURNACE 16 +#define NODEMETA_LOCKABLE_CHEST 17 + +core::map NodeMetadata::m_types; +core::map NodeMetadata::m_names; + +class SignNodeMetadata : public NodeMetadata +{ +public: + SignNodeMetadata(IGameDef *gamedef, std::string text); + //~SignNodeMetadata(); + + virtual u16 typeId() const; + virtual const char* typeName() const + { return "sign"; } + static NodeMetadata* create(std::istream &is, IGameDef *gamedef); + static NodeMetadata* create(IGameDef *gamedef); + virtual NodeMetadata* clone(IGameDef *gamedef); + virtual void serializeBody(std::ostream &os); + virtual std::string infoText(); + + virtual bool allowsTextInput(){ return true; } + virtual std::string getText(){ return m_text; } + virtual void setText(const std::string &t){ m_text = t; } + +private: + std::string m_text; +}; + +class ChestNodeMetadata : public NodeMetadata +{ +public: + ChestNodeMetadata(IGameDef *gamedef); + ~ChestNodeMetadata(); + + virtual u16 typeId() const; + virtual const char* typeName() const + { return "chest"; } + static NodeMetadata* create(std::istream &is, IGameDef *gamedef); + static NodeMetadata* create(IGameDef *gamedef); + virtual NodeMetadata* clone(IGameDef *gamedef); + virtual void serializeBody(std::ostream &os); + virtual std::string infoText(); + virtual Inventory* getInventory() {return m_inventory;} + virtual bool nodeRemovalDisabled(); + virtual std::string getInventoryDrawSpecString(); + +private: + Inventory *m_inventory; +}; + +class LockingChestNodeMetadata : public NodeMetadata +{ +public: + LockingChestNodeMetadata(IGameDef *gamedef); + ~LockingChestNodeMetadata(); + + virtual u16 typeId() const; + virtual const char* typeName() const + { return "locked_chest"; } + static NodeMetadata* create(std::istream &is, IGameDef *gamedef); + static NodeMetadata* create(IGameDef *gamedef); + virtual NodeMetadata* clone(IGameDef *gamedef); + virtual void serializeBody(std::ostream &os); + virtual std::string infoText(); + virtual Inventory* getInventory() {return m_inventory;} + virtual bool nodeRemovalDisabled(); + virtual std::string getInventoryDrawSpecString(); + + virtual std::string getOwner(){ return m_text; } + virtual void setOwner(std::string t){ m_text = t; } + +private: + Inventory *m_inventory; + std::string m_text; +}; + +class FurnaceNodeMetadata : public NodeMetadata +{ +public: + FurnaceNodeMetadata(IGameDef *gamedef); + ~FurnaceNodeMetadata(); + + virtual u16 typeId() const; + virtual const char* typeName() const + { return "furnace"; } + virtual NodeMetadata* clone(IGameDef *gamedef); + static NodeMetadata* create(std::istream &is, IGameDef *gamedef); + static NodeMetadata* create(IGameDef *gamedef); + virtual void serializeBody(std::ostream &os); + virtual std::string infoText(); + virtual Inventory* getInventory() {return m_inventory;} + virtual void inventoryModified(); + virtual bool step(float dtime); + virtual bool nodeRemovalDisabled(); + virtual std::string getInventoryDrawSpecString(); + +protected: + bool getCookResult(bool remove, std::string &cookresult, float &cooktime); + bool getBurnResult(bool remove, float &burntime); + +private: + Inventory *m_inventory; + std::string m_infotext; + float m_step_accumulator; + float m_fuel_totaltime; + float m_fuel_time; + float m_src_totaltime; + float m_src_time; +}; /* SignNodeMetadata */ // Prototype -SignNodeMetadata proto_SignNodeMetadata(""); +SignNodeMetadata proto_SignNodeMetadata(NULL, ""); -SignNodeMetadata::SignNodeMetadata(std::string text): +SignNodeMetadata::SignNodeMetadata(IGameDef *gamedef, std::string text): + NodeMetadata(gamedef), m_text(text) { - NodeMetadata::registerType(typeId(), create); + NodeMetadata::registerType(typeId(), typeName(), create, create); } u16 SignNodeMetadata::typeId() const { - return CONTENT_SIGN_WALL; + return NODEMETA_SIGN; } -NodeMetadata* SignNodeMetadata::create(std::istream &is) +NodeMetadata* SignNodeMetadata::create(std::istream &is, IGameDef *gamedef) { std::string text = deSerializeString(is); - return new SignNodeMetadata(text); + return new SignNodeMetadata(gamedef, text); +} +NodeMetadata* SignNodeMetadata::create(IGameDef *gamedef) +{ + return new SignNodeMetadata(gamedef, ""); } -NodeMetadata* SignNodeMetadata::clone() +NodeMetadata* SignNodeMetadata::clone(IGameDef *gamedef) { - return new SignNodeMetadata(m_text); + return new SignNodeMetadata(gamedef, m_text); } void SignNodeMetadata::serializeBody(std::ostream &os) { @@ -60,14 +186,13 @@ std::string SignNodeMetadata::infoText() */ // Prototype -ChestNodeMetadata proto_ChestNodeMetadata; +ChestNodeMetadata proto_ChestNodeMetadata(NULL); -ChestNodeMetadata::ChestNodeMetadata() +ChestNodeMetadata::ChestNodeMetadata(IGameDef *gamedef): + NodeMetadata(gamedef) { - NodeMetadata::registerType(typeId(), create); - - m_inventory = new Inventory(); - m_inventory->addList("0", 8*4); + NodeMetadata::registerType(typeId(), typeName(), create, create); + m_inventory = NULL; } ChestNodeMetadata::~ChestNodeMetadata() { @@ -75,18 +200,26 @@ ChestNodeMetadata::~ChestNodeMetadata() } u16 ChestNodeMetadata::typeId() const { - return CONTENT_CHEST; + return NODEMETA_CHEST; } -NodeMetadata* ChestNodeMetadata::create(std::istream &is) +NodeMetadata* ChestNodeMetadata::create(std::istream &is, IGameDef *gamedef) { - ChestNodeMetadata *d = new ChestNodeMetadata(); + ChestNodeMetadata *d = new ChestNodeMetadata(gamedef); + d->m_inventory = new Inventory(gamedef->idef()); d->m_inventory->deSerialize(is); return d; } -NodeMetadata* ChestNodeMetadata::clone() +NodeMetadata* ChestNodeMetadata::create(IGameDef *gamedef) +{ + ChestNodeMetadata *d = new ChestNodeMetadata(gamedef); + d->m_inventory = new Inventory(gamedef->idef()); + d->m_inventory->addList("0", 8*4); + return d; +} +NodeMetadata* ChestNodeMetadata::clone(IGameDef *gamedef) { - ChestNodeMetadata *d = new ChestNodeMetadata(); - *d->m_inventory = *m_inventory; + ChestNodeMetadata *d = new ChestNodeMetadata(gamedef); + d->m_inventory = new Inventory(*m_inventory); return d; } void ChestNodeMetadata::serializeBody(std::ostream &os) @@ -122,14 +255,13 @@ std::string ChestNodeMetadata::getInventoryDrawSpecString() */ // Prototype -LockingChestNodeMetadata proto_LockingChestNodeMetadata; +LockingChestNodeMetadata proto_LockingChestNodeMetadata(NULL); -LockingChestNodeMetadata::LockingChestNodeMetadata() +LockingChestNodeMetadata::LockingChestNodeMetadata(IGameDef *gamedef): + NodeMetadata(gamedef) { - NodeMetadata::registerType(typeId(), create); - - m_inventory = new Inventory(); - m_inventory->addList("0", 8*4); + NodeMetadata::registerType(typeId(), typeName(), create, create); + m_inventory = NULL; } LockingChestNodeMetadata::~LockingChestNodeMetadata() { @@ -137,19 +269,27 @@ LockingChestNodeMetadata::~LockingChestNodeMetadata() } u16 LockingChestNodeMetadata::typeId() const { - return CONTENT_LOCKABLE_CHEST; + return NODEMETA_LOCKABLE_CHEST; } -NodeMetadata* LockingChestNodeMetadata::create(std::istream &is) +NodeMetadata* LockingChestNodeMetadata::create(std::istream &is, IGameDef *gamedef) { - LockingChestNodeMetadata *d = new LockingChestNodeMetadata(); + LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef); d->setOwner(deSerializeString(is)); + d->m_inventory = new Inventory(gamedef->idef()); d->m_inventory->deSerialize(is); return d; } -NodeMetadata* LockingChestNodeMetadata::clone() +NodeMetadata* LockingChestNodeMetadata::create(IGameDef *gamedef) +{ + LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef); + d->m_inventory = new Inventory(gamedef->idef()); + d->m_inventory->addList("0", 8*4); + return d; +} +NodeMetadata* LockingChestNodeMetadata::clone(IGameDef *gamedef) { - LockingChestNodeMetadata *d = new LockingChestNodeMetadata(); - *d->m_inventory = *m_inventory; + LockingChestNodeMetadata *d = new LockingChestNodeMetadata(gamedef); + d->m_inventory = new Inventory(*m_inventory); return d; } void LockingChestNodeMetadata::serializeBody(std::ostream &os) @@ -186,16 +326,16 @@ std::string LockingChestNodeMetadata::getInventoryDrawSpecString() */ // Prototype -FurnaceNodeMetadata proto_FurnaceNodeMetadata; +FurnaceNodeMetadata proto_FurnaceNodeMetadata(NULL); -FurnaceNodeMetadata::FurnaceNodeMetadata() +FurnaceNodeMetadata::FurnaceNodeMetadata(IGameDef *gamedef): + NodeMetadata(gamedef) { - NodeMetadata::registerType(typeId(), create); + NodeMetadata::registerType(typeId(), typeName(), create, create); - m_inventory = new Inventory(); - m_inventory->addList("fuel", 1); - m_inventory->addList("src", 1); - m_inventory->addList("dst", 4); + m_inventory = NULL; + + m_infotext = "Furnace is inactive"; m_step_accumulator = 0; m_fuel_totaltime = 0; @@ -209,63 +349,71 @@ FurnaceNodeMetadata::~FurnaceNodeMetadata() } u16 FurnaceNodeMetadata::typeId() const { - return CONTENT_FURNACE; + return NODEMETA_FURNACE; } -NodeMetadata* FurnaceNodeMetadata::clone() +NodeMetadata* FurnaceNodeMetadata::clone(IGameDef *gamedef) { - FurnaceNodeMetadata *d = new FurnaceNodeMetadata(); - *d->m_inventory = *m_inventory; + FurnaceNodeMetadata *d = new FurnaceNodeMetadata(m_gamedef); + d->m_inventory = new Inventory(*m_inventory); return d; } -NodeMetadata* FurnaceNodeMetadata::create(std::istream &is) +NodeMetadata* FurnaceNodeMetadata::create(std::istream &is, IGameDef *gamedef) { - FurnaceNodeMetadata *d = new FurnaceNodeMetadata(); + FurnaceNodeMetadata *d = new FurnaceNodeMetadata(gamedef); + d->m_inventory = new Inventory(gamedef->idef()); d->m_inventory->deSerialize(is); - int temp; + int temp = 0; is>>temp; d->m_fuel_totaltime = (float)temp/10; + temp = 0; is>>temp; d->m_fuel_time = (float)temp/10; + temp = 0; + is>>temp; + d->m_src_totaltime = (float)temp/10; + temp = 0; + is>>temp; + d->m_src_time = (float)temp/10; + + if(is.eof()) + { + // Old furnaces didn't serialize src_totaltime and src_time + d->m_src_totaltime = 0; + d->m_src_time = 0; + d->m_infotext = ""; + } + else + { + // New furnaces also serialize the infotext (so that the + // client doesn't need to have the list of cooking recipes). + d->m_infotext = deSerializeJsonString(is); + } return d; } +NodeMetadata* FurnaceNodeMetadata::create(IGameDef *gamedef) +{ + FurnaceNodeMetadata *d = new FurnaceNodeMetadata(gamedef); + d->m_inventory = new Inventory(gamedef->idef()); + d->m_inventory->addList("fuel", 1); + d->m_inventory->addList("src", 1); + d->m_inventory->addList("dst", 4); + return d; +} void FurnaceNodeMetadata::serializeBody(std::ostream &os) { m_inventory->serialize(os); os<= m_fuel_totaltime) - { - const InventoryList *src_list = m_inventory->getList("src"); - assert(src_list); - const InventoryItem *src_item = src_list->getItem(0); - - if(src_item && src_item->isCookable()) { - InventoryList *dst_list = m_inventory->getList("dst"); - if(!dst_list->roomForCookedItem(src_item)) - return "Furnace is overloaded"; - return "Furnace is out of fuel"; - } - else - return "Furnace is inactive"; - } - else - { - std::string s = "Furnace is active"; - // Do this so it doesn't always show (0%) for weak fuel - if(m_fuel_totaltime > 3) { - s += " ("; - s += itos(m_fuel_time/m_fuel_totaltime*100); - s += "%)"; - } - return s; - } + return m_infotext; } bool FurnaceNodeMetadata::nodeRemovalDisabled() { @@ -287,12 +435,16 @@ bool FurnaceNodeMetadata::nodeRemovalDisabled() } void FurnaceNodeMetadata::inventoryModified() { - dstream<<"Furnace inventory modification callback"< 60.0) - dstream<<"Furnace stepping a long time ("<getList("dst"); + assert(dst_list); + // Update at a fixed frequency const float interval = 2.0; m_step_accumulator += dtime; @@ -302,160 +454,111 @@ bool FurnaceNodeMetadata::step(float dtime) m_step_accumulator -= interval; dtime = interval; - //dstream<<"Furnace step dtime="<getList("dst"); - assert(dst_list); + //infostream<<"Furnace step dtime="<getList("src"); - assert(src_list); - InventoryItem *src_item = src_list->getItem(0); - + bool changed_this_loop = false; + + // Check + // 1. if the source item is cookable + // 2. if there is room for the cooked item + std::string cookresult; + float cooktime; + bool cookable = getCookResult(false, cookresult, cooktime); + ItemStack cookresult_item; bool room_available = false; - - if(src_item && src_item->isCookable()) - room_available = dst_list->roomForCookedItem(src_item); - - // Start only if there are free slots in dst, so that it can - // accomodate any result item - if(room_available) + if(cookable) { - m_src_totaltime = 3; + cookresult_item.deSerialize(cookresult, m_gamedef->idef()); + room_available = dst_list->roomForItem(cookresult_item); } - else + + // Step fuel time + bool burning = (m_fuel_time < m_fuel_totaltime); + if(burning) { - m_src_time = 0; - m_src_totaltime = 0; + changed_this_loop = true; + m_fuel_time += dtime; } - - /* - If fuel is burning, increment the burn counters. - If item finishes cooking, move it to result. - */ - if(m_fuel_time < m_fuel_totaltime) + + std::string infotext; + if(room_available) { - //dstream<<"Furnace is active"<= m_src_totaltime && m_src_totaltime > 0.001 - && src_item) + float burntime; + if(burning) + { + changed_this_loop = true; + m_src_time += dtime; + m_src_totaltime = cooktime; + infotext = "Furnace is cooking"; + } + else if(getBurnResult(true, burntime)) + { + // Fuel inserted + changed_this_loop = true; + m_fuel_time = 0; + m_fuel_totaltime = burntime; + //m_src_time += dtime; + //m_src_totaltime = cooktime; + infotext = "Furnace is cooking"; + } + else { - InventoryItem *cookresult = src_item->createCookResult(); - dst_list->addItem(cookresult); - src_list->decrementMaterials(1); m_src_time = 0; m_src_totaltime = 0; + infotext = "Furnace is out of fuel"; + } + if(m_src_totaltime > 0.001 && m_src_time >= m_src_totaltime) + { + // One item fully cooked + changed_this_loop = true; + dst_list->addItem(cookresult_item); + getCookResult(true, cookresult, cooktime); // decrement source + m_src_totaltime = 0; + m_src_time = 0; } - changed = true; - - // If the fuel was not used up this step, just keep burning it - if(m_fuel_time < m_fuel_totaltime) - continue; } - - /* - Get the source again in case it has all burned - */ - src_item = src_list->getItem(0); - - /* - If there is no source item, or the source item is not cookable, - or the furnace is still cooking, or the furnace became overloaded, stop loop. - */ - if(src_item == NULL || !room_available || m_fuel_time < m_fuel_totaltime || - dst_list->roomForCookedItem(src_item) == false) + else { - m_step_accumulator = 0; - break; + // Not cookable or no room available + m_src_totaltime = 0; + m_src_time = 0; + if(cookable) + infotext = "Furnace is overloaded"; + else if(burning) + infotext = "Furnace is active"; + else + { + infotext = "Furnace is inactive"; + m_fuel_totaltime = 0; + m_fuel_time = 0; + } } - - //dstream<<"Furnace is out of fuel"<getList("fuel"); - assert(fuel_list); - const 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_JUNGLETREE).checkItem(fuel_item)) - { - m_fuel_totaltime = 30; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; - } - else if(ItemSpec(ITEM_MATERIAL, CONTENT_FENCE).checkItem(fuel_item)) - { - m_fuel_totaltime = 30/2; - 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_MATERIAL, CONTENT_BOOKSHELF).checkItem(fuel_item)) - { - m_fuel_totaltime = 30/4; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; - } - else if(ItemSpec(ITEM_MATERIAL, CONTENT_LEAVES).checkItem(fuel_item)) - { - m_fuel_totaltime = 30/16; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; - } - else if(ItemSpec(ITEM_MATERIAL, CONTENT_PAPYRUS).checkItem(fuel_item)) - { - m_fuel_totaltime = 30/32; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; - } - else if(ItemSpec(ITEM_MATERIAL, CONTENT_JUNGLEGRASS).checkItem(fuel_item)) - { - m_fuel_totaltime = 30/32; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; + // Do this so it doesn't always show (0%) for weak fuel + if(m_fuel_totaltime > 3) { + infotext += " ("; + infotext += itos(m_fuel_time/m_fuel_totaltime*100); + infotext += "%)"; } - else if(ItemSpec(ITEM_MATERIAL, CONTENT_CACTUS).checkItem(fuel_item)) + + if(infotext != m_infotext) { - m_fuel_totaltime = 30/4; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; + m_infotext = infotext; + changed_this_loop = true; } - else if(ItemSpec(ITEM_CRAFT, "Stick").checkItem(fuel_item)) + + if(burning && m_fuel_time >= m_fuel_totaltime) { - m_fuel_totaltime = 30/4/4; m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; + m_fuel_totaltime = 0; } - else if(ItemSpec(ITEM_CRAFT, "lump_of_coal").checkItem(fuel_item)) + + if(changed_this_loop) { - m_fuel_totaltime = 40; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); changed = true; } else { - //dstream<<"No fuel found"< items; + InventoryList *src_list = m_inventory->getList("src"); + assert(src_list); + items.push_back(src_list->getItem(0)); + + CraftInput ci(CRAFT_METHOD_COOKING, 1, items); + CraftOutput co; + bool found = m_gamedef->getCraftDefManager()->getCraftResult( + ci, co, remove, m_gamedef); + if(remove) + src_list->changeItem(0, ci.items[0]); + + cookresult = co.item; + cooktime = co.time; + return found; +} +bool FurnaceNodeMetadata::getBurnResult(bool remove, float &burntime) +{ + std::vector items; + InventoryList *fuel_list = m_inventory->getList("fuel"); + assert(fuel_list); + items.push_back(fuel_list->getItem(0)); + + CraftInput ci(CRAFT_METHOD_FUEL, 1, items); + CraftOutput co; + bool found = m_gamedef->getCraftDefManager()->getCraftResult( + ci, co, remove, m_gamedef); + if(remove) + fuel_list->changeItem(0, ci.items[0]); + + burntime = co.time; + return found; +} + + +/* + GenericNodeMetadata +*/ + +class GenericNodeMetadata : public NodeMetadata +{ +private: + Inventory *m_inventory; + std::string m_text; + std::string m_owner; + + std::string m_infotext; + std::string m_inventorydrawspec; + bool m_allow_text_input; + bool m_removal_disabled; + bool m_enforce_owner; + + bool m_inventory_modified; + bool m_text_modified; + + std::map m_stringvars; + +public: + u16 typeId() const + { + return NODEMETA_GENERIC; + } + const char* typeName() const + { + return "generic"; + } + + GenericNodeMetadata(IGameDef *gamedef): + NodeMetadata(gamedef), + + m_inventory(NULL), + m_text(""), + m_owner(""), + + m_infotext("GenericNodeMetadata"), + m_inventorydrawspec(""), + m_allow_text_input(false), + m_removal_disabled(false), + m_enforce_owner(false), + + m_inventory_modified(false), + m_text_modified(false) + { + NodeMetadata::registerType(typeId(), typeName(), create, create); + } + virtual ~GenericNodeMetadata() + { + delete m_inventory; + } + NodeMetadata* clone(IGameDef *gamedef) + { + GenericNodeMetadata *d = new GenericNodeMetadata(m_gamedef); + + d->m_inventory = new Inventory(*m_inventory); + d->m_text = m_text; + d->m_owner = m_owner; + + d->m_infotext = m_infotext; + d->m_inventorydrawspec = m_inventorydrawspec; + d->m_allow_text_input = m_allow_text_input; + d->m_removal_disabled = m_removal_disabled; + d->m_enforce_owner = m_enforce_owner; + d->m_inventory_modified = m_inventory_modified; + d->m_text_modified = m_text_modified; + return d; + } + static NodeMetadata* create(IGameDef *gamedef) + { + GenericNodeMetadata *d = new GenericNodeMetadata(gamedef); + d->m_inventory = new Inventory(gamedef->idef()); + return d; + } + static NodeMetadata* create(std::istream &is, IGameDef *gamedef) + { + GenericNodeMetadata *d = new GenericNodeMetadata(gamedef); + + d->m_inventory = new Inventory(gamedef->idef()); + d->m_inventory->deSerialize(is); + d->m_text = deSerializeLongString(is); + d->m_owner = deSerializeString(is); + + d->m_infotext = deSerializeString(is); + d->m_inventorydrawspec = deSerializeString(is); + d->m_allow_text_input = readU8(is); + d->m_removal_disabled = readU8(is); + d->m_enforce_owner = readU8(is); + + int num_vars = readU32(is); + for(int i=0; im_stringvars[name] = var; + } + return d; + } + void serializeBody(std::ostream &os) + { + m_inventory->serialize(os); + os<::iterator + i = m_stringvars.begin(); i != m_stringvars.end(); i++){ + os<first); + os<second); + } + } + + std::string infoText() + { + return m_infotext; + } + Inventory* getInventory() + { + return m_inventory; + } + void inventoryModified() + { + m_inventory_modified = true; + } + bool step(float dtime) + { + return false; + } + bool nodeRemovalDisabled() + { + return m_removal_disabled; + } + std::string getInventoryDrawSpecString() + { + return m_inventorydrawspec; + } + bool allowsTextInput() + { + return m_allow_text_input; + } + std::string getText() + { + return m_text; + } + void setText(const std::string &t) + { + m_text = t; + m_text_modified = true; + } + std::string getOwner() + { + if(m_enforce_owner) + return m_owner; + else + return ""; + } + void setOwner(std::string t) + { + m_owner = t; + } + + /* Interface for GenericNodeMetadata */ + + void setInfoText(const std::string &text) + { + infostream<<"GenericNodeMetadata::setInfoText(\"" + <::iterator i; + i = m_stringvars.find(name); + if(i == m_stringvars.end()) + return ""; + return i->second; + } +}; + +// Prototype +GenericNodeMetadata proto_GenericNodeMetadata(NULL);