diff options
Diffstat (limited to 'src/inventory.cpp')
-rw-r--r-- | src/inventory.cpp | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/src/inventory.cpp b/src/inventory.cpp new file mode 100644 index 000000000..4fe21b303 --- /dev/null +++ b/src/inventory.cpp @@ -0,0 +1,320 @@ +/* +(c) 2010 Perttu Ahola <celeron55@gmail.com> +*/ + +#include "inventory.h" +#include "serialization.h" +#include "utility.h" +#include "debug.h" +#include <sstream> +#include "main.h" + +/* + InventoryItem +*/ + +InventoryItem::InventoryItem() +{ +} + +InventoryItem::~InventoryItem() +{ +} + +InventoryItem* InventoryItem::deSerialize(std::istream &is) +{ + DSTACK(__FUNCTION_NAME); + + //is.imbue(std::locale("C")); + // Read name + std::string name; + std::getline(is, name, ' '); + + if(name == "MaterialItem") + { + // u16 reads directly as a number (u8 doesn't) + u16 material; + is>>material; + u16 count; + is>>count; + if(material > 255) + throw SerializationError("Too large material number"); + return new MaterialItem(material, count); + } + else if(name == "MBOItem") + { + std::string inventorystring; + std::getline(is, inventorystring, '|'); + return new MapBlockObjectItem(inventorystring); + } + else + { + dstream<<"Unknown InventoryItem name=\""<<name<<"\""<<std::endl; + throw SerializationError("Unknown InventoryItem name"); + } +} + +/* + MapBlockObjectItem +*/ + +video::ITexture * MapBlockObjectItem::getImage() +{ + if(m_inventorystring.substr(0,3) == "Rat") + return g_device->getVideoDriver()->getTexture("../data/rat.png"); + + if(m_inventorystring.substr(0,4) == "Sign") + return g_device->getVideoDriver()->getTexture("../data/sign.png"); + + return NULL; +} +std::string MapBlockObjectItem::getText() +{ + if(m_inventorystring.substr(0,3) == "Rat") + return ""; + + if(m_inventorystring.substr(0,4) == "Sign") + return ""; + + return "obj"; +} + +MapBlockObject * MapBlockObjectItem::createObject + (v3f pos, f32 player_yaw, f32 player_pitch) +{ + std::istringstream is(m_inventorystring); + std::string name; + std::getline(is, name, ' '); + + if(name == "None") + { + return NULL; + } + else if(name == "Sign") + { + std::string text; + std::getline(is, text, '|'); + SignObject *obj = new SignObject(NULL, -1, pos); + obj->setText(text); + obj->setYaw(-player_yaw); + return obj; + } + else if(name == "Rat") + { + RatObject *obj = new RatObject(NULL, -1, pos); + return obj; + } + else + { + return NULL; + } +} + +/* + Inventory +*/ + +Inventory::Inventory(u32 size) +{ + m_size = size; + clearItems(); +} + +Inventory::~Inventory() +{ + for(u32 i=0; i<m_items.size(); i++) + { + delete m_items[i]; + } +} + +void Inventory::clearItems() +{ + m_items.clear(); + for(u32 i=0; i<m_size; i++) + { + m_items.push_back(NULL); + } +} + +void Inventory::serialize(std::ostream &os) +{ + //os.imbue(std::locale("C")); + + for(u32 i=0; i<m_items.size(); i++) + { + InventoryItem *item = m_items[i]; + if(item != NULL) + { + os<<"Item "; + item->serialize(os); + } + else + { + os<<"Empty"; + } + os<<"\n"; + } + + os<<"end\n"; +} + +void Inventory::deSerialize(std::istream &is) +{ + //is.imbue(std::locale("C")); + + clearItems(); + u32 item_i = 0; + + for(;;) + { + std::string line; + std::getline(is, line, '\n'); + + std::istringstream iss(line); + //iss.imbue(std::locale("C")); + + std::string name; + std::getline(iss, name, ' '); + + if(name == "end") + { + break; + } + else if(name == "Item") + { + if(item_i > getSize() - 1) + throw SerializationError("too many items"); + InventoryItem *item = InventoryItem::deSerialize(iss); + m_items[item_i++] = item; + } + else if(name == "Empty") + { + if(item_i > getSize() - 1) + throw SerializationError("too many items"); + m_items[item_i++] = NULL; + } + else + { + throw SerializationError("Unknown inventory identifier"); + } + } +} + +Inventory & Inventory::operator = (Inventory &other) +{ + m_size = other.m_size; + clearItems(); + for(u32 i=0; i<other.m_items.size(); i++) + { + InventoryItem *item = other.m_items[i]; + if(item != NULL) + { + m_items[i] = item->clone(); + } + } + + return *this; +} + +u32 Inventory::getSize() +{ + return m_items.size(); +} + +u32 Inventory::getUsedSlots() +{ + u32 num = 0; + for(u32 i=0; i<m_items.size(); i++) + { + InventoryItem *item = m_items[i]; + if(item != NULL) + num++; + } + return num; +} + +InventoryItem * Inventory::getItem(u32 i) +{ + if(i > m_items.size() - 1) + return NULL; + return m_items[i]; +} + +InventoryItem * Inventory::changeItem(u32 i, InventoryItem *newitem) +{ + assert(i < m_items.size()); + + InventoryItem *olditem = m_items[i]; + m_items[i] = newitem; + return olditem; +} + +void Inventory::deleteItem(u32 i) +{ + assert(i < m_items.size()); + InventoryItem *item = changeItem(i, NULL); + if(item) + delete item; +} + +bool Inventory::addItem(InventoryItem *newitem) +{ + // If it is a MaterialItem, try to find an already existing one + // and just increment the counter + if(std::string("MaterialItem") == newitem->getName()) + { + u8 material = ((MaterialItem*)newitem)->getMaterial(); + u8 count = ((MaterialItem*)newitem)->getCount(); + for(u32 i=0; i<m_items.size(); i++) + { + InventoryItem *item2 = m_items[i]; + if(item2 == NULL) + continue; + if(std::string("MaterialItem") != item2->getName()) + continue; + // Found one. Check if it is of the right material and has + // free space + MaterialItem *mitem2 = (MaterialItem*)item2; + if(mitem2->getMaterial() != material) + continue; + //TODO: Add all that can be added and add remaining part + // to another place + if(mitem2->freeSpace() < count) + continue; + // Add to the counter + mitem2->add(count); + // Dump the parameter + delete newitem; + return true; + } + } + // Else find an empty position + for(u32 i=0; i<m_items.size(); i++) + { + InventoryItem *item = m_items[i]; + if(item != NULL) + continue; + m_items[i] = newitem; + return true; + } + // Failed + return false; +} + +void Inventory::print(std::ostream &o) +{ + o<<"Player inventory:"<<std::endl; + for(u32 i=0; i<m_items.size(); i++) + { + InventoryItem *item = m_items[i]; + if(item != NULL) + { + o<<i<<": "; + item->serialize(o); + o<<"\n"; + } + } +} + +//END |