summaryrefslogblamecommitdiff
path: root/src/gui/popupmenu.cpp
blob: d63fe2f32fb491206e7c35f63322eaafb0ba33f1 (plain) (tree)
1
2
3
4
5
6
7
8
  
                   
                                                            
                                                
  
                                         
  
                                                                        



                                                                        
                                                                   




                                                                     
                                                                         

   

                          
                               
                  
                      


                        
                
                       
                            
 
                           
                                
                                
                                 


                                   
                             
                                 
                    

                             
 

                               
 
                          
                              

                  
 
                             

                       
                       
                

                        
 
                                 


                                                          
                                      
                     

 
                                                     
 
                              
                             
 
                                               
 
                             
     
                                 
             
                                              
                                                             
                                                                                
                                                                            
                                                   


                                                                            



                                                                            


                                              

                                                           
                                                 


                                                                            

                                                





                                                                            


                                                     
                                                                        
                                                                           



                                                                               


                                                 
                                                                        
                                                                           
                                                                            


                              
                                                      
                                                                 

                                                                            
                                                

                                                                  
                                                                 

                                                                            
                 
 
                                         

                                                  

                                                                      
                 


                  
                              

                                                                          


                                                                            

                  
                                  

                                           


                                                                            
 
                                         

                                                                      

                  
 

                                                    
                   
     
                                                                         
 
                                                                  
                                  
                                                                 
 




                                                             
                           
                                         
                             

                                                                         
                                      


                                                                             
 
                                                                  
                                  
                                                                 

                    

 
                                                   
 
                                                           
 
                     
                                                    
     
                        


                   

                                                     
     
                                               
                                            
     
                    
                                       
     
                                          
     



                                                                     

                                                     
     
                                                                                

     

                                                     
     
                                                                                

     

                                                     
     
                                                                                    

     

                                                     
     
                                                                               
     
                   

                                                     
     
                                           
     
 
                                
                                              
     
                                         

     




                            
                                                                        
     
                      
                                  

                                    



                                                                                
                
             
                                               
             

            
         
                                         
         
     
                            
     



                                                                     

     

                             
                                                                 
                                                     
     
 

                            
                                                                
                                                     
     
 

                             
                                                                




                                                     

                                                                            

     

                                                     
     
                                              



                                     
                                                   
                                       

     

                                    

                                                        
     
                                                     
     
 
                      
                              
     
                                                                             



                      
                 

                         
 
 
                                                                   
                                                         

                 
                 
                     
                             
 
                    
     
                                              



                                                                       
                                            

                                   
                                                                               
                
                                                                           
         

                                                                             
 






                                                                            
 
                                                       
         
                                                                       
         




                                                            
                                                                         
     
                                                                    
                                  
                                                                 
 




                                       
                                                                              



                                                      
                      


                       
/*
 *  The Mana Client
 *  Copyright (C) 2004-2009  The Mana World Development Team
 *  Copyright (C) 2009-2012  The Mana Developers
 *
 *  This file is part of The Mana Client.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "gui/popupmenu.h"

#include "actorspritemanager.h"
#include "being.h"
#include "flooritem.h"
#include "graphics.h"
#include "item.h"
#include "localplayer.h"
#include "log.h"
#include "playerinfo.h"
#include "playerrelations.h"

#include "gui/chatwindow.h"
#include "gui/equipmentwindow.h"
#include "gui/inventorywindow.h"
#include "gui/itemamountwindow.h"

#include "gui/widgets/browserbox.h"

#include "net/adminhandler.h"
#include "net/inventoryhandler.h"
#include "net/net.h"
#include "net/partyhandler.h"
#include "net/tradehandler.h"

#include "resources/itemdb.h"
#include "resources/iteminfo.h"

#include "utils/gettext.h"
#include "utils/stringutils.h"

#include <cassert>

std::string tradePartnerName;

PopupMenu::PopupMenu():
    Popup("PopupMenu"),
    mBeingId(0),
    mFloorItem(nullptr),
    mItem(nullptr)
{
    mBrowserBox = new BrowserBox;
    mBrowserBox->setPosition(4, 4);
    mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND);
    mBrowserBox->setOpaque(false);
    mBrowserBox->setLinkHandler(this);
    add(mBrowserBox);
}

void PopupMenu::showPopup(int x, int y, Being *being)
{
    mBeingId = being->getId();
    mBrowserBox->clearRows();

    const std::string &name = being->getName();

    switch (being->getType())
    {
        case ActorSprite::PLAYER:
            {
                // Players can be traded with.
                mBrowserBox->addRow(strprintf("@@trade|%s@@",
                                                strprintf(_("Trade with %s..."),
                                                    name.c_str()).c_str()));
                // TRANSLATORS: Attacking a player.
                mBrowserBox->addRow(strprintf("@@attack|%s@@",
                                                strprintf(_("Attack %s"),
                                                    name.c_str()).c_str()));
                // TRANSLATORS: Whispering a player.
                mBrowserBox->addRow(strprintf("@@whisper|%s@@",
                                                strprintf(_("Whisper %s"),
                                                    name.c_str()).c_str()));

                mBrowserBox->addRow("##3---");

                switch (player_relations.getRelation(name))
                {
                    case PlayerRelation::NEUTRAL:
                        mBrowserBox->addRow(strprintf("@@friend|%s@@",
                                                strprintf(_("Befriend %s"),
                                                    name.c_str()).c_str()));

                    case PlayerRelation::FRIEND:
                        mBrowserBox->addRow(strprintf("@@disregard|%s@@",
                                                strprintf(_("Disregard %s"),
                                                    name.c_str()).c_str()));
                        mBrowserBox->addRow(strprintf("@@ignore|%s@@",
                                                strprintf(_("Ignore %s"),
                                                    name.c_str()).c_str()));
                        break;

                    case PlayerRelation::DISREGARDED:
                        mBrowserBox->addRow(strprintf("@@unignore|%s@@",
                                                strprintf(_("Unignore %s"),
                                                    name.c_str()).c_str()));
                        mBrowserBox->addRow(strprintf("@@ignore|%s@@",
                                           strprintf(_("Completely ignore %s"),
                                                    name.c_str()).c_str()));
                        break;

                    case PlayerRelation::IGNORED:
                        mBrowserBox->addRow(strprintf("@@unignore|%s@@",
                                                strprintf(_("Unignore %s"),
                                                    name.c_str()).c_str()));
                        break;
                }

                if (local_player->getNumberOfGuilds())
                    mBrowserBox->addRow(strprintf("@@guild|%s@@",
                                strprintf(_("Invite %s to join your guild"),
                                                    name.c_str()).c_str()));
                if (local_player->isInParty() ||
                    Net::getNetworkType() == ServerInfo::MANASERV)
                {
                    mBrowserBox->addRow(strprintf("@@party|%s@@",
                                strprintf(_("Invite %s to join your party"),
                                                    name.c_str()).c_str()));
                }

                if (local_player->isGM())
                {
                    mBrowserBox->addRow("##3---");
                    mBrowserBox->addRow(strprintf("@@admin-kick|%s@@",
                                                  _("Kick player")));
                }
            }
            break;

        case ActorSprite::NPC:
            // NPCs can be talked to (single option, candidate for removal
            // unless more options would be added)
            mBrowserBox->addRow(strprintf("@@talk|%s@@",
                                              strprintf(_("Talk to %s"),
                                                    name.c_str()).c_str()));
            break;

        case ActorSprite::MONSTER:
            {
                // Monsters can be attacked
                mBrowserBox->addRow(strprintf("@@attack|%s@@",
                                              strprintf(_("Attack %s"),
                                                    name.c_str()).c_str()));

                if (local_player->isGM())
                    mBrowserBox->addRow(strprintf("@@admin-kick|%s@@",
                                                  _("Kick monster")));
            }
            break;

        default:
            /* Other beings aren't interesting... */
            return;
    }
    mBrowserBox->addRow(strprintf("@@name|%s@@", _("Add name to chat")));

    //mBrowserBox->addRow(strprintf("@@look|%s@@", _("Look To")));
    mBrowserBox->addRow("##3---");
    mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));

    showPopup(x, y);
}

