better caves
authorPerttu Ahola <celeron55@gmail.com>
Sat, 25 Dec 2010 14:04:51 +0000 (16:04 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Sat, 25 Dec 2010 14:04:51 +0000 (16:04 +0200)
src/guiInventoryMenu.cpp
src/guiInventoryMenu.h
src/guiPauseMenu.cpp
src/irrlichtwrapper.cpp
src/main.cpp
src/map.cpp
src/map.h
src/server.cpp
src/utility.h

index a1f7d02d003a109a583776a16765c43e54038be0..d7af0a0b955538627b917dfe7da05b8c6760cc44 100644 (file)
@@ -93,19 +93,35 @@ GUIInventoryMenu::GUIInventoryMenu(gui::IGUIEnvironment* env,
 
 GUIInventoryMenu::~GUIInventoryMenu()
 {
+       removeChildren();
+
        if(m_selected_item)
                delete m_selected_item;
 }
 
+void GUIInventoryMenu::removeChildren()
+{
+       {
+               gui::IGUIElement *e = getElementFromId(256);
+               if(e != NULL)
+                       e->remove();
+       }
+}
+
 void GUIInventoryMenu::regenerateGui(v2u32 screensize)
 {
+       // Remove children
+       removeChildren();
+       
        padding = v2s32(24,24);
        spacing = v2s32(60,56);
        imgsize = v2s32(48,48);
 
+       s32 helptext_h = 15;
+
        v2s32 size(
                padding.X*2+spacing.X*(8-1)+imgsize.X,
-               padding.Y*2+spacing.Y*(7-1)+imgsize.Y
+               padding.Y*2+spacing.Y*(7-1)+imgsize.Y + helptext_h
        );
 
        core::rect<s32> rect(
@@ -127,6 +143,16 @@ void GUIInventoryMenu::regenerateGui(v2u32 screensize)
                        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)));
+       
+       // Add children
+       {
+               core::rect<s32> rect(0, 0, size.X-padding.X*2, helptext_h);
+               rect = rect + v2s32(size.X/2 - rect.getWidth()/2,
+                               size.Y-rect.getHeight()-15);
+               const wchar_t *text =
+               L"Left click: Move all items, Right click: Move single item";
+               Environment->addStaticText(text, rect, false, true, this, 256);
+       }
 }
 
 GUIInventoryMenu::ItemSpec GUIInventoryMenu::getItemAtPos(v2s32 p) const
@@ -244,22 +270,25 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event)
                                                        m_inventory->getList(m_selected_item->listname);
                                        InventoryList *list_to =
                                                        m_inventory->getList(s.listname);
+                                       // Indicates whether source slot completely empties
+                                       bool source_empties = false;
                                        if(list_from && list_to
                                                        && list_from->getItem(m_selected_item->i) != NULL)
                                        {
                                                dstream<<"Queueing IACTION_MOVE"<<std::endl;
-                                               IMoveAction *a =
-                                                       new IMoveAction();
+                                               IMoveAction *a = new IMoveAction();
                                                a->count = right ? 1 : 0;
                                                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);
+                                               
+                                               if(list_from->getItem(m_selected_item->i)->getCount()==1)
+                                                       source_empties = true;
                                        }
-                                       bool source_empties = false;
-                                       if(list_from && list_from->getItem(m_selected_item->i)->getCount()==1)
-                                               source_empties = true;
+                                       // Remove selection if target was left-clicked or source
+                                       // slot was emptied
                                        if(right == false || source_empties)
                                        {
                                                delete m_selected_item;
index b6766484ebf69f835e50c5de3fcd48e8720c904e..82e7ee89d7a5305a8e92de87e047b9a39e18ac15 100644 (file)
@@ -77,6 +77,7 @@ public:
                        int *active_menu_count);
        ~GUIInventoryMenu();
 
+       void removeChildren();
        /*
                Remove and re-add (or reposition) stuff
        */
index 10d272b35b947221d82064a540d770120affc997..9ff21a437e227369b28c69c10416e8200b5cda45 100644 (file)
@@ -114,11 +114,21 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize)
        {\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
+       \r
+               v2u32 max_texture_size;\r
+               {\r
+                       video::IVideoDriver* driver = Environment->getVideoDriver();\r
+                       max_texture_size = driver->getMaxTextureSize();\r
+               }\r
+\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
+                               L"SER_FMT_VER_HIGHEST=%i\n"\r
+                               L"max_texture_size=\n(%i,%i)\n",\r
+                               (int)SER_FMT_VER_HIGHEST,\r
+                               max_texture_size.X,\r
+                               max_texture_size.Y\r
                );\r
        \r
                Environment->addStaticText(text, rect, false, true, this, 259);\r
