aboutsummaryrefslogtreecommitdiff
path: root/src/inventory.cpp
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2010-11-27 01:02:21 +0200
committerPerttu Ahola <celeron55@gmail.com>2010-11-27 01:02:21 +0200
commit4e249fb3fbf75f0359758760d88e22aa5b14533c (patch)
tree323087d05efbd2ace27b316d4f017cf812a31992 /src/inventory.cpp
downloadhax-minetest-server-4e249fb3fbf75f0359758760d88e22aa5b14533c.tar.gz
hax-minetest-server-4e249fb3fbf75f0359758760d88e22aa5b14533c.zip
Initial files
Diffstat (limited to 'src/inventory.cpp')
-rw-r--r--src/inventory.cpp320
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