void PopupMenu::showPopup(int x, int y, FloorItem *floorItem)
{
    mFloorItem = floorItem;
    ItemInfo info = floorItem->getInfo();
    mBrowserBox->clearRows();

    // Floor item can be picked up (single option, candidate for removal)
    std::string name = info.getName();
    mBrowserBox->addRow(strprintf("@@pickup|%s@@", strprintf(_("Pick up %s"),
                                                    name.c_str()).c_str()));
    mBrowserBox->addRow(strprintf("@@chat|%s@@", _("Add to chat")));

    //mBrowserBox->addRow(strprintf("@@look|%s@@", _("Look To")));
    mBrowserBox->addRow("##3---");
    mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));

    showPopup(x, y);
}

void PopupMenu::handleLink(const std::string &link)
{
    Being *being = actorSpriteManager->findBeing(mBeingId);

    // Talk To action
    if (link == "talk" && being && being->canTalk())
    {
        being->talkTo();
    }

    // Trade action
    else if (link == "trade" && being &&
             being->getType() == ActorSprite::PLAYER)
    {
        Net::getTradeHandler()->request(being);
        tradePartnerName = being->getName();
    }
    // Attack action
    else if (link == "attack" && being)
    {
        local_player->attack(being, true);
    }
    else if (link == "whisper" && being)
    {
        chatWindow->addInputText("/w \"" + being->getName() + "\" ");
    }
    else if (link == "unignore" && being &&
             being->getType() == ActorSprite::PLAYER)
    {
        player_relations.setRelation(being->getName(), PlayerRelation::NEUTRAL);
    }

    else if (link == "ignore" && being &&
             being->getType() == ActorSprite::PLAYER)
    {
        player_relations.setRelation(being->getName(), PlayerRelation::IGNORED);
    }

    else if (link == "disregard" && being &&
             being->getType() == ActorSprite::PLAYER)
    {
        player_relations.setRelation(being->getName(), PlayerRelation::DISREGARDED);
    }

    else if (link == "friend" && being &&
             being->getType() == ActorSprite::PLAYER)
    {
        player_relations.setRelation(being->getName(), PlayerRelation::FRIEND);
    }
    // Guild action
    else if (link == "guild" && being &&
             being->getType() == ActorSprite::PLAYER)
    {
        local_player->inviteToGuild(being);
    }

    // Pick Up Floor Item action
    else if ((link == "pickup") && mFloorItem)
    {
        local_player->pickUp(mFloorItem);
    }

    // Look To action
    else if (link == "look")
    {
    }

    else if (link == "activate" || link == "equip" || link == "unequip")
    {
        assert(mItem);
        if (mItem->isEquippable())
        {
            if (mItem->isEquipped())
            {
                PlayerInfo::getEquipment()->triggerUnequip(
                                                equipmentWindow->getSelected());
            }
            else
            {
                mItem->doEvent(Event::DoEquip);
            }
        }
        else
        {
            mItem->doEvent(Event::DoUse);
        }
    }
    else if (link == "chat")
    {
        if (mItem)
            chatWindow->addItemText(mItem->getInfo().getName());
        else if (mFloorItem)
            chatWindow->addItemText(mFloorItem->getInfo().getName());
    }

    else if (link == "split")
    {
        ItemAmountWindow::showWindow(ItemAmountWindow::ItemSplit,
                             inventoryWindow, mItem);
    }

    else if (link == "drop")
    {
        ItemAmountWindow::showWindow(ItemAmountWindow::ItemDrop,
                             inventoryWindow, mItem);
    }

    else if (link == "store")
    {
        ItemAmountWindow::showWindow(ItemAmountWindow::StoreAdd,
                             inventoryWindow, mItem);
    }

    else if (link == "retrieve")
    {
        ItemAmountWindow::showWindow(ItemAmountWindow::StoreRemove, mWindow,
                                     mItem);
    }

    else if (link == "party" && being &&
             being->getType() == ActorSprite::PLAYER)
    {
        Net::getPartyHandler()->invite(being);
    }

    else if (link == "name" && being)
    {
        const std::string &name = being->getName();
        chatWindow->addInputText(name);
    }

    else if (link == "admin-kick" &&
             being &&
             (being->getType() == ActorSprite::PLAYER ||
              being->getType() == ActorSprite::MONSTER))
    {
        Net::getAdminHandler()->kick(being->getId());
    }

    // Unknown actions
    else if (link != "cancel")
    {
        logger->log("PopupMenu: Warning, unknown action '%s'", link.c_str());
    }

    setVisible(false);

    mBeingId = 0;
    mFloorItem = nullptr;
    mItem = nullptr;
}