index 30de6846cf501f73c02aacc29b99128a5d60b80e..81cd7f9f06a1096f846f4f9645d4c5f5f1160c9c 100644 (file)
@@ -1,4 +1,5 @@
 #include "irrlichtwrapper.h"
+#include "constants.h"
 
 IrrlichtWrapper::IrrlichtWrapper(IrrlichtDevice *device)
 {
@@ -119,10 +120,17 @@ video::ITexture * CrackTextureMod::make(video::ITexture *original,
        assert(baseimage);
        
        video::ITexture *other = driver->getTexture("../data/crack.png");
+
        // We have to get the whole texture because getting a smaller area
        // messes the whole thing. It is probably a bug in Irrlicht.
+       // NOTE: This doesn't work probably because some systems scale
+       //       the image to fit a texture or something...
+       /*video::IImage *otherimage = driver->createImage(
+                       other, core::position2d<s32>(0,0), other->getSize());*/
+       // This should work on more systems
        video::IImage *otherimage = driver->createImage(
-                       other, core::position2d<s32>(0,0), other->getSize());
+                       other, core::position2d<s32>(0,0),
+                       v2u32(16, CRACK_ANIMATION_LENGTH * 16));
 
        assert(otherimage);
        
index 47840eae8d65a18798be0be58a2d534c86dae02e..0cb16c0332d991705295a4416e4175132dea2e17 100644 (file)
@@ -184,9 +184,8 @@ TODO: There has to be some better way to handle static objects than to
 Doing now:\r
 ======================================================================\r
 \r
-TODO: Tool capability table: Which materials, at what speed, how much\r
-      wearing\r
-TODO: Transferring of the table from server to client\r
+TODO: When server sees that client is removing an inexistent block or\r
+      adding a block to an existent position, resend the MapBlock.\r
 \r
 ======================================================================\r
 \r
@@ -1545,10 +1544,10 @@ int main(int argc, char *argv[])
                                &g_active_menu_count,\r
                                L"Asd");\r
        menu->drop();*/\r
-               \r
+       \r
        // Launch pause menu\r
