summaryrefslogblamecommitdiff
path: root/src/gui/skill.cpp
blob: 61bb9ce98123861eabda9c632a6cec94b1ac711d (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11

                  
                                                       


                                        
                                                                        



                                                                        
                                                                   




                                                                     
                                                               
                                                                             
   
 


                                    
                    
                       
                  
                  
                            
 

                           
                           
                   

                          

                               
                         
 
                                                 
 

                



                     




                                        

                                
                            




                                                  
                              





                         



                             
 
                                         
     



                       

     
                              



                  
                         



                                                 

                                            
                                                   
                                  

                          





                                                              
                                                                                  
                                                         

                                             
                                                       

                                             
                                                       






                                  


                         

  
 
                           
                       
 

                                               


                                       
                                     

                                      
 
                            
                         
                                                                    
 


                                                
                                                         
                                                                       

                                                      
                                  
 
                                                                            




                                                  
 

                                             
 
                                       
                      



                           
                  

 
                                                       
 
                               

                          
                                                     
                               
                                                                   
     
                                                                       
     









                                                                         
     
                                      
                          

 
                          
 

                                                                  
 
                                                 
 

                           









                                                                     

        
                                      

                          
                                                



                                      
                             

 

                                  


                                                        
                        



                 
                                                   
 
                           
                 

                  
                              

 
                                                   
 



                                                        

                                    


         


                             
                           
                       
 
 
                           







                                                             
                                                                  













                                                                                  

                           







                                                           
/*
 *  The Mana World
 *  Copyright (C) 2004  The Mana World Development Team
 *
 *  This file is part of The Mana World.
 *
 *  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, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <guichan/widgets/label.hpp>

#include "button.h"
#include "listbox.h"
#include "scrollarea.h"
#include "skill.h"
#include "table.h"
#include "windowcontainer.h"

#include "widgets/layout.h"

#include "../localplayer.h"
#include "../log.h"

#include "../utils/dtor.h"
#include "../utils/gettext.h"
#include "../utils/strprintf.h"
#include "../utils/xml.h"

static const char *SKILLS_FILE = _("skills.xml");

struct SkillInfo
{
    std::string name;
    bool modifiable;
};

static const SkillInfo fakeSkillInfo = {
    _("Mystery Skill"),
    false
};

std::vector<SkillInfo> skill_db;

static void initSkillinfo();

class SkillGuiTableModel : public StaticTableModel
{
public:
    SkillGuiTableModel(SkillDialog *dialog) :
        StaticTableModel(0, 3)
    {
        mEntriesNr = 0;
        mDialog = dialog;
        update();
    }

    virtual int getRows(void)
    {
        return mEntriesNr;
    }

    virtual int getColumnWidth(int index)
    {
        if (index == 0)
            return 160;

        return 35;
    }

    virtual int getRowHeight()
    {
        return 12;
    }

    virtual void update()
    {
        mEntriesNr = mDialog->getSkills().size();
        resize();

        for (int i = 0; i < mEntriesNr; i++)
        {
            SKILL *skill = mDialog->getSkills()[i];
            SkillInfo const *info;
            char tmp[128];

            if (skill->id >= 0
                && (unsigned int) skill->id < skill_db.size())
                info = &skill_db[skill->id];
            else
                info = &fakeSkillInfo;

            sprintf(tmp, "%c%s", info->modifiable? ' ' : '*', info->name.c_str());
            gcn::Label *name_label = new gcn::Label(tmp);

            sprintf(tmp, "Lv:%i", skill->lv);
            gcn::Label *lv_label = new gcn::Label(tmp);

            sprintf(tmp, "Sp:%i", skill->sp);
            gcn::Label *sp_label = new gcn::Label(tmp);

            set(i, 0, name_label);
            set(i, 1, lv_label);
            set(i, 2, sp_label);
        }
    }

private:
    SkillDialog *mDialog;
    int mEntriesNr;
};


SkillDialog::SkillDialog():
    Window(_("Skills"))
{
    initSkillinfo();
    mTableModel = new SkillGuiTableModel(this);
    mTable = new GuiTable(mTableModel);
    mTable->setOpaque(false);
    mTable->setLinewiseSelection(true);
    mTable->setWrappingEnabled(true);
    mTable->setActionEventId("skill");
    mTable->addActionListener(this);

    setWindowName("Skills");
    setCloseButton(true);
    setDefaultSize(windowContainer->getWidth() - 260, 25, 255, 260);

    setMinHeight(50 + mTableModel->getHeight());
    setMinWidth(200);

    ScrollArea *skillScrollArea = new ScrollArea(mTable);
    mPointsLabel = new gcn::Label(strprintf(_("Skill points: %d"), 0));
    mIncButton = new Button(_("Up"), _("inc"), this);
    mUseButton = new Button(_("Use"), _("use"), this);
    mUseButton->setEnabled(false);

    skillScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);

    place(0, 0, skillScrollArea, 5).setPadding(3);
    place(0, 1, mPointsLabel, 2);
    place(3, 2, mIncButton);
    place(4, 2, mUseButton);

    Layout &layout = getLayout();
    layout.setRowHeight(0, Layout::AUTO_SET);

    setLocationRelativeTo(getParent());
    loadWindowState();
}

SkillDialog::~SkillDialog()
{
    delete mTable;
}

void SkillDialog::action(const gcn::ActionEvent &event)
{
    if (event.getId() == "inc")
    {
        // Increment skill
        int selectedSkill = mTable->getSelectedRow();
        if (selectedSkill >= 0)
            player_node->raiseSkill(mSkillList[selectedSkill]->id);
    }
    else if (event.getId() == "skill" && mTable->getSelectedRow() > -1)
    {
        SKILL *skill = mSkillList[mTable->getSelectedRow()];
        SkillInfo const *info;

        if (skill->id >= 0 && (unsigned int) skill->id < skill_db.size())
            info = &skill_db[skill->id];
        else
            info = &fakeSkillInfo;

        mIncButton->setEnabled(player_node->mSkillPoint > 0 &&
                               info->modifiable);
    }
    else if (event.getId() == "close")
        setVisible(false);
}

void SkillDialog::update()
{
    mPointsLabel->setCaption(strprintf(_("Skill points: %d"),
                                       player_node->mSkillPoint));

    int selectedSkill = mTable->getSelectedRow();

    if (selectedSkill >= 0)
    {
        int skillId = mSkillList[selectedSkill]->id;
        bool modifiable;

        if (skillId >= 0 && (unsigned int) skillId < skill_db.size())
            modifiable = skill_db[skillId].modifiable;
        else
            modifiable = false;

        mIncButton->setEnabled(modifiable
                               && player_node->mSkillPoint > 0);
    }
    else
        mIncButton->setEnabled(false);

    mTableModel->update();
    setMinHeight(50 + mTableModel->getHeight());
}

int SkillDialog::getNumberOfElements()
{
    return mSkillList.size();
}

bool SkillDialog::hasSkill(int id)
{
    for (unsigned int i = 0; i < mSkillList.size(); i++)
    {
        if (mSkillList[i]->id == id)
            return true;
    }
    return false;
}

void SkillDialog::addSkill(int id, int lvl, int mp)
{
    SKILL *tmp = new SKILL;
    tmp->id = id;
    tmp->lv = lvl;
    tmp->sp = mp;
    mSkillList.push_back(tmp);
}

void SkillDialog::setSkill(int id, int lvl, int mp)
{
    for (unsigned int i = 0; i < mSkillList.size(); i++)
    {
        if (mSkillList[i]->id == id)
        {
            mSkillList[i]->lv = lvl;
            mSkillList[i]->sp = mp;
        }
    }
}

void SkillDialog::cleanList()
{
    delete_all(mSkillList);
    mSkillList.clear();
}

static void initSkillinfo()
{
    SkillInfo emptySkillInfo = { "", false };

    XML::Document doc(SKILLS_FILE);
    xmlNodePtr root = doc.rootNode();

    if (!root || !xmlStrEqual(root->name, BAD_CAST "skills"))
    {
        logger->log("Error loading skills file: %s", SKILLS_FILE);
        skill_db.resize(2, emptySkillInfo);
        skill_db[1].name = "Basic";
        skill_db[1].modifiable = true;
        return;
    }

    for_each_xml_child_node(node, root)
    {
        if (xmlStrEqual(node->name, BAD_CAST "skill"))
        {
            int index = atoi(XML::getProperty(node, "id", "-1").c_str());
            std::string name = XML::getProperty(node, "name", "");
            bool modifiable = !atoi(XML::getProperty(node, "fixed", "0").c_str());

            if (index >= 0)
            {
                skill_db.resize(index + 1, emptySkillInfo);
                skill_db[index].name = name;
                skill_db[index].modifiable = modifiable;
            }
        }
    }
}