]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/guiFormSpecMenu.cpp
Prevent world creation if the world already exists
[dragonfireclient.git] / src / guiFormSpecMenu.cpp
index b2fee9c0dd9789a8d5730d0fec56fa7ab6944e2f..ed44e441b4c562e29761165d97b18a86e7413ba1 100644 (file)
@@ -215,10 +215,9 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
                        }
                        else{
                                invsize.Y = stof(f.next(";"));
-                               errorstream<<"WARNING: invsize is deprecated, use size"<<std::endl;
                                f.next("]");
                        }
-                       infostream<<"size ("<<invsize.X<<","<<invsize.Y<<")"<<std::endl;
+                       infostream<<"Form size ("<<invsize.X<<","<<invsize.Y<<")"<<std::endl;
 
                        padding = v2s32(screensize.Y/40, screensize.Y/40);
                        spacing = v2s32(screensize.Y/12, screensize.Y/13);
@@ -257,10 +256,13 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
                                        <<", pos=("<<pos.X<<","<<pos.Y<<")"
                                        <<", geom=("<<geom.X<<","<<geom.Y<<")"
                                        <<std::endl;
-                       f.next("]");
+                       std::string start_i_s = f.next("]");
+                       s32 start_i = 0;
+                       if(start_i_s != "")
+                               start_i = stoi(start_i_s);
                        if(bp_set != 2)
-                               errorstream<<"WARNING: invalid use of button without a size[] element"<<std::endl;
-                       m_inventorylists.push_back(ListDrawSpec(loc, listname, pos, geom));
+                               errorstream<<"WARNING: invalid use of list without a size[] element"<<std::endl;
+                       m_inventorylists.push_back(ListDrawSpec(loc, listname, pos, geom, start_i));
                }
                else if(type == "image")
                {
@@ -380,9 +382,9 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
                }
                else if(type == "label")
                {
-                       v2s32 pos;
-                       pos.X = stof(f.next(",")) * (float)spacing.X;
-                       pos.Y = stof(f.next(";")) * (float)spacing.Y;
+                       v2s32 pos = padding;
+                       pos.X += stof(f.next(",")) * (float)spacing.X;
+                       pos.Y += stof(f.next(";")) * (float)spacing.Y;
 
                        rect = core::rect<s32>(pos.X, pos.Y+((imgsize.Y/2)-15), pos.X+300, pos.Y+((imgsize.Y/2)+15));
                        
@@ -401,9 +403,9 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
                }
                else if(type == "button" || type == "button_exit")
                {
-                       v2s32 pos;
-                       pos.X = stof(f.next(",")) * (float)spacing.X;
-                       pos.Y = stof(f.next(";")) * (float)spacing.Y;
+                       v2s32 pos = padding;
+                       pos.X += stof(f.next(",")) * (float)spacing.X;
+                       pos.Y += stof(f.next(";")) * (float)spacing.Y;
                        v2s32 geom;
                        geom.X = (stof(f.next(",")) * (float)spacing.X)-(spacing.X-imgsize.X);
                        pos.Y += (stof(f.next(";")) * (float)imgsize.Y)/2;
@@ -429,9 +431,9 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
                }
                else if(type == "image_button" || type == "image_button_exit")
                {
-                       v2s32 pos;
-                       pos.X = stof(f.next(",")) * (float)spacing.X;
-                       pos.Y = stof(f.next(";")) * (float)spacing.Y;
+                       v2s32 pos = padding;
+                       pos.X += stof(f.next(",")) * (float)spacing.X;
+                       pos.Y += stof(f.next(";")) * (float)spacing.Y;
                        v2s32 geom;
                        geom.X = (stof(f.next(",")) * (float)spacing.X)-(spacing.X-imgsize.X);
                        geom.Y = (stof(f.next(";")) * (float)spacing.Y)-(spacing.Y-imgsize.Y);
@@ -531,13 +533,14 @@ GUIFormSpecMenu::ItemSpec GUIFormSpecMenu::getItemAtPos(v2s32 p) const
 
                for(s32 i=0; i<s.geom.X*s.geom.Y; i++)
                {
+                       s32 item_i = i + s.start_item_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.inventoryloc, s.listname, i);
+                               return ItemSpec(s.inventoryloc, s.listname, item_i);
                        }
                }
        }