void PopupMenu::showPopup(Window *parent, int x, int y, Item *item,
                          bool isInventory, bool canDrop)
{
    assert(item);
    mItem = item;
    mWindow = parent;
    mBrowserBox->clearRows();

    if (isInventory)
    {
        if (PlayerInfo::getStorageCount() > 0)
        {
            mBrowserBox->addRow(strprintf("@@store|%s@@", _("Store")));
        }

        if (item->getInfo().getEquippable())
        {
            if (item->isEquipped())
                mBrowserBox->addRow(strprintf("@@unequip|%s@@", _("Unequip")));
            else
                mBrowserBox->addRow(strprintf("@@equip|%s@@", _("Equip")));
        }
        if (item->getInfo().getActivatable())
            mBrowserBox->addRow(strprintf("@@activate|%s@@", _("Activate")));

        if (canDrop)
        {
            if (item->getQuantity() > 1)
                mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop...")));
            else
                mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop")));
        }

        if (Net::getInventoryHandler()->canSplit(item))
        {
            mBrowserBox->addRow(strprintf("@@split|%s@@", _("Split")));
        }
    }
    // Assume in storage for now
    // TODO: make this whole system more flexible, if needed
    else
    {
        mBrowserBox->addRow(strprintf("@@retrieve|%s@@", _("Retrieve")));
    }
    mBrowserBox->addRow(strprintf("@@chat|%s@@", _("Add to chat")));
    mBrowserBox->addRow("##3---");
    mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));

    showPopup(x, y);
}

void PopupMenu::showPopup(int x, int y)
{
    setContentSize(mBrowserBox->getWidth() + 8, mBrowserBox->getHeight() + 8);
    if (graphics->getWidth() < (x + getWidth() + 5))
        x = graphics->getWidth() - getWidth();
    if (graphics->getHeight() < (y + getHeight() + 5))
        y = graphics->getHeight() - getHeight();
    setPosition(x, y);
    setVisible(true);
    requestMoveToTop();
}