-       /*(new GUIPauseMenu(guienv, guiroot, -1, g_device,\r
-                       &g_active_menu_count))->drop();*/\r
+       (new GUIPauseMenu(guienv, guiroot, -1, g_device,\r
+                       &g_active_menu_count))->drop();\r
 \r
        // First line of debug text\r
        gui::IGUIStaticText *guitext = guienv->addStaticText(\r
@@ -2349,23 +2348,36 @@ int main(int argc, char *argv[])
                        while(client.getChatMessage(message))\r
                        {\r
                                chat_lines.push_back(ChatLine(message));\r
-                               if(chat_lines.size() > 5)\r
+                               /*if(chat_lines.size() > 6)\r
                                {\r
                                        core::list<ChatLine>::Iterator\r
                                                        i = chat_lines.begin();\r
                                        chat_lines.erase(i);\r
-                               }\r
+                               }*/\r
                        }\r
                        // Append them to form the whole static text and throw\r
                        // it to the gui element\r
                        std::wstring whole;\r
+                       // This will correspond to the line number counted from\r
+                       // top to bottom, from size-1 to 0\r
+                       s16 line_number = chat_lines.size();\r
+                       // Count of messages to be removed from the top\r
                        u16 to_be_removed_count = 0;\r
                        for(core::list<ChatLine>::Iterator\r
                                        i = chat_lines.begin();\r
                                        i != chat_lines.end(); i++)\r
                        {\r
+                               // After this, line number is valid for this loop\r
+                               line_number--;\r
+                               // Increment age\r
                                (*i).age += dtime;\r
-                               if((*i).age > 300.0)\r
+                               /*\r
+                                       This results in a maximum age of 60*6 to the\r
+                                       lowermost line and a maximum of 6 lines\r
+                               */\r
+                               float allowed_age = (6-line_number) * 60.0;\r
+\r
+                               if((*i).age > allowed_age)\r
                                {\r
                                        to_be_removed_count++;\r
                                        continue;\r
index fe94d6e971222b866084f2f4621a325d7d1ab444..9a23863d573db8a42c79bd55c9c03b01655342c7 100644 (file)
@@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "voxel.h"
 #include "porting.h"
 
+#if 0
 MapBlockPointerCache::MapBlockPointerCache(Map *map)
 {
        m_map = map;
@@ -62,6 +63,7 @@ MapBlock * MapBlockPointerCache::getBlockNoCreate(v3s16 p)
        m_blocks[p] = b;
        return b;
 }
+#endif
 
 /*
        Map
@@ -1727,24 +1729,25 @@ MapBlock * ServerMap::emergeBlock(
                // Allocate the block to be a proper one.
                block->unDummify();
        }
-
-       // Randomize a bit. This makes dungeons.
-       /*bool low_block_is_empty = false;
-       if(rand() % 4 == 0)
-               low_block_is_empty = true;*/
        
-       const s32 ued = 4;
-       //const s32 ued = 8;
-       bool underground_emptiness[ued*ued*ued];
+#if 0
+       /*
+               Initialize dungeon making by creating a random table
+       */
+       const s32 ued_max = 5;
+       const s32 ued_min = 3;
+       bool underground_emptiness[ued_max*ued_max*ued_max];
+       s32 ued = (rand()%(ued_max-ued_min+1))+1;
+       //s32 ued = ued_max;
        for(s32 i=0; i<ued*ued*ued; i++)
        {
                underground_emptiness[i] = ((rand() % 5) == 0);
        }
 
-#if 1
        /*
                This is a messy hack to sort the emptiness a bit
        */
+       // Iterator through a few times
        for(s32 j=0; j<2; j++)
        for(s32 y0=0; y0<ued; y0++)
        for(s32 z0=0; z0<ued; z0++)
@@ -1764,6 +1767,7 @@ MapBlock * ServerMap::emergeBlock(
                        /*v3s16(0,1,0), // top
                        v3s16(0,-1,0), // bottom*/
                };
+
                for(s32 i=0; i<4; i++)
                {
                        v3s16 p1 = p0 + dirs[i];
@@ -1808,6 +1812,140 @@ MapBlock * ServerMap::emergeBlock(
                }
        }
 #endif
+
+       /*
+               Create dungeon making table
+       */
+       const s32 ued = MAP_BLOCKSIZE;
+       bool underground_emptiness[ued*ued*ued];
+       for(s32 i=0; i<ued*ued*ued; i++)
+       {
+               underground_emptiness[i] = 0;
+       }
+       // Generate dungeons
+       {
+               /*
+                       Initialize orp and ors. Try to find if some neighboring
+                       MapBlock has a tunnel ended in its side
+               */
+
+               v3f orp;
+               s16 ors;
+
+               // Check z-
+               try
+               {
+                       s16 z = -1;
+                       for(s16 y=0; y<ued; y++)
+                       for(s16 x=0; x<ued; x++)
+                       {
+                               v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
+                               if(getNode(ap).d == CONTENT_AIR)
+                               {
+                                       orp = v3f(x+1,y+1,0);
+                                       ors = 4;
+                               }
+                       }
+               }
+               catch(InvalidPositionException &e){}
+               
+               // Check z+
+               try
+               {
+                       s16 z = ued;
+                       for(s16 y=0; y<ued; y++)
+                       for(s16 x=0; x<ued; x++)
+                       {
+                               v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
+                               if(getNode(ap).d == CONTENT_AIR)
+                               {
+                                       orp = v3f(x+1,y+1,ued-1);
+                                       ors = 4;
+                               }
+                       }
+               }
+               catch(InvalidPositionException &e){}
+               
+               // Check x-
+               try
+               {
+                       s16 x = -1;
+                       for(s16 y=0; y<ued; y++)
+                       for(s16 z=0; z<ued; z++)
+                       {
+                               v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
+                               if(getNode(ap).d == CONTENT_AIR)
+                               {
+                                       orp = v3f(0,y+1,z+1);
+                                       ors = 4;
+                               }
+                       }
+               }
+               catch(InvalidPositionException &e){}
+               
+               // Check x+
+               try
+               {
+                       s16 x = ued;
+                       for(s16 y=0; y<ued; y++)
+                       for(s16 z=0; z<ued; z++)
+                       {
+                               v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
+                               if(getNode(ap).d == CONTENT_AIR)
+                               {
+                                       orp = v3f(ued-1,y+1,z+1);
+                                       ors = 4;
+                               }
+                       }
+               }
+               catch(InvalidPositionException &e){}
+               
+               /*
+                       Generate some tunnel starting from orp and ors
+               */
+               for(u16 i=0; i<3; i++)
+               {
+                       v3f rp(
+                               (float)(rand()%(ued-1))+0.5,
+                               (float)(rand()%(ued-1))+0.5,
+                               (float)(rand()%(ued-1))+0.5
+                       );
+                       s16 min_d = 0;
+                       s16 max_d = 4;
+                       s16 rs = (rand()%(max_d-min_d+1))+min_d;
+                       
+                       v3f vec = rp - orp;
+
+                       for(float f=0; f<1.0; f+=0.04)
+                       {
+                               v3f fp = orp + vec * f;
+                               v3s16 cp(fp.X, fp.Y, fp.Z);
+                               s16 d0 = -rs/2;
+                               s16 d1 = d0 + rs - 1;
+                               for(s16 z0=d0; z0<=d1; z0++)
+                               {
+                                       s16 si = rs - abs(z0);
+                                       for(s16 x0=-si; x0<=si-1; x0++)
+                                       {
+                                               s16 si2 = rs - abs(x0);
+                                               for(s16 y0=-si2+1; y0<=si2-1; y0++)
+                                               {
+                                                       s16 z = cp.Z + z0;
+                                                       s16 y = cp.Y + y0;
+                                                       s16 x = cp.X + x0;
+                                                       v3s16 p(x,y,z);
+                                                       if(isInArea(p, ued) == false)
+                                                               continue;
+                                                       underground_emptiness[ued*ued*z + ued*y + x] = 1;
+                                               }
+                                       }
+                               }
+                       }
+
+                       orp = rp;
+                       ors = rs;
+               }
+       }
        
        // This is the basic material of what the visible flat ground
        // will consist of
index 2a3fa5061b30744da0ee7b6db5521112b2bae981..3c3fe9dafab9f2648fbee5c0642301bd05337666 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -43,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 class Map;
 
+#if 0
 /*
        A cache for short-term fast access to map data
 
@@ -108,6 +109,7 @@ private:
        u32 m_from_cache_count;
        u32 m_from_map_count;
 };
+#endif
 
 class CacheLock
 {
@@ -303,6 +305,7 @@ public:
        }
        
        // virtual from NodeContainer
+       // throws InvalidPositionException if not found
        MapNode getNode(v3s16 p)
        {
                v3s16 blockpos = getNodeBlockPos(p);
@@ -313,6 +316,7 @@ public:
        }
 
        // virtual from NodeContainer
+       // throws InvalidPositionException if not found
        void setNode(v3s16 p, MapNode & n)
        {
                v3s16 blockpos = getNodeBlockPos(p);
index c8f9be00e986c861916a068cf38dd7755e280ba7..cbe2b932fe4641ecd07bbc25361ba6c028a5e1ba 100644 (file)
@@ -2215,13 +2215,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
        }
        else if(command == TOSERVER_INVENTORY_ACTION)
        {
-               // Ignore inventory changes if in creative mode
+               /*// 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;
@@ -2231,10 +2231,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                if(a != NULL)
                {
                        /*
-                               Handle craftresult specially
+                               Handle craftresult specially if not in creative mode
                        */
                        bool disable_action = false;
-                       if(a->getType() == IACTION_MOVE)
+                       if(a->getType() == IACTION_MOVE
+                                       && g_settings.getBool("creative_mode") == false)
                        {
                                IMoveAction *ma = (IMoveAction*)a;
                                // Don't allow moving anything to craftresult
@@ -2311,13 +2312,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                        message += (wchar_t)readU16(buf);
                }
 
-               dstream<<"CHAT: "<<wide_to_narrow(message)<<std::endl;
-
                // Get player name of this client
                std::wstring name = narrow_to_wide(player->getName());
 
                std::wstring line = std::wstring(L"<")+name+L"> "+message;
                
+               dstream<<"CHAT: "<<wide_to_narrow(line)<<std::endl;
+
                /*
                        Send the message to all other clients
                */
@@ -2674,127 +2675,128 @@ void Server::SendInventory(u16 peer_id)
        /*
                Calculate crafting stuff
        */
-
-       InventoryList *clist = player->inventory.getList("craft");
-       InventoryList *rlist = player->inventory.getList("craftresult");
-       if(rlist)
+       if(g_settings.getBool("creative_mode") == false)
        {
-               rlist->clearItems();
-       }
-       if(clist && rlist)
-       {
-               InventoryItem *items[9];
-               for(u16 i=0; i<9; i++)
+               InventoryList *clist = player->inventory.getList("craft");
+               InventoryList *rlist = player->inventory.getList("craftresult");
+               if(rlist)
                {
-                       items[i] = clist->getItem(i);
+                       rlist->clearItems();
                }
-               
-               bool found = false;
-
-               // Wood
-               if(!found)
+               if(clist && rlist)
                {
-                       ItemSpec specs[9];
-                       specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_TREE);
-                       if(checkItemCombination(items, specs))
+                       InventoryItem *items[9];
+                       for(u16 i=0; i<9; i++)
                        {
-                               rlist->addItem(new MaterialItem(CONTENT_WOOD, 4));
-                               found = true;
+                               items[i] = clist->getItem(i);
                        }
-               }
+                       
+                       bool found = false;
 
-               // Stick
-               if(!found)
-               {
-                       ItemSpec specs[9];
-                       specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
-                       if(checkItemCombination(items, specs))
+                       // Wood
+                       if(!found)
                        {
-                               rlist->addItem(new CraftItem("Stick", 4));
-                               found = true;
+                               ItemSpec specs[9];
+                               specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_TREE);
+                               if(checkItemCombination(items, specs))
+                               {
+                                       rlist->addItem(new MaterialItem(CONTENT_WOOD, 4));
+                                       found = true;
+                               }
                        }
-               }
 
-               // Sign
-               if(!found)
-               {
-                       ItemSpec specs[9];
-                       specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
-                       specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
-                       specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
-                       specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
-                       specs[4] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
-                       specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
-                       specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
-                       if(checkItemCombination(items, specs))
+                       // Stick
+                       if(!found)
                        {
-                               rlist->addItem(new MapBlockObjectItem("Sign"));
-                               found = true;
+                               ItemSpec specs[9];
+                               specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
+                               if(checkItemCombination(items, specs))
+                               {
+                                       rlist->addItem(new CraftItem("Stick", 4));
+                                       found = true;
+                               }
                        }
-               }
 
-               // Torch
-               if(!found)
-               {
-                       ItemSpec specs[9];
-                       specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COALSTONE);
-                       specs[3] = ItemSpec(ITEM_CRAFT, "Stick");
-                       if(checkItemCombination(items, specs))
+                       // Sign
+                       if(!found)
                        {
-                               rlist->addItem(new MaterialItem(CONTENT_TORCH, 4));
-                               found = true;
+                               ItemSpec specs[9];
+                               specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
+                               specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
+                               specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
+                               specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
+                               specs[4] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
+                               specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
+                               specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
+                               if(checkItemCombination(items, specs))
+                               {
+                                       rlist->addItem(new MapBlockObjectItem("Sign"));
+                                       found = true;
+                               }
                        }
-               }
 
-               // Wooden pick
-               if(!found)
-               {
-                       ItemSpec specs[9];
-                       specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
-                       specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
-                       specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
-                       specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
-                       specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
-                       if(checkItemCombination(items, specs))
+                       // Torch
+                       if(!found)
                        {
-                               rlist->addItem(new ToolItem("WPick", 0));
-                               found = true;
+                               ItemSpec specs[9];
+                               specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COALSTONE);
+                               specs[3] = ItemSpec(ITEM_CRAFT, "Stick");
+                               if(checkItemCombination(items, specs))
+                               {
+                                       rlist->addItem(new MaterialItem(CONTENT_TORCH, 4));
+                                       found = true;
+                               }
                        }
-               }
 
-               // Stone pick
-               if(!found)
-               {
-                       ItemSpec specs[9];
-                       specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE);
-                       specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE);
-                       specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE);
-                       specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
-                       specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
-                       if(checkItemCombination(items, specs))
+                       // Wooden pick
+                       if(!found)
                        {
-                               rlist->addItem(new ToolItem("STPick", 0));
-                               found = true;
+                               ItemSpec specs[9];
+                               specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
+                               specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
+                               specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD);
+                               specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
+                               specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
+                               if(checkItemCombination(items, specs))
+                               {
+                                       rlist->addItem(new ToolItem("WPick", 0));
+                                       found = true;
+                               }
                        }
