SOURCES = $(addprefix src/, $(SOURCE_FILES))\r
BUILD_DIR = build\r
OBJECTS = $(addprefix $(BUILD_DIR)/, $(SOURCE_FILES:.cpp=.o))\r
-#OBJECTS = $(SOURCES:.cpp=.o)\r
\r
FAST_TARGET = fasttest\r
+FAST_SOURCES = $(addprefix src/, $(SOURCE_FILES))\r
+FAST_BUILD_DIR = fastbuild\r
+FAST_OBJECTS = $(addprefix $(FAST_BUILD_DIR)/, $(SOURCE_FILES:.cpp=.o))\r
\r
SERVER_TARGET = server\r
SERVER_SOURCE_FILES = defaultsettings.cpp mapnode.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp servermain.cpp test.cpp\r
SERVER_SOURCES = $(addprefix src/, $(SERVER_SOURCE_FILES))\r
SERVER_BUILD_DIR = serverbuild\r
SERVER_OBJECTS = $(addprefix $(SERVER_BUILD_DIR)/, $(SERVER_SOURCE_FILES:.cpp=.o))\r
-#SERVER_OBJECTS = $(SERVER_SOURCES:.cpp=.o)\r
\r
IRRLICHTPATH = ../irrlicht/irrlicht-1.7.1\r
JTHREADPATH = ../jthread/jthread-1.2.1\r
# Build commands\r
\r
all_linux all_win32: $(BUILD_DIR) $(DESTPATH)\r
-fast_linux: $(BUILD_DIR) $(FAST_DESTPATH)\r
+fast_linux: $(FAST_BUILD_DIR) $(FAST_DESTPATH)\r
server_linux: $(SERVER_BUILD_DIR) $(SERVER_DESTPATH)\r
\r
$(BUILD_DIR):\r
mkdir -p $(BUILD_DIR)\r
+$(FAST_BUILD_DIR):\r
+ mkdir -p $(FAST_BUILD_DIR)\r
$(SERVER_BUILD_DIR):\r
mkdir -p $(SERVER_BUILD_DIR)\r
\r
$(DESTPATH): $(OBJECTS)\r
$(CXX) -o $@ $(OBJECTS) $(LDFLAGS)\r
\r
-$(FAST_DESTPATH): $(OBJECTS)\r
- $(CXX) -o $@ $(OBJECTS) $(LDFLAGS) -DUNITTEST_DISABLE\r
+$(FAST_DESTPATH): $(FAST_OBJECTS)\r
+ $(CXX) -o $@ $(FAST_OBJECTS) $(LDFLAGS) -DUNITTEST_DISABLE\r
\r
$(SERVER_DESTPATH): $(SERVER_OBJECTS)\r
$(CXX) -o $@ $(SERVER_OBJECTS) $(LDFLAGS) -DSERVER -DUNITTEST_DISABLE\r
$(BUILD_DIR)/%.o: src/%.cpp\r
$(CXX) -c -o $@ $< $(CPPFLAGS) $(CXXFLAGS)\r
\r
+$(FAST_BUILD_DIR)/%.o: src/%.cpp\r
+ $(CXX) -c -o $@ $< $(CPPFLAGS) $(CXXFLAGS)\r
+\r
$(SERVER_BUILD_DIR)/%.o: src/%.cpp\r
$(CXX) -c -o $@ $< $(CPPFLAGS) $(CXXFLAGS)\r
\r
cp bin/zlibwapi.dll $PACKAGEPATH/bin/
#cp bin/test $PACKAGEPATH/bin/
cp bin/fasttest $PACKAGEPATH/bin/
+cp bin/server $PACKAGEPATH/bin/
cp ../irrlicht/irrlicht-1.7.1/lib/Linux/libIrrlicht.a $PACKAGEPATH/bin/
cp ../jthread/jthread-1.2.1/src/.libs/libjthread-1.2.1.so $PACKAGEPATH/bin/
cp -r data/skybox3.png $PACKAGEPATH/data/
cp -r data/tree_top.png $PACKAGEPATH/data/
cp -r data/mud_with_grass.png $PACKAGEPATH/data/
+cp -r data/coalstone.png $PACKAGEPATH/data/
+cp -r data/crack.png $PACKAGEPATH/data/
-cp -r data/pauseMenu.gui $PACKAGEPATH/data/
+#cp -r data/pauseMenu.gui $PACKAGEPATH/data/
cp -r doc/README.txt $PACKAGEPATH/doc/README.txt
RelativePath=".\src\filesys.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\src\guiInventoryMenu.cpp"\r
+ >\r
+ </File>\r
<File\r
RelativePath=".\src\guiPauseMenu.cpp"\r
>\r
// Send as reliable
Send(0, data, true);
}
+
+void Client::sendInventoryAction(InventoryAction *a)
+{
+ std::ostringstream os(std::ios_base::binary);
+ u8 buf[12];
+
+ // Write command
+ writeU16(buf, TOSERVER_INVENTORY_ACTION);
+ os.write((char*)buf, 2);
+
+ a->serialize(os);
+
+ // Make data buffer
+ std::string s = os.str();
+ SharedBuffer<u8> data((u8*)s.c_str(), s.size());
+ // Send as reliable
+ Send(0, data, true);
+}
void Client::sendPlayerPos()
{
void clickObject(u8 button, v3s16 blockpos, s16 id, u16 item);
void sendSignText(v3s16 blockpos, s16 id, std::string text);
+ void sendInventoryAction(InventoryAction *a);
void updateCamera(v3f pos, v3f dir);
u16 textlen
textdata
*/
+
+ TOSERVER_INVENTORY_ACTION = 0x31,
+ /*
+ See InventoryAction in inventory.h
+ */
};
inline SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time)
if(item != NULL)
{
gui::IGUIFont *font = skin->getFont();
- if(font)
+ std::string text = item->getText();
+ if(font && text != "")
{
core::rect<s32> rect2(rect.UpperLeftCorner,
(core::dimension2d<u32>(rect.getWidth(), 15)));
video::SColor bgcolor(128,0,0,0);
driver->draw2DRectangle(bgcolor, rect2, clip);
- font->draw(item->getText().c_str(), rect2,
+ font->draw(text.c_str(), rect2,
video::SColor(255,255,255,255), false, false,
clip);
}
}
}
-/*
- GUIInventorySlot
-*/
-
-GUIInventorySlot::GUIInventorySlot(gui::IGUIEnvironment* env,
- gui::IGUIElement* parent, s32 id, core::rect<s32> rect):
- IGUIElement(gui::EGUIET_ELEMENT, env, parent, id, rect)
-{
- m_item = NULL;
-}
-
-void GUIInventorySlot::draw()
-{
- if(!IsVisible)
- return;
-
- drawInventoryItem(Environment, m_item, AbsoluteRect,
- &AbsoluteClippingRect);
-
- gui::IGUIElement::draw();
-}
-
-bool GUIInventorySlot::OnEvent(const SEvent& event)
-{
- /*if (!IsEnabled)
- return IGUIElement::OnEvent(event);*/
-
- switch(event.EventType)
- {
- case EET_MOUSE_INPUT_EVENT:
- if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
- {
- dstream<<"Slot pressed"<<std::endl;
- //return true;
- }
- else
- if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
- {
- dstream<<"Slot released"<<std::endl;
- //return true;
- }
- break;
- default:
- break;
- }
-
- return Parent ? Parent->OnEvent(event) : false;
-}
-
/*
GUIInventoryMenu
*/
{
m_inventory = inventory;
m_screensize_old = v2u32(0,0);
+ m_selected_item = NULL;
resizeGui();
setVisible(false);
+
+ /*m_selected_item = new ItemSpec;
+ m_selected_item->listname = "main";
+ m_selected_item->i = 3;*/
}
GUIInventoryMenu::~GUIInventoryMenu()
{
+ if(m_selected_item)
+ delete m_selected_item;
}
void GUIInventoryMenu::resizeGui()
return;
m_screensize_old = screensize;
+ padding = v2s32(24,24);
+ spacing = v2s32(60,56);
+ imgsize = v2s32(48,48);
+
+ v2s32 size(
+ padding.X*2+spacing.X*(8-1)+imgsize.X,
+ padding.Y*2+spacing.Y*(7-1)+imgsize.Y
+ );
+
core::rect<s32> rect(
- screensize.X/2 - 560/2,
- screensize.Y/2 - 480/2,
- screensize.X/2 + 560/2,
- screensize.Y/2 + 480/2
+ screensize.X/2 - size.X/2,
+ screensize.Y/2 - size.Y/2,
+ screensize.X/2 + size.X/2,
+ screensize.Y/2 + size.Y/2
);
DesiredRect = rect;
recalculateAbsolutePosition(false);
+
+ v2s32 basepos = getBasePos();
+
+ m_draw_positions.clear();
+ m_draw_positions.push_back(ListDrawSpec("main",
+ basepos + v2s32(spacing.X*0, spacing.Y*3), v2s32(8, 4)));
+ m_draw_positions.push_back(ListDrawSpec("craft",
+ basepos + v2s32(spacing.X*3, spacing.Y*0), v2s32(3, 3)));
+ m_draw_positions.push_back(ListDrawSpec("craftresult",
+ basepos + v2s32(spacing.X*7, spacing.Y*1), v2s32(1, 1)));
+}
+
+GUIInventoryMenu::ItemSpec GUIInventoryMenu::getItemAtPos(v2s32 p) const
+{
+ core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
+
+ for(u32 i=0; i<m_draw_positions.size(); i++)
+ {
+ const ListDrawSpec &s = m_draw_positions[i];
+
+ for(s32 i=0; i<s.geom.X*s.geom.Y; i++)
+ {
+ s32 x = (i%s.geom.X) * spacing.X;
+ s32 y = (i/s.geom.X) * spacing.Y;
+ v2s32 p0(x,y);
+ core::rect<s32> rect = imgrect + s.pos + p0;
+ if(rect.isPointInside(p))
+ {
+ return ItemSpec(s.listname, i);
+ }
+ }
+ }
+
+ return ItemSpec("", -1);
}
-void GUIInventoryMenu::update()
+//void GUIInventoryMenu::drawList(const std::string &name, v2s32 pos, v2s32 geom)
+void GUIInventoryMenu::drawList(const ListDrawSpec &s)
{
+ video::IVideoDriver* driver = Environment->getVideoDriver();
+
+ InventoryList *ilist = m_inventory->getList(s.listname);
+
+ core::rect<s32> imgrect(0,0,imgsize.X,imgsize.Y);
+
+ for(s32 i=0; i<s.geom.X*s.geom.Y; i++)
+ {
+ s32 x = (i%s.geom.X) * spacing.X;
+ s32 y = (i/s.geom.X) * spacing.Y;
+ v2s32 p(x,y);
+ core::rect<s32> rect = imgrect + s.pos + p;
+ InventoryItem *item = NULL;
+ if(ilist)
+ item = ilist->getItem(i);
+
+ if(m_selected_item != NULL && m_selected_item->listname == s.listname
+ && m_selected_item->i == i)
+ {
+ driver->draw2DRectangle(video::SColor(255,255,0,0),
+ core::rect<s32>(rect.UpperLeftCorner - v2s32(2,2),
+ rect.LowerRightCorner + v2s32(2,2)),
+ &AbsoluteClippingRect);
+ }
+ drawInventoryItem(Environment, item,
+ rect, &AbsoluteClippingRect);
+ }
}
void GUIInventoryMenu::draw()
Draw items
*/
+ for(u32 i=0; i<m_draw_positions.size(); i++)
{
- InventoryList *ilist = m_inventory->getList("main");
- if(ilist != NULL)
- {
- core::rect<s32> imgsize(0,0,48,48);
- v2s32 basepos(30, 210);
- basepos += AbsoluteRect.UpperLeftCorner;
- for(s32 i=0; i<PLAYER_INVENTORY_SIZE; i++)
- {
- s32 x = (i%8) * 64;
- s32 y = (i/8) * 64;
- v2s32 p(x,y);
- core::rect<s32> rect = imgsize + basepos + p;
- drawInventoryItem(Environment, ilist->getItem(i),
- rect, &AbsoluteClippingRect);
- }
- }
- }
-
- {
- InventoryList *ilist = m_inventory->getList("craft");
- if(ilist != NULL)
- {
- core::rect<s32> imgsize(0,0,48,48);
- v2s32 basepos(30, 30);
- basepos += AbsoluteRect.UpperLeftCorner;
- for(s32 i=0; i<9; i++)
- {
- s32 x = (i%3) * 64;
- s32 y = (i/3) * 64;
- v2s32 p(x,y);
- core::rect<s32> rect = imgsize + basepos + p;
- drawInventoryItem(Environment, ilist->getItem(i),
- rect, &AbsoluteClippingRect);
- }
- }
+ ListDrawSpec &s = m_draw_positions[i];
+ drawList(s);
}
/*
{
if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
{
+ v2s32 p(event.MouseInput.X, event.MouseInput.Y);
+ //dstream<<"Mouse down at p=("<<p.X<<","<<p.Y<<")"<<std::endl;
+ ItemSpec s = getItemAtPos(p);
+ if(s.isValid())
+ {
+ //dstream<<"Mouse down on "<<s.listname<<" "<<s.i<<std::endl;
+ if(m_selected_item)
+ {
+ InventoryList *list_from =
+ m_inventory->getList(m_selected_item->listname);
+ InventoryList *list_to =
+ m_inventory->getList(s.listname);
+ if(list_from && list_to
+ && list_from->getItem(m_selected_item->i) != NULL)
+ {
+ dstream<<"Queueing IACTION_MOVE"<<std::endl;
+ IMoveAction *a =
+ new IMoveAction();
+ a->count = 1;
+ a->from_name = m_selected_item->listname;
+ a->from_i = m_selected_item->i;
+ a->to_name = s.listname;
+ a->to_i = s.i;
+ m_actions.push_back(a);
+ }
+ delete m_selected_item;
+ m_selected_item = NULL;
+ }
+ else
+ {
+ /*
+ Select if non-NULL
+ */
+ InventoryList *list = m_inventory->getList(s.listname);
+ if(list->getItem(s.i) != NULL)
+ {
+ m_selected_item = new ItemSpec(s);
+ }
+ }
+ }
+ else
+ {
+ if(m_selected_item)
+ {
+ delete m_selected_item;
+ m_selected_item = NULL;
+ }
+ }
}
}
if(event.EventType==EET_GUI_EVENT)
return Parent ? Parent->OnEvent(event) : false;
}
+InventoryAction* GUIInventoryMenu::getNextAction()
+{
+ if(m_actions.size() == 0)
+ return NULL;
+ return m_actions.pop_front();
+}
+
#include "common_irrlicht.h"
#include "inventory.h"
+#include "utility.h"
void drawInventoryItem(gui::IGUIEnvironment* env,
InventoryItem *item, core::rect<s32> rect,
const core::rect<s32> *clip=0);
-class GUIInventorySlot: public gui::IGUIElement
+class GUIInventoryMenu : public gui::IGUIElement
{
-public:
- GUIInventorySlot(gui::IGUIEnvironment* env,
- gui::IGUIElement* parent, s32 id, core::rect<s32> rect);
-
- void setItem(InventoryItem *item)
+ struct ItemSpec
{
- m_item = item;
- }
-
- void draw();
-
- bool OnEvent(const SEvent& event);
-
-private:
- InventoryItem *m_item;
-};
+ ItemSpec()
+ {
+ i = -1;
+ }
+ ItemSpec(const std::string &a_name, s32 a_i)
+ {
+ listname = a_name;
+ i = a_i;
+ }
+ bool isValid() const
+ {
+ return i != -1;
+ }
+
+ std::string listname;
+ s32 i;
+ };
+
+ struct ListDrawSpec
+ {
+ ListDrawSpec()
+ {
+ }
+ ListDrawSpec(const std::string &a_name, v2s32 a_pos, v2s32 a_geom)
+ {
+ listname = a_name;
+ pos = a_pos;
+ geom = a_geom;
+ }
+
+ std::string listname;
+ v2s32 pos;
+ v2s32 geom;
+ };
-class GUIInventoryMenu : public gui::IGUIElement
-{
public:
GUIInventoryMenu(gui::IGUIEnvironment* env,
gui::IGUIElement* parent, s32 id,
Remove and re-add (or reposition) stuff
*/
void resizeGui();
-
- // Updates stuff from inventory to screen
- // TODO: Remove, not used
- void update();
-
+
+ ItemSpec getItemAtPos(v2s32 p) const;
+ void drawList(const ListDrawSpec &s);
void draw();
void launch()
bool OnEvent(const SEvent& event);
+ // Actions returned by this are sent to the server.
+ // Server replies by updating the inventory.
+ InventoryAction* getNextAction();
+
private:
+ v2s32 getBasePos() const
+ {
+ return padding + AbsoluteRect.UpperLeftCorner;
+ }
+
+ v2s32 padding;
+ v2s32 spacing;
+ v2s32 imgsize;
+
+ core::array<ListDrawSpec> m_draw_positions;
+
Inventory *m_inventory;
v2u32 m_screensize_old;
+
+ ItemSpec *m_selected_item;
+
+ Queue<InventoryAction*> m_actions;
};
#endif
\r
#include "guiPauseMenu.h"\r
#include "debug.h"\r
+#include "serialization.h"\r
\r
GUIPauseMenu::GUIPauseMenu(gui::IGUIEnvironment* env,\r
gui::IGUIElement* parent, s32 id,\r
return;\r
m_screensize_old = screensize;\r
\r
+ /*\r
+ Remove stuff\r
+ */\r
{\r
gui::IGUIElement *e = getElementFromId(256);\r
if(e != NULL)\r
if(e != NULL)\r
e->remove();\r
}\r
+ {\r
+ gui::IGUIElement *e = getElementFromId(258);\r
+ if(e != NULL)\r
+ e->remove();\r
+ }\r
+ {\r
+ gui::IGUIElement *e = getElementFromId(259);\r
+ if(e != NULL)\r
+ e->remove();\r
+ }\r
\r
core::rect<s32> rect(\r
- screensize.X/2 - 560/2,\r
+ screensize.X/2 - 580/2,\r
screensize.Y/2 - 300/2,\r
- screensize.X/2 + 560/2,\r
+ screensize.X/2 + 580/2,\r
screensize.Y/2 + 300/2\r
);\r
\r
\r
v2s32 size = rect.getSize();\r
\r
+ /*\r
+ Add stuff\r
+ */\r
{\r
core::rect<s32> rect(0, 0, 140, 30);\r
rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2-25);\r
rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25);\r
Environment->addButton(rect, this, 257, L"Exit");\r
}\r
+ {\r
+ core::rect<s32> rect(0, 0, 180, 220);\r
+ rect = rect + v2s32(size.X/2 + 90, size.Y/2-rect.getHeight()/2);\r
+ const wchar_t *text =\r
+ L"Keys:\n"\r
+ L"- WASD: Walk\n"\r
+ L"- Mouse left: dig blocks\n"\r
+ L"- Mouse right: place blocks\n"\r
+ L"- Mouse wheel: select item\n"\r
+ L"- R: Toggle viewing all loaded chunks\n"\r
+ L"- I: Inventory menu\n"\r
+ L"- ESC: This menu\n"\r
+ L"\n"\r
+ L"To generate a new map, remove the map directory.\n";\r
+ Environment->addStaticText(text, rect, false, true, this, 258);\r
+ }\r
+ {\r
+ core::rect<s32> rect(0, 0, 180, 220);\r
+ rect = rect + v2s32(size.X/2 - 90 - rect.getWidth(), size.Y/2-rect.getHeight()/2);\r
+ wchar_t text[200];\r
+ swprintf(text, 200,\r
+ L"Minetest-c55\n"\r
+ L"SER_FMT_VER_HIGHEST=%i",\r
+ (int)SER_FMT_VER_HIGHEST\r
+ );\r
+ \r
+ Environment->addStaticText(text, rect, false, true, this, 259);\r
+ }\r
}\r
\r
void GUIPauseMenu::draw()\r
return false;
}
+bool InventoryList::addItem(u32 i, InventoryItem *newitem)
+{
+ // If it is an empty position, it's an easy job.
+ InventoryItem *item = m_items[i];
+ if(item == NULL)
+ {
+ m_items[i] = newitem;
+ return true;
+ }
+
+ // If it is a material item, try to
+ if(std::string("MaterialItem") == newitem->getName())
+ {
+ u8 material = ((MaterialItem*)newitem)->getMaterial();
+ u8 count = ((MaterialItem*)newitem)->getCount();
+ InventoryItem *item2 = m_items[i];
+
+ if(item2 != NULL
+ && std::string("MaterialItem") == item2->getName())
+ {
+ // Check if it is of the right material and has free space
+ MaterialItem *mitem2 = (MaterialItem*)item2;
+ if(mitem2->getMaterial() == material
+ && mitem2->freeSpace() >= count)
+ {
+ // Add to the counter
+ mitem2->add(count);
+ // Dump the parameter
+ delete newitem;
+ // Done
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+void InventoryList::decrementMaterials(u16 count)
+{
+ for(u32 i=0; i<m_items.size(); i++)
+ {
+ InventoryItem *item = m_items[i];
+ if(item == NULL)
+ continue;
+ if(std::string("MaterialItem") == item->getName())
+ {
+ MaterialItem *mitem = (MaterialItem*)item;
+ if(mitem->getCount() < count)
+ {
+ dstream<<__FUNCTION_NAME<<": decrementMaterials():"
+ <<" too small material count"<<std::endl;
+ }
+ else if(mitem->getCount() == count)
+ {
+ deleteItem(i);
+ }
+ else
+ {
+ mitem->remove(1);
+ }
+ }
+ }
+}
+
void InventoryList::print(std::ostream &o)
{
o<<"InventoryList:"<<std::endl;
return -1;
}
+/*
+ InventoryAction
+*/
+
+InventoryAction * InventoryAction::deSerialize(std::istream &is)
+{
+ std::string type;
+ std::getline(is, type, ' ');
+
+ InventoryAction *a = NULL;
+
+ if(type == "Move")
+ {
+ a = new IMoveAction(is);
+ }
+
+ return a;
+}
+
+void IMoveAction::apply(Inventory *inventory)
+{
+ /*dstream<<"from_name="<<from_name<<" to_name="<<to_name<<std::endl;
+ dstream<<"from_i="<<from_i<<" to_i="<<to_i<<std::endl;*/
+ InventoryList *list_from = inventory->getList(from_name);
+ InventoryList *list_to = inventory->getList(to_name);
+ /*dstream<<"list_from="<<list_from<<" list_to="<<list_to
+ <<std::endl;*/
+ /*if(list_from)
+ dstream<<" list_from->getItem(from_i)="<<list_from->getItem(from_i)
+ <<std::endl;
+ if(list_to)
+ dstream<<" list_to->getItem(to_i)="<<list_to->getItem(to_i)
+ <<std::endl;*/
+
+ if(!list_from || !list_to || list_from->getItem(from_i) == NULL
+ || (list_from == list_to && from_i == to_i))
+ {
+ dstream<<__FUNCTION_NAME<<": Operation not allowed"<<std::endl;
+ return;
+ }
+
+ // Take item from source list
+ InventoryItem *item1 = list_from->changeItem(from_i, NULL);
+ // Try to add the item to destination list
+ if(list_to->addItem(to_i, item1))
+ {
+ // Done.
+ return;
+ }
+ // Adding was not possible, switch it.
+ // Switch it to the destination list
+ InventoryItem *item2 = list_to->changeItem(to_i, item1);
+ // Put item from destination list to the source list
+ list_from->changeItem(from_i, item2);
+}
//END
// Count used slots
u32 getUsedSlots();
+ // Get pointer to item
InventoryItem * getItem(u32 i);
// Returns old item (or NULL). Parameter can be NULL.
InventoryItem * changeItem(u32 i, InventoryItem *newitem);
+ // Delete item
void deleteItem(u32 i);
// Adds an item to a suitable place. Returns false if failed.
bool addItem(InventoryItem *newitem);
+ // If possible, adds item to given slot. Returns true on success.
+ // Fails when slot is populated by a different kind of item.
+ bool addItem(u32 i, InventoryItem *newitem);
+
+ // Decrements amount of every material item
+ void decrementMaterials(u16 count);
void print(std::ostream &o);
core::array<InventoryList*> m_lists;
};
+#define IACTION_MOVE 0
+
+struct InventoryAction
+{
+ static InventoryAction * deSerialize(std::istream &is);
+
+ virtual u16 getType() const = 0;
+ virtual void serialize(std::ostream &os) = 0;
+ virtual void apply(Inventory *inventory) = 0;
+};
+
+struct IMoveAction : public InventoryAction
+{
+ u16 count;
+ std::string from_name;
+ s16 from_i;
+ std::string to_name;
+ s16 to_i;
+
+ IMoveAction()
+ {
+ count = 0;
+ from_i = -1;
+ to_i = -1;
+ }
+ IMoveAction(std::istream &is)
+ {
+ std::string ts;
+
+ std::getline(is, ts, ' ');
+ count = stoi(ts);
+
+ std::getline(is, from_name, ' ');
+
+ std::getline(is, ts, ' ');
+ from_i = stoi(ts);
+
+ std::getline(is, to_name, ' ');
+
+ std::getline(is, ts, ' ');
+ to_i = stoi(ts);
+ }
+
+ u16 getType() const
+ {
+ return IACTION_MOVE;
+ }
+
+ void serialize(std::ostream &os)
+ {
+ os<<"Move ";
+ os<<count<<" ";
+ os<<from_name<<" ";
+ os<<from_i<<" ";
+ os<<to_name<<" ";
+ os<<to_i;
+ }
+
+ void apply(Inventory *inventory);
+};
+
#endif
client.getLocalInventory(local_inventory);\r
quick_inventory->setSelection(g_selected_item);\r
quick_inventory->update();\r
- inventoryMenu->update();\r
+ }\r
+ \r
+ /*\r
+ Send actions returned by the inventory menu\r
+ */\r
+ while(InventoryAction *a = inventoryMenu->getNextAction())\r
+ {\r
+ client.sendInventoryAction(a);\r
+ // Eat it\r
+ delete a;\r
}\r
\r
if(input_guitext != NULL)\r
Add some minerals
*/
- //if(is_underground)
if(some_part_underground)
{
s16 underground_level = (lowest_ground_y/MAP_BLOCKSIZE - block_y)+1;
- for(s16 i=0; i<underground_level*3; i++)
+ for(s16 i=0; i<underground_level*1; i++)
{
if(rand()%2 == 0)
{
}
}
}
+
+ if(rand()%3 == 0)
+ {
+ for(s16 i=0; i<20; i++)
+ {
+ v3s16 cp(
+ (rand()%(MAP_BLOCKSIZE-2))+1,
+ (rand()%(MAP_BLOCKSIZE-2))+1,
+ (rand()%(MAP_BLOCKSIZE-2))+1
+ );
+
+ MapNode n;
+ n.d = CONTENT_COALSTONE;
+
+ //dstream<<"Adding coalstone"<<std::endl;
+
+ //if(is_ground_content(block->getNode(cp).d))
+ if(block->getNode(cp).d == CONTENT_STONE)
+ if(rand()%8 == 0)
+ block->setNode(cp, n);
+
+ for(u16 i=0; i<26; i++)
+ {
+ //if(is_ground_content(block->getNode(cp+g_26dirs[i]).d))
+ if(block->getNode(cp+g_26dirs[i]).d == CONTENT_STONE)
+ if(rand()%8 == 0)
+ block->setNode(cp+g_26dirs[i], n);
+ }
+ }
+ }
}
/*
{TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD},
{TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER},
{TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD},
+ {TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE,TILE_COALSTONE},
};
const char * g_content_inventory_textures[USEFUL_CONTENT_COUNT] =
"../data/mud.png",
"../data/water.png",
"../data/cloud.png",
+ "../data/coalstone.png",
};
CONTENT_MUD,
CONTENT_OCEAN,
CONTENT_CLOUD,
+ CONTENT_COALSTONE,
// This is set to the number of the actual values in this enum
USEFUL_CONTENT_COUNT
updateName("<not set>");
inventory.addList("main", PLAYER_INVENTORY_SIZE);
inventory.addList("craft", 9);
+ inventory.addList("craftresult", 1);
}
Player::~Player()
obj->getBlock()->setChangedFlag();
}
+ else if(command == TOSERVER_INVENTORY_ACTION)
+ {
+ // Ignore inventory changes if in creative mode
+ if(g_settings.getBool("creative_mode") == true)
+ {
+ dstream<<"TOSERVER_INVENTORY_ACTION: ignoring in creative mode"
+ <<std::endl;
+ return;
+ }
+ // Strip command and create a stream
+ std::string datastring((char*)&data[2], datasize-2);
+ dstream<<"TOSERVER_INVENTORY_ACTION: data="<<datastring<<std::endl;
+ std::istringstream is(datastring, std::ios_base::binary);
+ // Create an action
+ InventoryAction *a = InventoryAction::deSerialize(is);
+ if(a != NULL)
+ {
+ /*
+ Handle craftresult specially
+ */
+ bool disable_action = false;
+ if(a->getType() == IACTION_MOVE)
+ {
+ IMoveAction *ma = (IMoveAction*)a;
+ // Don't allow moving anything to craftresult
+ if(ma->to_name == "craftresult")
+ {
+ // Do nothing
+ disable_action = true;
+ }
+ // When something is removed from craftresult
+ if(ma->from_name == "craftresult")
+ {
+ disable_action = true;
+ // Remove stuff from craft
+ InventoryList *clist = player->inventory.getList("craft");
+ if(clist)
+ {
+ clist->decrementMaterials(ma->count);
+ }
+ // Do action
+ // Feed action to player inventory
+ a->apply(&player->inventory);
+ // Eat it
+ delete a;
+ // If something appeared in craftresult, throw it
+ // in the main list
+ InventoryList *rlist = player->inventory.getList("craftresult");
+ InventoryList *mlist = player->inventory.getList("main");
+ if(rlist && mlist && rlist->getUsedSlots() == 1)
+ {
+ InventoryItem *item1 = rlist->changeItem(0, NULL);
+ mlist->addItem(item1);
+ }
+ }
+ }
+ if(disable_action == false)
+ {
+ // Feed action to player inventory
+ a->apply(&player->inventory);
+ // Eat it
+ delete a;
+ }
+ // Send inventory
+ SendInventory(player->peer_id);
+ }
+ else
+ {
+ dstream<<"TOSERVER_INVENTORY_ACTION: "
+ <<"InventoryAction::deSerialize() returned NULL"
+ <<std::endl;
+ }
+ }
else
{
derr_server<<"WARNING: Server::ProcessData(): Ignoring "
}
else
{
- // Give some lights
+ /*// Give some lights
{
- InventoryItem *item = new MaterialItem(3, 999);
+ InventoryItem *item = new MaterialItem(CONTENT_TORCH, 999);
bool r = player->inventory.addItem("main", item);
assert(r == true);
}
InventoryItem *item = new MapBlockObjectItem("Sign Example text");
bool r = player->inventory.addItem("main", item);
assert(r == true);
- }
- /*// and some rats
- for(u16 i=0; i<4; i++)
+ }*/
+ /*// Give some other stuff
{
- InventoryItem *item = new MapBlockObjectItem("Rat");
+ InventoryItem *item = new MaterialItem(CONTENT_TREE, 999);
bool r = player->inventory.addItem("main", item);
assert(r == true);
}*/
Player* player = m_env.getPlayer(peer_id);
+ /*
+ Calculate crafting stuff
+ */
+
+ InventoryList *clist = player->inventory.getList("craft");
+ InventoryList *rlist = player->inventory.getList("craftresult");
+ if(rlist)
+ {
+ //rlist->clearItems();
+ }
+ if(clist && rlist)
+ {
+ InventoryItem *items[9];
+ for(u16 i=0; i<9; i++)
+ {
+ items[i] = clist->getItem(i);
+ }
+ // Sign
+ if(clist->getUsedSlots() == 1 && items[0])
+ {
+ if((std::string)items[0]->getName() == "MaterialItem")
+ {
+ MaterialItem *mitem = (MaterialItem*)items[0];
+ if(mitem->getMaterial() == CONTENT_TREE)
+ {
+ rlist->addItem(new MapBlockObjectItem("Sign"));
+ }
+ }
+ }
+ // Torch
+ if(clist->getUsedSlots() == 2 && items[0] && items[3])
+ {
+ if(
+ (std::string)items[0]->getName() == "MaterialItem"
+ && ((MaterialItem*)items[0])->getMaterial() == CONTENT_COALSTONE
+ && (std::string)items[3]->getName() == "MaterialItem"
+ && ((MaterialItem*)items[3])->getMaterial() == CONTENT_TREE
+ )
+ {
+ rlist->addItem(new MaterialItem(CONTENT_TORCH, 4));
+ }
+ }
+ }
+
+ /*
+ Serialize it
+ */
+
std::ostringstream os;
//os.imbue(std::locale("C"));
#include <string>
-std::string trim(std::string str);
+std::string trim(const std::string &str);
class Strfnd{
std::string tek;
}
};
-inline std::string trim(std::string str)
+inline std::string trim(const std::string &s)
{
+ std::string str = s;
while(
str.length()>0
&&
"../data/tree_top.png",
"../data/mud_with_grass.png",
"../data/cloud.png",
+ "../data/coalstone.png",
};
const char * tile_texture_path_get(u32 i)
TILE_TREE_TOP,
TILE_MUD_WITH_GRASS,
TILE_CLOUD,
+ TILE_COALSTONE,
// Count of tile ids
TILES_COUNT
return f;
}
-inline std::string lowercase(std::string s)
+inline std::string lowercase(const std::string &s)
{
+ std::string s2;
for(size_t i=0; i<s.size(); i++)
{
- if(s[i] >= 'A' && s[i] <= 'Z')
- s[i] -= 'A' - 'a';
+ char c = s[i];
+ if(c >= 'A' && c <= 'Z')
+ c -= 'A' - 'a';
+ s2 += c;
}
- return s;
+ return s2;
}
-inline bool is_yes(std::string s)
+inline bool is_yes(const std::string &s)
{
- s = lowercase(trim(s));
- if(s == "y" || s == "yes" || s == "true")
+ std::string s2 = lowercase(trim(s));
+ if(s2 == "y" || s2 == "yes" || s2 == "true")
return true;
return false;
}
-inline s32 stoi(std::string s, s32 min, s32 max)
+inline s32 stoi(const std::string &s, s32 min, s32 max)
{
s32 i = atoi(s.c_str());
if(i < min)
};
/*
- A thread-safe queue
+ FIFO queue
+*/
+template<typename T>
+class Queue
+{
+public:
+ void push_back(T t)
+ {
+ m_list.push_back(t);
+ }
+
+ T pop_front()
+ {
+ if(m_list.size() == 0)
+ throw ItemNotFoundException("MutexedQueue: queue is empty");
+
+ typename core::list<T>::Iterator begin = m_list.begin();
+ T t = *begin;
+ m_list.erase(begin);
+ return t;
+ }
+
+ u32 size()
+ {
+ return m_list.size();
+ }
+
+protected:
+ core::list<T> m_list;
+};
+
+/*
+ Thread-safe FIFO queue
*/
template<typename T>