@@ -576,13 +579,16 @@ void GUIFormSpecMenu::drawList(const ListDrawSpec &s, int phase)
        
        for(s32 i=0; i<s.geom.X*s.geom.Y; i++)
        {
+               u32 item_i = i + s.start_item_i;
+               if(item_i >= ilist->getSize())
+                       break;
                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;
                ItemStack item;
                if(ilist)
-                       item = ilist->getItem(i);
+                       item = ilist->getItem(item_i);
 
                bool selected = m_selected_item
                        && m_invmgr->getInventory(m_selected_item->inventoryloc) == inv
@@ -727,6 +733,54 @@ void GUIFormSpecMenu::drawMenu()
 
 void GUIFormSpecMenu::updateSelectedItem()
 {
+       // WARNING: BLACK MAGIC
+       // See if there is a stack suited for our current guess.
+       // If such stack does not exist, clear the guess.
+       if(m_selected_content_guess.name != "")
+       {
+               bool found = false;
+               for(u32 i=0; i<m_inventorylists.size() && !found; i++){
+                       const ListDrawSpec &s = m_inventorylists[i];
+                       Inventory *inv = m_invmgr->getInventory(s.inventoryloc);
+                       if(!inv)
+                               continue;
+                       InventoryList *list = inv->getList(s.listname);
+                       if(!list)
+                               continue;
+                       for(s32 i=0; i<s.geom.X*s.geom.Y && !found; i++){
+                               u32 item_i = i + s.start_item_i;
+                               if(item_i >= list->getSize())
+                                       continue;
+                               ItemStack stack = list->getItem(item_i);
+                               if(stack.name == m_selected_content_guess.name &&
+                                               stack.count == m_selected_content_guess.count){
+                                       found = true;
+                                       if(m_selected_item){
+                                               // If guessed stack is already selected, all is fine
+                                               if(m_selected_item->inventoryloc == s.inventoryloc &&
+                                                               m_selected_item->listname == s.listname &&
+                                                               m_selected_item->i == (s32)item_i &&
+                                                               m_selected_amount == stack.count){
+                                                       break;
+                                               }
+                                               delete m_selected_item;
+                                               m_selected_item = NULL;
+                                       }
+                                       infostream<<"Client: Changing selected content guess to "
+                                                       <<s.inventoryloc.dump()<<" "<<s.listname
+                                                       <<" "<<item_i<<std::endl;
+                                       m_selected_item = new ItemSpec(s.inventoryloc, s.listname, item_i);
+                                       m_selected_amount = stack.count;
+                                       break;
+                               }
+                       }
+               }
+               if(!found){
+                       infostream<<"Client: Discarding selected content guess: "
+                                       <<m_selected_content_guess.getItemString()<<std::endl;
+                       m_selected_content_guess.name = "";
+               }
+       }
        // If the selected stack has become empty for some reason, deselect it.
        // If the selected stack has become smaller, adjust m_selected_amount.
        if(m_selected_item)
@@ -884,14 +938,14 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
 
                        InventoryList *list = inv_s->getList(s.listname);
                        if(list == NULL){
-                               errorstream<<"InventoryMenu: The selected inventory list \""
+                               verbosestream<<"InventoryMenu: The selected inventory list \""
                                                <<s.listname<<"\" does not exist"<<std::endl;
                                s.i = -1;  // make it invalid again
                                break;
                        }
 
                        if((u32)s.i >= list->getSize()){
-                               errorstream<<"InventoryMenu: The selected inventory list \""
+                               infostream<<"InventoryMenu: The selected inventory list \""
                                                <<s.listname<<"\" is too small (i="<<s.i<<", size="
                                                <<list->getSize()<<")"<<std::endl;
                                s.i = -1;  // make it invalid again
@@ -1048,21 +1102,28 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
                        // Check how many items can be moved
                        move_amount = stack_from.count = MYMIN(move_amount, stack_from.count);
                        ItemStack leftover = stack_to.addItem(stack_from, m_gamedef->idef());
-                       if(leftover.count == stack_from.count)
+                       // If source stack cannot be added to destination stack at all,
+                       // they are swapped
+                       if(leftover.count == stack_from.count && leftover.name == stack_from.name)
                        {
-                               // Swap the stacks
-                               m_selected_amount -= stack_to.count;
+                               m_selected_amount = stack_to.count;
+                               // In case the server doesn't directly swap them but instead
+                               // moves stack_to somewhere else, set this
+                               m_selected_content_guess = stack_to;
+                               m_selected_content_guess_inventory = s.inventoryloc;
                        }
+                       // Source stack goes fully into destination stack
                        else if(leftover.empty())
                        {
-                               // Item fits
                                m_selected_amount -= move_amount;
+                               m_selected_content_guess = ItemStack(); // Clear
                        }
+                       // Source stack goes partly into destination stack
                        else
                        {
-                               // Item only fits partially
                                move_amount -= leftover.count;
                                m_selected_amount -= move_amount;
+                               m_selected_content_guess = ItemStack(); // Clear
                        }
 
                        infostream<<"Handing IACTION_MOVE to manager"<<std::endl;
@@ -1078,6 +1139,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
                }
                else if(drop_amount > 0)
                {
+                       m_selected_content_guess = ItemStack(); // Clear
+
                        // Send IACTION_DROP
 
                        assert(m_selected_item && m_selected_item->isValid());
@@ -1101,6 +1164,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
                }
                else if(craft_amount > 0)
                {
+                       m_selected_content_guess = ItemStack(); // Clear
+
                        // Send IACTION_CRAFT
 
                        assert(s.isValid());
@@ -1120,6 +1185,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
                        m_selected_item = NULL;
                        m_selected_amount = 0;
                        m_selected_dragging = false;
+                       m_selected_content_guess = ItemStack();
                }
        }
        if(event.EventType==EET_GUI_EVENT)
@@ -1160,6 +1226,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
                                                return true;
                                        }else{
                                                s.send = false;
+                                               // Restore focus to the full form
+                                               Environment->setFocus(this);
                                                return true;
                                        }
                                }