-               }
 
-               // Mese pick
-               if(!found)
-               {
-                       ItemSpec specs[9];
-                       specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE);
-                       specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE);
-                       specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE);
-                       specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
-                       specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
-                       if(checkItemCombination(items, specs))
+                       // Stone pick
+                       if(!found)
                        {
-                               rlist->addItem(new ToolItem("MesePick", 0));
-                               found = true;
+                               ItemSpec specs[9];
+                               specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE);
+                               specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE);
+                               specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_STONE);
+                               specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
+                               specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
+                               if(checkItemCombination(items, specs))
+                               {
+                                       rlist->addItem(new ToolItem("STPick", 0));
+                                       found = true;
+                               }
                        }
-               }
 
-       }
+                       // Mese pick
+                       if(!found)
+                       {
+                               ItemSpec specs[9];
+                               specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE);
+                               specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE);
+                               specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE);
+                               specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
+                               specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
+                               if(checkItemCombination(items, specs))
+                               {
+                                       rlist->addItem(new ToolItem("MesePick", 0));
+                                       found = true;
+                               }
+                       }
+               }
+       } // if creative_mode == false
 
        /*
                Serialize it
@@ -3025,18 +3027,32 @@ void Server::handlePeerChange(PeerChange &c)
                        
                        if(g_settings.getBool("creative_mode"))
                        {
-                               // Give a good pick
+                               // Give some good picks
                                {
-                                       InventoryItem *item = new ToolItem("STPick", 32000);
+                                       InventoryItem *item = new ToolItem("STPick", 0);
                                        void* r = player->inventory.addItem("main", item);
                                        assert(r == NULL);
                                }
-                               // Give all materials
+                               {
+                                       InventoryItem *item = new ToolItem("MesePick", 0);
+                                       void* r = player->inventory.addItem("main", item);
+                                       assert(r == NULL);
+                               }
+
+                               /*
+                                       Give materials
+                               */
                                assert(USEFUL_CONTENT_COUNT <= PLAYER_INVENTORY_SIZE);
+                               
+                               // add torch first
+                               InventoryItem *item = new MaterialItem(CONTENT_TORCH, 1);
+                               player->inventory.addItem("main", item);
+                               
+                               // Then others
                                for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
                                {
                                        // Skip some materials
-                                       if(i == CONTENT_OCEAN)
+                                       if(i == CONTENT_OCEAN || i == CONTENT_TORCH)
                                                continue;
 
                                        InventoryItem *item = new MaterialItem(i, 1);
@@ -3048,12 +3064,6 @@ void Server::handlePeerChange(PeerChange &c)
                                        void* r = player->inventory.addItem("main", item);
                                        assert(r == NULL);
                                }
-                               /*// Rat
-                               {
-                                       InventoryItem *item = new MapBlockObjectItem("Rat");
-                                       bool r = player->inventory.addItem("main", item);
-                                       assert(r == true);
-                               }*/
                        }
                        else
                        {
index bcdcd15509b4affbbaef125198d09bc843f1028b..3764616d09373370e1873ec8d49f5552ae2a1ee5 100644 (file)
@@ -550,6 +550,41 @@ inline bool isInArea(v2s16 p, s16 d)
        );
 }
 
+inline s16 rangelim(s16 i, s16 min, s16 max)
+{
+       if(i < min)
+               return min;
+       if(i > max)
+               return max;
+       return i;
+}
+
+inline s16 rangelim(s16 i, s16 max)
+{
+       if(i < 0)
+               return 0;
+       if(i > max)
+               return max;
+       return i;
+}
+
+inline v3s16 arealim(v3s16 p, s16 d)
+{
+       if(p.X < 0)
+               p.X = 0;
+       if(p.Y < 0)
+               p.Y = 0;
+       if(p.Z < 0)
+               p.Z = 0;
+       if(p.X > d-1)
+               p.X = d-1;
+       if(p.Y > d-1)
+               p.Y = d-1;
+       if(p.Z > d-1)
+               p.Z = d-1;
+       return p;
+}
+
 inline std::wstring narrow_to_wide(const std::string& mbs)
 {
        size_t wcl = mbs.size();