From 7a7018c517948c2cc567d28d221c5cd8a91f2c12 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Fri, 7 Aug 2009 14:49:27 -0600 Subject: Clear tab data from SkillDialog --- src/gui/skilldialog.cpp | 16 ++++++++++++++-- src/gui/skilldialog.h | 1 - 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index a27a2775..2f970184 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -47,7 +47,6 @@ #include "utils/xml.h" #include -#include class SkillEntry; @@ -104,7 +103,8 @@ SkillDialog::SkillDialog(): SkillDialog::~SkillDialog() { - //delete_all(mTabs); + // Clear gui + loadSkills(""); } void SkillDialog::action(const gcn::ActionEvent &event) @@ -182,9 +182,21 @@ void SkillDialog::update() void SkillDialog::loadSkills(const std::string &file) { // TODO: mTabs->clear(); + while (mTabs->getSelectedTabIndex() != -1) + { + mTabs->removeTabWithIndex(mTabs->getSelectedTabIndex()); + } + + for (SkillMap::iterator it = mSkills.begin(); it != mSkills.end(); it++) + { + delete (*it).second->display; + } delete_all(mSkills); mSkills.clear(); + if (file.length() == 0) + return; + XML::Document doc(file); xmlNodePtr root = doc.rootNode(); diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h index ce8f091a..6ad28be4 100644 --- a/src/gui/skilldialog.h +++ b/src/gui/skilldialog.h @@ -28,7 +28,6 @@ #include -#include #include class Label; -- cgit v1.2.3-70-g09d2 From 4f59c7bb5ed023c9c9eed0df3b41384337c1eeee Mon Sep 17 00:00:00 2001 From: Bertram Date: Mon, 10 Aug 2009 23:11:42 +0200 Subject: Included libintl.h before gettext.h in order to make ngettext function work. --- src/localplayer.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 57dc8981..9e4d6ab5 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -65,6 +65,7 @@ #include "resources/iteminfo.h" #include "resources/resourcemanager.h" +#include #include "utils/gettext.h" #include "utils/stringutils.h" -- cgit v1.2.3-70-g09d2 From a940bc4648882350071e1a3c3ef7230f0c3021c2 Mon Sep 17 00:00:00 2001 From: Bertram Date: Tue, 11 Aug 2009 00:39:13 +0200 Subject: Added the possibility to get random login wallpapers, when several fit the resolution. This resolve the Mantis #809. The images filenames must end using the mask "_x.png" For instance: myskylogin_800x600.png. Of course, the images must be in the data/graphics/images folder. --- src/resources/wallpaper.cpp | 91 ++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/resources/wallpaper.cpp b/src/resources/wallpaper.cpp index bc9728d0..f0e834b1 100644 --- a/src/resources/wallpaper.cpp +++ b/src/resources/wallpaper.cpp @@ -32,18 +32,19 @@ #include #define WALLPAPER_FOLDER "graphics/images/" -#define WALLPAPER_BASE "login_wallpaper" +#define WALLPAPER_BASE "login_wallpaper.png" -struct WallpaperSize +struct WallpaperData { + std::string filename; int width; int height; }; -static std::vector wallpaperSizes; +static std::vector wallpaperData; static bool haveBackup; // Is the backup (no size given) version available? -bool wallpaperCompare(WallpaperSize a, WallpaperSize b) +bool wallpaperCompare(WallpaperData a, WallpaperData b) { int aa = a.width * a.height; int ab = b.width * b.height; @@ -53,60 +54,82 @@ bool wallpaperCompare(WallpaperSize a, WallpaperSize b) void Wallpaper::loadWallpapers() { - wallpaperSizes.clear(); - - size_t baseLen = strlen(WALLPAPER_BASE); - haveBackup = false; + wallpaperData.clear(); char **imgs = PHYSFS_enumerateFiles(WALLPAPER_FOLDER); for (char **i = imgs; *i != NULL; i++) { - if (strncmp(*i, WALLPAPER_BASE, baseLen) == 0) + int width; + int height; + + // If the backup file is found, we tell it. + if (strncmp (*i, WALLPAPER_BASE, strlen(*i)) == 0) + haveBackup = true; + + // If the image format is terminated by: "_x.png" + // It is taken as a potential wallpaper. + + // First, get the base filename of the image: + std::string filename = *i; + int separator = filename.rfind("_"); + filename = filename.substr(0, separator); + + // Then, append the width and height search mask. + filename.append("_%dx%d.png"); + + if (sscanf(*i, filename.c_str(), &width, &height) == 2) { - int width; - int height; - - if (strlen(*i) == baseLen + 4) - { - if (haveBackup) - logger->log("Duplicate default wallpaper!"); - else - haveBackup = true; - } - else if (sscanf(*i, WALLPAPER_BASE "_%dx%d.png", - &width, &height) == 2) - { - WallpaperSize wp; - wp.width = width; - wp.height = height; - wallpaperSizes.push_back(wp); - } + WallpaperData wp; + wp.filename = WALLPAPER_FOLDER; + wp.filename.append(*i); + wp.width = width; + wp.height = height; + wallpaperData.push_back(wp); } } PHYSFS_freeList(imgs); - std::sort(wallpaperSizes.begin(), wallpaperSizes.end(), wallpaperCompare); + std::sort(wallpaperData.begin(), wallpaperData.end(), wallpaperCompare); } std::string Wallpaper::getWallpaper(int width, int height) { - std::vector::iterator iter; - WallpaperSize wp; + std::vector::iterator iter; + WallpaperData wp; - for (iter = wallpaperSizes.begin(); iter != wallpaperSizes.end(); iter++) + // Wallpaper filename container + std::vector wallPaperVector; + + for (iter = wallpaperData.begin(); iter != wallpaperData.end(); iter++) { wp = *iter; if (wp.width <= width && wp.height <= height) + wallPaperVector.push_back(wp.filename); + } + + + if (!wallPaperVector.empty()) + { + // If we've got more than one occurence of a valid wallpaper... + if (wallPaperVector.size() > 0) { - return std::string(strprintf(WALLPAPER_FOLDER WALLPAPER_BASE - "_%dx%d.png", wp.width, wp.height)); + // Return randomly a wallpaper between vector[0] and + // vector[vector.size() - 1] + srand((unsigned)time(0)); + return wallPaperVector + [int(wallPaperVector.size() * rand() / (RAND_MAX + 1.0))]; } + else // If there at least one, we return it + return wallPaperVector[0]; } + // Return the backup file if everything else failed... if (haveBackup) - return std::string(WALLPAPER_FOLDER WALLPAPER_BASE ".png"); + return std::string(WALLPAPER_FOLDER WALLPAPER_BASE); + // Return an empty string if everything else failed return std::string(); + } -- cgit v1.2.3-70-g09d2 From 0ebdce30ee61d7b038e81bc64ae7d1e27d98a144 Mon Sep 17 00:00:00 2001 From: Bertram Date: Tue, 11 Aug 2009 00:56:14 +0200 Subject: Bugfixed the TMWserv client version. --- src/net/tmwserv/chathandler.cpp | 2 +- src/net/tmwserv/partyhandler.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/net/tmwserv/chathandler.cpp b/src/net/tmwserv/chathandler.cpp index ad3ae49b..c95f6ac5 100644 --- a/src/net/tmwserv/chathandler.cpp +++ b/src/net/tmwserv/chathandler.cpp @@ -298,7 +298,7 @@ void ChatHandler::handleChannelEvent(MessageIn &msg) std::string user1 = line.substr(0, first); std::string user2 = line.substr(first+1, line.length()); channel->getTab()->chatLog(strprintf(_("%s has kicked %s."), - user1, user2), BY_CHANNEL); + user1.c_str(), user2.c_str()), BY_CHANNEL); } break; default: diff --git a/src/net/tmwserv/partyhandler.cpp b/src/net/tmwserv/partyhandler.cpp index 2af0e4cb..220d20c0 100644 --- a/src/net/tmwserv/partyhandler.cpp +++ b/src/net/tmwserv/partyhandler.cpp @@ -100,7 +100,7 @@ void PartyHandler::handleMessage(MessageIn &msg) int id = msg.readInt16(); // being id std::string name = msg.readString(); - localChatTab->chatLog(strprintf(_("%s joined the party.", + localChatTab->chatLog(strprintf(_("%s joined the party."), name.c_str())); if (!player_node->isInParty()) -- cgit v1.2.3-70-g09d2 From 9af6e761373f25b56e815f1f75b44473474cf280 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Mon, 10 Aug 2009 20:28:23 -0600 Subject: Fix TabbedArea and ScrollArea to resize contents Also remove that code from SkillDialog. I tried to do the same with ChatWindow, but it kept segfaulting. Will try again later. --- src/gui/skilldialog.cpp | 22 ---------------------- src/gui/skilldialog.h | 8 -------- src/gui/widgets/scrollarea.cpp | 5 +++++ src/gui/widgets/scrollarea.h | 5 ++++- src/gui/widgets/tabbedarea.cpp | 11 +++++++++++ src/gui/widgets/tabbedarea.h | 5 ++++- 6 files changed, 24 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index a0bfaf53..01b6e5ae 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -122,25 +122,6 @@ void SkillDialog::action(const gcn::ActionEvent &event) } } -void SkillDialog::adjustTabSize() -{ - gcn::Widget *content = mTabs->getCurrentWidget(); - if (content) { - int width = mTabs->getWidth() - 2 * content->getFrameSize() - 2 * mTabs->getFrameSize(); - int height = mTabs->getContainerHeight() - 2 * content->getFrameSize(); - content->setSize(width, height); - content->setVisible(true); - content->logic(); - } -} - -void SkillDialog::widgetResized(const gcn::Event &event) -{ - Window::widgetResized(event); - - adjustTabSize(); -} - void SkillDialog::logic() { Window::logic(); @@ -148,7 +129,6 @@ void SkillDialog::logic() Tab *tab = dynamic_cast(mTabs->getSelectedTab()); if (tab != mCurrentTab) { mCurrentTab = tab; - adjustTabSize(); } } @@ -248,8 +228,6 @@ void SkillDialog::loadSkills(const std::string &file) } } } - - adjustTabSize(); update(); } diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h index 6ad28be4..8fa7443d 100644 --- a/src/gui/skilldialog.h +++ b/src/gui/skilldialog.h @@ -54,12 +54,6 @@ class SkillDialog : public Window, public gcn::ActionListener */ void action(const gcn::ActionEvent &event); - /** - * Called when the widget changes size. Used for adapting the size of - * the tabbed area. - */ - void widgetResized(const gcn::Event &event); - void logic(); /** @@ -77,8 +71,6 @@ class SkillDialog : public Window, public gcn::ActionListener void setModifiable(int id, bool modifiable); private: - void adjustTabSize(); - typedef std::map SkillMap; SkillMap mSkills; Tab *mCurrentTab; diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp index 52322b05..6cf27bb6 100644 --- a/src/gui/widgets/scrollarea.cpp +++ b/src/gui/widgets/scrollarea.cpp @@ -42,6 +42,7 @@ ScrollArea::ScrollArea(): mY(0), mOpaque(true) { + addWidgetListener(this); init(); } @@ -346,3 +347,7 @@ void ScrollArea::mouseExited(gcn::MouseEvent& event) mHasMouse = false; } +void ScrollArea::widgetResized(const gcn::Event &event) +{ + getContent()->setSize(getWidth() - 2 * getFrameSize(), getHeight() - 2 * getFrameSize()); +} diff --git a/src/gui/widgets/scrollarea.h b/src/gui/widgets/scrollarea.h index 8fd92b5f..69e99b1f 100644 --- a/src/gui/widgets/scrollarea.h +++ b/src/gui/widgets/scrollarea.h @@ -23,6 +23,7 @@ #define SCROLLAREA_H #include +#include class Image; class ImageRect; @@ -36,7 +37,7 @@ class ImageRect; * * \ingroup GUI */ -class ScrollArea : public gcn::ScrollArea +class ScrollArea : public gcn::ScrollArea, public gcn::WidgetListener { public: /** @@ -98,6 +99,8 @@ class ScrollArea : public gcn::ScrollArea */ void mouseExited(gcn::MouseEvent& event); + void widgetResized(const gcn::Event &event); + protected: enum BUTTON_DIR { UP, diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index bb5ae9a4..2de812ed 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -27,6 +27,7 @@ TabbedArea::TabbedArea() : gcn::TabbedArea() { mWidgetContainer->setOpaque(false); + addWidgetListener(this); } int TabbedArea::getNumberOfTabs() const @@ -152,3 +153,13 @@ void TabbedArea::setSelectedTab(gcn::Tab *tab) if (newTab) newTab->setCurrent(); } + +void TabbedArea::widgetResized(const gcn::Event &event) +{ + int width = getWidth() - 2 * getFrameSize(); + int height = getHeight() - 2 * getFrameSize() - mTabContainer->getHeight(); + mWidgetContainer->setSize(width, height); + gcn::Widget *w = getCurrentWidget(); + if (w) + w->setSize(width, height); +} diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h index 29ba2f76..1b61b102 100644 --- a/src/gui/widgets/tabbedarea.h +++ b/src/gui/widgets/tabbedarea.h @@ -23,6 +23,7 @@ #define TABBEDAREA_H #include +#include #include #include @@ -33,7 +34,7 @@ class Tab; /** * A tabbed area, the same as the guichan tabbed area in 0.8, but extended */ -class TabbedArea : public gcn::TabbedArea +class TabbedArea : public gcn::TabbedArea, public gcn::WidgetListener { public: /** @@ -97,6 +98,8 @@ class TabbedArea : public gcn::TabbedArea void setSelectedTab(gcn::Tab *tab); + void widgetResized(const gcn::Event &event); + private: typedef std::vector< std::pair > TabContainer; }; -- cgit v1.2.3-70-g09d2 From 1b13d8557c8666e1017fd70a455830dbdcb9f46c Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Mon, 10 Aug 2009 20:34:17 -0600 Subject: Add SpecialsWindow THis replaces the MagicWindow that the TMWServ build used and will be usable going forward for eAthena. --- src/CMakeLists.txt | 6 +- src/Makefile.am | 6 +- src/game.cpp | 8 +- src/gui/chat.cpp | 3 + src/gui/magic.cpp | 92 -------------- src/gui/magic.h | 61 --------- src/gui/specialswindow.cpp | 254 +++++++++++++++++++++++++++++++++++++ src/gui/specialswindow.h | 69 ++++++++++ src/gui/widgets/flowcontainer.cpp | 78 ++++++++++++ src/gui/widgets/flowcontainer.h | 68 ++++++++++ src/gui/windowmenu.cpp | 10 +- src/net/tmwserv/generalhandler.cpp | 6 +- src/net/tmwserv/generalhandler.h | 1 + src/net/tmwserv/specialhandler.cpp | 5 + src/net/tmwserv/specialhandler.h | 5 +- tmw.cbp | 12 +- 16 files changed, 508 insertions(+), 176 deletions(-) delete mode 100644 src/gui/magic.cpp delete mode 100644 src/gui/magic.h create mode 100644 src/gui/specialswindow.cpp create mode 100644 src/gui/specialswindow.h create mode 100644 src/gui/widgets/flowcontainer.cpp create mode 100644 src/gui/widgets/flowcontainer.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 43726f9d..eeaa7459 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -74,6 +74,8 @@ SET(SRCS gui/widgets/desktop.h gui/widgets/dropdown.cpp gui/widgets/dropdown.h + gui/widgets/flowcontainer.cpp + gui/widgets/flowcontainer.h gui/widgets/icon.cpp gui/widgets/icon.h gui/widgets/inttextfield.cpp @@ -221,6 +223,8 @@ SET(SRCS gui/skin.h gui/speechbubble.cpp gui/speechbubble.h + gui/specialswindow.cpp + gui/specialswindow.h gui/statuswindow.cpp gui/statuswindow.h gui/storagewindow.cpp @@ -476,8 +480,6 @@ SET(SRCS_TMW gui/guildlistbox.h gui/guildwindow.cpp gui/guildwindow.h - gui/magic.cpp - gui/magic.h gui/quitdialog.cpp gui/quitdialog.h gui/serverdialog.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 25fdb140..ff35cdd5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,6 +23,8 @@ tmw_SOURCES = gui/widgets/avatar.cpp \ gui/widgets/desktop.h \ gui/widgets/dropdown.cpp \ gui/widgets/dropdown.h \ + gui/widgets/flowcontainer.cpp \ + gui/widgets/flowcontainer.h \ gui/widgets/icon.cpp \ gui/widgets/icon.h \ gui/widgets/inttextfield.cpp \ @@ -170,6 +172,8 @@ tmw_SOURCES = gui/widgets/avatar.cpp \ gui/skin.h \ gui/speechbubble.cpp \ gui/speechbubble.h \ + gui/specialswindow.cpp \ + gui/specialswindow.h \ gui/statuswindow.cpp \ gui/statuswindow.h \ gui/storagewindow.cpp \ @@ -384,8 +388,6 @@ tmw_SOURCES += \ gui/guildlistbox.h \ gui/guildwindow.cpp \ gui/guildwindow.h \ - gui/magic.cpp \ - gui/magic.h \ gui/quitdialog.cpp \ gui/quitdialog.h \ gui/serverdialog.cpp \ diff --git a/src/game.cpp b/src/game.cpp index ff0d84f7..2acb8bc2 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -71,10 +71,10 @@ #ifdef TMWSERV_SUPPORT #include "gui/buddywindow.h" #include "gui/guildwindow.h" -#include "gui/magic.h" #include "gui/quitdialog.h" #endif #include "gui/npcpostdialog.h" +#include "gui/specialswindow.h" #include "gui/storagewindow.h" #include "net/generalhandler.h" @@ -128,7 +128,6 @@ PartyWindow *partyWindow; #ifdef TMWSERV_SUPPORT BuddyWindow *buddyWindow; GuildWindow *guildWindow; -MagicDialog *magicDialog; #endif NpcDialog *npcDialog; NpcPostDialog *npcPostDialog; @@ -141,6 +140,7 @@ DebugWindow *debugWindow; ShortcutWindow *itemShortcutWindow; ShortcutWindow *emoteShortcutWindow; OutfitWindow *outfitWindow; +SpecialsWindow *specialsWindow; BeingManager *beingManager = NULL; FloorItemManager *floorItemManager = NULL; @@ -215,7 +215,6 @@ static void createGuiWindows() tradeWindow = new TradeWindow; partyWindow = new PartyWindow; #ifdef TMWSERV_SUPPORT - magicDialog = new MagicDialog; buddyWindow = new BuddyWindow; guildWindow = new GuildWindow; #else @@ -237,6 +236,7 @@ static void createGuiWindows() emoteShortcutWindow = new ShortcutWindow("EmoteShortcut", new EmoteShortcutContainer); outfitWindow = new OutfitWindow(); + specialsWindow = new SpecialsWindow(); localChatTab = new ChatTab(_("General")); @@ -269,7 +269,6 @@ static void destroyGuiWindows() delete npcDialog; delete npcPostDialog; #ifdef TMWSERV_SUPPORT - delete magicDialog; delete buddyWindow; delete guildWindow; #endif @@ -283,6 +282,7 @@ static void destroyGuiWindows() delete emoteShortcutWindow; delete storageWindow; delete outfitWindow; + delete specialsWindow; } Game::Game(): diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index c337d33b..be302dc3 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -98,6 +98,8 @@ ChatWindow::ChatWindow(): mChatTabs = new TabbedArea; + //place(0, 0, mChatTabs, 3, 3); + //place(0, 3, mChatInput, 3); add(mChatTabs); add(mChatInput); @@ -128,6 +130,7 @@ void ChatWindow::resetToDefaultSize() void ChatWindow::adjustTabSize() { + //return; const gcn::Rectangle area = getChildrenArea(); mChatInput->setPosition(mChatInput->getFrameSize(), diff --git a/src/gui/magic.cpp b/src/gui/magic.cpp deleted file mode 100644 index 48cfc5dc..00000000 --- a/src/gui/magic.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 "gui/magic.h" - -#include "gui/widgets/button.h" -#include "gui/setup.h" - -#include "localplayer.h" - -#include "utils/dtor.h" -#include "utils/gettext.h" - -MagicDialog::MagicDialog(): - Window(_("Magic")) -{ - setWindowName("Magic"); - setCloseButton(true); - setSaveVisible(true); - setDefaultSize(255, 30, 175, 225); - setupWindow->registerWindowForReset(this); - - gcn::Button *spellButton1 = new Button(_("Cast Test Spell 1"), "spell_1", this); - gcn::Button *spellButton2 = new Button(_("Cast Test Spell 2"), "spell_2", this); - gcn::Button *spellButton3 = new Button(_("Cast Test Spell 3"), "spell_3", this); - - spellButton1->setPosition(10, 30); - spellButton2->setPosition(10, 60); - spellButton3->setPosition(10, 90); - - add(spellButton1); - add(spellButton2); - add(spellButton3); - - update(); - - setLocationRelativeTo(getParent()); - loadWindowState(); -} - -MagicDialog::~MagicDialog() -{ -} - -void MagicDialog::action(const gcn::ActionEvent &event) -{ - if (event.getId() == "spell_1") - { - player_node->useSpecial(1); - } - if (event.getId() == "spell_2") - { - player_node->useSpecial(2); - } - if (event.getId() == "spell_3") - { - player_node->useSpecial(3); - } - else if (event.getId() == "close") - { - setVisible(false); - } -} - -void MagicDialog::draw(gcn::Graphics *g) -{ - update(); - - Window::draw(g); -} - -void MagicDialog::update() -{ -} diff --git a/src/gui/magic.h b/src/gui/magic.h deleted file mode 100644 index 734ad799..00000000 --- a/src/gui/magic.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 - */ - -#ifndef MAGIC_H -#define MAGIC_H - -#include "gui/widgets/window.h" - -#include "guichanfwd.h" - -#include - -/** - * The skill dialog. - * - * \ingroup Interface - */ -class MagicDialog : public Window, public gcn::ActionListener -{ - public: - MagicDialog(); - - ~MagicDialog(); - - /** - * Called when receiving actions from widget. - */ - void action(const gcn::ActionEvent &event); - - /** - * Update the tabs in this dialog - */ - void update(); - - /** - * Draw this window. - */ - void draw(gcn::Graphics *g); -}; - -extern MagicDialog *magicDialog; - -#endif diff --git a/src/gui/specialswindow.cpp b/src/gui/specialswindow.cpp new file mode 100644 index 00000000..5d2ab676 --- /dev/null +++ b/src/gui/specialswindow.cpp @@ -0,0 +1,254 @@ +/* + * The Mana World + * Copyright (C) 2009 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 "gui/specialswindow.h" + +#include "gui/widgets/button.h" +#include "gui/widgets/container.h" +#include "gui/widgets/icon.h" +#include "gui/widgets/label.h" +#include "gui/widgets/layouthelper.h" +#include "gui/widgets/listbox.h" +#include "gui/widgets/progressbar.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/tab.h" +#include "gui/widgets/tabbedarea.h" +#include "gui/widgets/flowcontainer.h" +#include "gui/widgets/windowcontainer.h" +#include "gui/setup.h" + +#include "localplayer.h" +#include "log.h" + +#include "net/net.h" +#include "net/specialhandler.h" + +#include "utils/dtor.h" +#include "utils/gettext.h" +#include "utils/stringutils.h" +#include "utils/xml.h" + +#include + +#define SPECIALS_WIDTH 200 +#define SPECIALS_HEIGHT 32 + +class SpecialEntry; + +struct SpecialInfo +{ + unsigned short id; + std::string name; + std::string icon; + SpecialEntry *display; +}; + +class SpecialEntry : public Container +{ + public: + SpecialEntry(SpecialInfo *info); + + void update(); + + protected: + friend class SpecialsWindow; + SpecialInfo *mInfo; + + private: + Icon *mIcon; + Label *mNameLabel; + Label *mLevelLabel; + Label *mTechLabel; + Button *mUse; +}; + +SpecialsWindow::SpecialsWindow(): + Window(_("Specials")) +{ + setWindowName("Specials"); + setCloseButton(true); + setResizable(true); + setSaveVisible(true); + setDefaultSize(windowContainer->getWidth() - 280, 30, 275, 425); + setupWindow->registerWindowForReset(this); + + mTabs = new TabbedArea(); + + place(0, 0, mTabs, 5, 5); + + setLocationRelativeTo(getParent()); + loadWindowState(); +} + +SpecialsWindow::~SpecialsWindow() +{ + // Clear gui + loadSpecials(""); +} + +void SpecialsWindow::action(const gcn::ActionEvent &event) +{ + if (event.getId() == "use") + { + SpecialEntry *disp = dynamic_cast(event.getSource()->getParent()); + + if (disp) + { + /*Being *target = player_node->getTarget(); + + if (target) + Net::getSpecialHandler()->use(disp->mInfo->id, 1, target->getId()); + else*/ + Net::getSpecialHandler()->use(disp->mInfo->id); + } + } + else if (event.getId() == "close") + { + setVisible(false); + } +} + +void SpecialsWindow::logic() +{ + Window::logic(); + + Tab *tab = dynamic_cast(mTabs->getSelectedTab()); + if (tab != mCurrentTab) { + mCurrentTab = tab; + } +} + +std::string SpecialsWindow::update(int id) +{ + // TODO + + return std::string(); +} + +void SpecialsWindow::loadSpecials(const std::string &file) +{ + // TODO: mTabs->clear(); + while (mTabs->getSelectedTabIndex() != -1) + { + mTabs->removeTabWithIndex(mTabs->getSelectedTabIndex()); + } + + for (SpecialMap::iterator it = mSpecials.begin(); it != mSpecials.end(); it++) + { + delete (*it).second->display; + } + delete_all(mSpecials); + mSpecials.clear(); + + if (file.length() == 0) + return; + + XML::Document doc(file); + xmlNodePtr root = doc.rootNode(); + + if (!root || !xmlStrEqual(root->name, BAD_CAST "specials")) + { + logger->log("Error loading specials file: %s", file.c_str()); + return; + } + + int setCount = 0; + std::string setName; + ScrollArea *scroll; + FlowContainer *container; + + for_each_xml_child_node(set, root) + { + if (xmlStrEqual(set->name, BAD_CAST "set")) + { + setCount++; + setName = XML::getProperty(set, "name", strprintf(_("Specials Set %d"), setCount)); + + container = new FlowContainer(SPECIALS_WIDTH, SPECIALS_HEIGHT); + container->setOpaque(false); + scroll = new ScrollArea(container); + scroll->setOpaque(false); + scroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER); + scroll->setVerticalScrollPolicy(ScrollArea::SHOW_ALWAYS); + + mTabs->addTab(setName, scroll); + for_each_xml_child_node(node, set) + { + if (xmlStrEqual(node->name, BAD_CAST "special")) + { + int id = atoi(XML::getProperty(node, "id", "-1").c_str()); + if (id == -1) + continue; + std::string name = XML::getProperty(node, "name", strprintf(_("Special %d"), id)); + std::string icon = XML::getProperty(node, "icon", ""); + + SpecialInfo *special = new SpecialInfo; + special->id = id; + special->name = name; + special->icon = icon; + special->display = new SpecialEntry(special); + + container->add(special->display); + + mSpecials[id] = special; + } + } + } + } +} + +SpecialEntry::SpecialEntry(SpecialInfo *info) : + mInfo(info), + mIcon(NULL), + mNameLabel(new Label(info->name)), + mLevelLabel(new Label("999")), + mUse(new Button("Use", "use", specialsWindow)) +{ + setFrameSize(1); + setOpaque(false); + setSize(SPECIALS_WIDTH, SPECIALS_HEIGHT); + + if (!info->icon.empty()) + mIcon = new Icon(info->icon); + else + mIcon = new Icon("graphics/gui/unknown-item.png"); + + mIcon->setPosition(1, 0); + add(mIcon); + + mNameLabel->setPosition(35, 0); + add(mNameLabel); + + mLevelLabel->setPosition(getWidth() - mLevelLabel->getWidth(), 0); + add(mLevelLabel); + + mNameLabel->setWidth(mLevelLabel->getX() - mNameLabel->getX() - 1); + + mUse->setPosition(getWidth() - mUse->getWidth(), 13); + add(mUse); + + update(); +} + +void SpecialEntry::update() +{ + // TODO +} diff --git a/src/gui/specialswindow.h b/src/gui/specialswindow.h new file mode 100644 index 00000000..17c29597 --- /dev/null +++ b/src/gui/specialswindow.h @@ -0,0 +1,69 @@ +/* + * The Mana World + * Copyright (C) 2009 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 + */ + +#ifndef SPECIALSWINDOW_H +#define SPECIALSWINDOW_H + +#include "gui/widgets/window.h" + +#include "guichanfwd.h" + +#include + +#include + +class Label; +class ScrollArea; +class Tab; +class TabbedArea; + +struct SpecialInfo; + +class SpecialsWindow : public Window, public gcn::ActionListener { + public: + SpecialsWindow(); + + ~SpecialsWindow(); + + /** + * Called when receiving actions from widget. + */ + void action(const gcn::ActionEvent &actionEvent); + + void logic(); + + /** + * Update the given special's display + */ + std::string update(int id); + + void loadSpecials(const std::string &file); + + private: + typedef std::map SpecialMap; + SpecialMap mSpecials; + Tab *mCurrentTab; + TabbedArea *mTabs; +}; + +extern SpecialsWindow *specialsWindow; + +#endif // SPECIALSWINDOW_H diff --git a/src/gui/widgets/flowcontainer.cpp b/src/gui/widgets/flowcontainer.cpp new file mode 100644 index 00000000..6ce4284b --- /dev/null +++ b/src/gui/widgets/flowcontainer.cpp @@ -0,0 +1,78 @@ +/* + * The Mana World + * Copyright (C) 2007 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 "flowcontainer.h" + +FlowContainer::FlowContainer(int boxWidth, int boxHeight): + mBoxWidth(boxWidth), mBoxHeight(boxHeight), + mGridWidth(1), mGridHeight(1) +{ + addWidgetListener(this); +} + +void FlowContainer::widgetResized(const gcn::Event &event) +{ + if (getWidth() < mBoxWidth) + { + setWidth(mBoxWidth); + return; + } + + int itemCount = mWidgets.size(); + + mGridWidth = getWidth() / mBoxWidth; + + if (mGridWidth < 1) + mGridWidth = 1; + + mGridHeight = itemCount / mGridWidth; + + if (itemCount % mGridWidth != 0 || mGridHeight < 1) + ++mGridHeight; + + int height = mGridHeight * mBoxHeight; + + if (getHeight() != height) + { + setHeight(height); + return; + } + + int i = 0; + height = 0; + for (WidgetList::iterator it = mWidgets.begin(); it != mWidgets.end(); it++) + { + int x = i % mGridWidth * mBoxWidth; + (*it)->setPosition(x, height); + + i++; + + if (i % mGridWidth == 0) + height += mBoxHeight; + } +} + +void FlowContainer::add(gcn::Widget *widget) +{ + Container::add(widget); + widget->setSize(mBoxWidth, mBoxHeight); + widgetResized(NULL); +} diff --git a/src/gui/widgets/flowcontainer.h b/src/gui/widgets/flowcontainer.h new file mode 100644 index 00000000..afecde25 --- /dev/null +++ b/src/gui/widgets/flowcontainer.h @@ -0,0 +1,68 @@ +/* + * The Mana World + * Copyright (C) 2009 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 + */ + +#ifndef FLOWCONTAINER_H +#define FLOWCONTAINER_H + +#include "container.h" + +#include + +/** + * A container that arranges its contents like words on a page. + * + * \ingroup GUI + */ +class FlowContainer : public Container, + public gcn::WidgetListener +{ + public: + /** + * Constructor. Initializes the shortcut container. + */ + FlowContainer(int boxWidth, int boxHeight); + + /** + * Destructor. + */ + ~FlowContainer() {} + + /** + * Invoked when a widget changes its size. This is used to determine + * the new height of the container. + */ + void widgetResized(const gcn::Event &event); + + int getBoxWidth() const + { return mBoxWidth; } + + int getBoxHeight() const + { return mBoxHeight; } + + void add(gcn::Widget *widget); + + private: + int mBoxWidth; + int mBoxHeight; + int mGridWidth, mGridHeight; +}; + +#endif diff --git a/src/gui/windowmenu.cpp b/src/gui/windowmenu.cpp index 96776617..b73558c0 100644 --- a/src/gui/windowmenu.cpp +++ b/src/gui/windowmenu.cpp @@ -41,11 +41,11 @@ extern Window *inventoryWindow; extern Window *itemShortcutWindow; extern Window *setupWindow; extern Window *skillDialog; +extern Window *specialsWindow; extern Window *statusWindow; #ifdef TMWSERV_SUPPORT extern Window *buddyWindow; extern Window *guildWindow; -extern Window *magicDialog; #endif WindowMenu::WindowMenu(): @@ -59,8 +59,8 @@ WindowMenu::WindowMenu(): N_("Equipment"), N_("Inventory"), N_("Skills"), + N_("Specials"), #ifdef TMWSERV_SUPPORT - N_("Magic"), N_("Guilds"), N_("Buddies"), #endif @@ -129,11 +129,11 @@ void WindowMenu::action(const gcn::ActionEvent &event) { window = skillDialog; } -#ifdef TMWSERV_SUPPORT - else if (event.getId() == "Magic") + else if (event.getId() == "Specials") { - window = magicDialog; + window = specialsWindow; } +#ifdef TMWSERV_SUPPORT else if (event.getId() == "Guilds") { window = guildWindow; diff --git a/src/net/tmwserv/generalhandler.cpp b/src/net/tmwserv/generalhandler.cpp index d643586b..011433fe 100644 --- a/src/net/tmwserv/generalhandler.cpp +++ b/src/net/tmwserv/generalhandler.cpp @@ -22,6 +22,7 @@ #include "gui/inventorywindow.h" #include "gui/partywindow.h" #include "gui/skilldialog.h" +#include "gui/specialswindow.h" #include "gui/statuswindow.h" #include "net/tmwserv/generalhandler.h" @@ -43,6 +44,7 @@ #include "net/tmwserv/npchandler.h" #include "net/tmwserv/partyhandler.h" #include "net/tmwserv/playerhandler.h" +#include "net/tmwserv/specialhandler.h" #include "net/tmwserv/tradehandler.h" #include "utils/gettext.h" @@ -72,7 +74,8 @@ GeneralHandler::GeneralHandler(): mNpcHandler(new NpcHandler), mPartyHandler(new PartyHandler), mPlayerHandler(new PlayerHandler), - mTradeHandler(new TradeHandler) + mTradeHandler(new TradeHandler), + mSpecialHandler(new SpecialHandler) { accountServerConnection = Net::getConnection(); gameServerConnection = Net::getConnection(); @@ -149,6 +152,7 @@ void GeneralHandler::guiWindowsLoaded() inventoryWindow->setSplitAllowed(true); partyWindow->clearPartyName(); skillDialog->loadSkills("tmw-skills.xml"); + specialsWindow->loadSpecials("specials.xml"); player_node->setExpNeeded(100); diff --git a/src/net/tmwserv/generalhandler.h b/src/net/tmwserv/generalhandler.h index 08e18850..40166ca0 100644 --- a/src/net/tmwserv/generalhandler.h +++ b/src/net/tmwserv/generalhandler.h @@ -63,6 +63,7 @@ class GeneralHandler : public Net::GeneralHandler MessageHandlerPtr mPartyHandler; MessageHandlerPtr mPlayerHandler; MessageHandlerPtr mTradeHandler; + MessageHandlerPtr mSpecialHandler; }; } // namespace TmwServ diff --git a/src/net/tmwserv/specialhandler.cpp b/src/net/tmwserv/specialhandler.cpp index f259e77a..2e4ff1bb 100644 --- a/src/net/tmwserv/specialhandler.cpp +++ b/src/net/tmwserv/specialhandler.cpp @@ -37,6 +37,11 @@ SpecialHandler::SpecialHandler() specialHandler = this; } +void SpecialHandler::handleMessage(MessageIn &msg) +{ + // TODO +} + void SpecialHandler::use(int id) { MessageOut msg(PGMSG_USE_SPECIAL); diff --git a/src/net/tmwserv/specialhandler.h b/src/net/tmwserv/specialhandler.h index c7ebd6a2..b8f0ce90 100644 --- a/src/net/tmwserv/specialhandler.h +++ b/src/net/tmwserv/specialhandler.h @@ -22,15 +22,18 @@ #ifndef NET_TMWSERV_SKILLHANDLER_H #define NET_TMWSERV_SKILLHANDLER_H +#include "net/messagehandler.h" #include "net/specialhandler.h" namespace TmwServ { -class SpecialHandler : public Net::SpecialHandler +class SpecialHandler : public MessageHandler, public Net::SpecialHandler { public: SpecialHandler(); + void handleMessage(MessageIn &msg); + void use(int id); void use(int id, int level, int beingId); diff --git a/tmw.cbp b/tmw.cbp index 46c3aef2..86196052 100644 --- a/tmw.cbp +++ b/tmw.cbp @@ -267,14 +267,6 @@ - - - - @@ -355,6 +347,8 @@ + + @@ -406,6 +400,8 @@ + + -- cgit v1.2.3-70-g09d2 From 843fbb7fac79d1e0340fe489e8e78e4a41b3da43 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Mon, 10 Aug 2009 20:37:22 -0600 Subject: Move libintl from localplayer to gettext Better for future use. --- src/localplayer.cpp | 1 - src/utils/gettext.h | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 9e4d6ab5..57dc8981 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -65,7 +65,6 @@ #include "resources/iteminfo.h" #include "resources/resourcemanager.h" -#include #include "utils/gettext.h" #include "utils/stringutils.h" diff --git a/src/utils/gettext.h b/src/utils/gettext.h index 55e72555..4f85952c 100644 --- a/src/utils/gettext.h +++ b/src/utils/gettext.h @@ -26,10 +26,10 @@ #include "config.h" #endif -#if ENABLE_NLS - #include +#if ENABLE_NLS + #define _(s) ((char const *)gettext(s)) #define N_(s) ((char const *)s) -- cgit v1.2.3-70-g09d2 From 3a23f6a771142b6dc3df361b88621eec31d4e40f Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Mon, 10 Aug 2009 20:53:07 -0600 Subject: Remove layout code from ChatWindow --- src/gui/chat.cpp | 48 ++++-------------------------------------- src/gui/chat.h | 8 ------- src/gui/widgets/tabbedarea.cpp | 8 +++++++ src/gui/widgets/tabbedarea.h | 8 +++++++ 4 files changed, 20 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index be302dc3..4cabf92e 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -98,10 +98,10 @@ ChatWindow::ChatWindow(): mChatTabs = new TabbedArea; - //place(0, 0, mChatTabs, 3, 3); - //place(0, 3, mChatInput, 3); - add(mChatTabs); - add(mChatInput); + place(0, 0, mChatTabs, 3, 3); + place(0, 3, mChatInput, 3); + //add(mChatTabs); + //add(mChatInput); loadWindowState(); @@ -128,41 +128,6 @@ void ChatWindow::resetToDefaultSize() Window::resetToDefaultSize(); } -void ChatWindow::adjustTabSize() -{ - //return; - const gcn::Rectangle area = getChildrenArea(); - - mChatInput->setPosition(mChatInput->getFrameSize(), - area.height - mChatInput->getHeight() - - mChatInput->getFrameSize()); - mChatInput->setWidth(area.width - 2 * mChatInput->getFrameSize()); - - mChatTabs->setWidth(area.width - 2 * mChatTabs->getFrameSize()); - mChatTabs->setHeight(area.height - 2 * mChatTabs->getFrameSize() - - (mChatInput->getHeight() + mChatInput->getFrameSize() * 2)); - - ChatTab *tab = getFocused(); - if (tab) { - gcn::Widget *content = tab->mScrollArea; - bool scrollLock = false; - if(tab->mScrollArea->getVerticalMaxScroll() == tab->mScrollArea->getVerticalScrollAmount()) - scrollLock = true; - content->setSize(mChatTabs->getWidth() - 2 * content->getFrameSize(), - mChatTabs->getContainerHeight() - 2 * content->getFrameSize()); - content->logic(); - if(scrollLock) - tab->mScrollArea->setVerticalScrollAmount(tab->mScrollArea->getVerticalMaxScroll()); - } -} - -void ChatWindow::widgetResized(const gcn::Event &event) -{ - Window::widgetResized(event); - - adjustTabSize(); -} - void ChatWindow::logic() { Window::logic(); @@ -170,7 +135,6 @@ void ChatWindow::logic() Tab *tab = getFocused(); if (tab != mCurrentTab) { mCurrentTab = tab; - adjustTabSize(); } } @@ -294,10 +258,6 @@ void ChatWindow::addTab(ChatTab *tab) mChatTabs->addTab(tab, tab->mScrollArea); - // Fix for layout issues when adding the first tab - if (tab == localChatTab) - adjustTabSize(); - // Update UI logic(); } diff --git a/src/gui/chat.h b/src/gui/chat.h index 2de3a634..af5f760b 100644 --- a/src/gui/chat.h +++ b/src/gui/chat.h @@ -74,12 +74,6 @@ class ChatWindow : public Window, */ ~ChatWindow(); - /** - * Called when the widget changes size. Used for adapting the size of - * the tabbed area. - */ - void widgetResized(const gcn::Event &event); - void logic(); /** @@ -193,8 +187,6 @@ class ChatWindow : public Window, void removeWhisper(const std::string &nick); - void adjustTabSize(); - /** Used for showing item popup on clicking links **/ ItemLinkHandler *mItemLinkHandler; Recorder *mRecorder; diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index 2de812ed..681f99ec 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -80,6 +80,14 @@ gcn::Widget *TabbedArea::getCurrentWidget() return NULL; } +void TabbedArea::addTab(gcn::Tab* tab, gcn::Widget* widget) +{ + int width = getWidth() - 2 * getFrameSize(); + int height = getHeight() - 2 * getFrameSize() - mTabContainer->getHeight(); + widget->setSize(width, height); + gcn::TabbedArea::addTab(tab, widget); +} + void TabbedArea::addTab(const std::string &caption, gcn::Widget *widget) { Tab *tab = new Tab; diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h index 1b61b102..a64d855f 100644 --- a/src/gui/widgets/tabbedarea.h +++ b/src/gui/widgets/tabbedarea.h @@ -71,6 +71,14 @@ class TabbedArea : public gcn::TabbedArea, public gcn::WidgetListener using gcn::TabbedArea::addTab; + /** + * Add a tab. Overridden since it needs to size the widget. + * + * @param tab The tab widget for the tab. + * @param widget The widget to view when the tab is selected. + */ + void addTab(gcn::Tab* tab, gcn::Widget* widget); + /** * Add a tab. Overridden since it needs to create an instance of Tab * instead of gcn::Tab. -- cgit v1.2.3-70-g09d2 From bb9380e68c48f901353ac22042105243c8edd250 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Mon, 10 Aug 2009 20:54:18 -0600 Subject: Fix SkillDialog's layout for points to always show --- src/gui/skilldialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index 01b6e5ae..f6ab226a 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -95,7 +95,7 @@ SkillDialog::SkillDialog(): mPointsLabel = new Label("0"); place(0, 0, mTabs, 5, 5); - place(0, 5, mPointsLabel); + place(0, 5, mPointsLabel, 2); setLocationRelativeTo(getParent()); loadWindowState(); -- cgit v1.2.3-70-g09d2 From dd3df0c3d2adb3601abfedea2142c015cf3442c5 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Thu, 13 Aug 2009 08:06:06 -0600 Subject: Fix initial sizing issue with TabbedAreas Also remove some commented code from ChatWindow --- src/gui/chat.cpp | 2 -- src/gui/widgets/tabbedarea.cpp | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp index 4cabf92e..f1814d93 100644 --- a/src/gui/chat.cpp +++ b/src/gui/chat.cpp @@ -100,8 +100,6 @@ ChatWindow::ChatWindow(): place(0, 0, mChatTabs, 3, 3); place(0, 3, mChatInput, 3); - //add(mChatTabs); - //add(mChatInput); loadWindowState(); diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index 681f99ec..13bb884b 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -82,10 +82,11 @@ gcn::Widget *TabbedArea::getCurrentWidget() void TabbedArea::addTab(gcn::Tab* tab, gcn::Widget* widget) { + gcn::TabbedArea::addTab(tab, widget); + int width = getWidth() - 2 * getFrameSize(); int height = getHeight() - 2 * getFrameSize() - mTabContainer->getHeight(); widget->setSize(width, height); - gcn::TabbedArea::addTab(tab, widget); } void TabbedArea::addTab(const std::string &caption, gcn::Widget *widget) -- cgit v1.2.3-70-g09d2 From 3f21f53869044e5928ed2407a48ac28835da1cb1 Mon Sep 17 00:00:00 2001 From: Bertram Date: Thu, 13 Aug 2009 19:53:56 +0200 Subject: Cleaned up the image code a bit... --- src/resources/image.cpp | 284 +++++++++++++++++++++++++----------------------- src/resources/image.h | 90 +++++++++------ 2 files changed, 204 insertions(+), 170 deletions(-) (limited to 'src') diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 9af3059a..b51e1e1e 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -133,141 +133,11 @@ Image *Image::load(SDL_Surface *tmpImage) #ifdef USE_OPENGL if (mUseOpenGL) { - // Flush current error flag. - glGetError(); - - int width = tmpImage->w; - int height = tmpImage->h; - int realWidth = powerOfTwo(width); - int realHeight = powerOfTwo(height); - - if (realWidth < width || realHeight < height) - { - logger->log("Warning: image too large, cropping to %dx%d texture!", - tmpImage->w, tmpImage->h); - } - - // Make sure the alpha channel is not used, but copied to destination - SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE); - - // Determine 32-bit masks based on byte order - Uint32 rmask, gmask, bmask, amask; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - rmask = 0xff000000; - gmask = 0x00ff0000; - bmask = 0x0000ff00; - amask = 0x000000ff; -#else - rmask = 0x000000ff; - gmask = 0x0000ff00; - bmask = 0x00ff0000; - amask = 0xff000000; -#endif - - SDL_Surface *oldImage = tmpImage; - tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight, - 32, rmask, gmask, bmask, amask); - - if (!tmpImage) - { - logger->log("Error, image convert failed: out of memory"); - return NULL; - } - - SDL_BlitSurface(oldImage, NULL, tmpImage, NULL); - - GLuint texture; - glGenTextures(1, &texture); - glBindTexture(mTextureType, texture); - - if (SDL_MUSTLOCK(tmpImage)) - SDL_LockSurface(tmpImage); - - glTexImage2D( - mTextureType, 0, 4, - tmpImage->w, tmpImage->h, - 0, GL_RGBA, GL_UNSIGNED_BYTE, - tmpImage->pixels); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - if (SDL_MUSTLOCK(tmpImage)) { - SDL_UnlockSurface(tmpImage); - } - - SDL_FreeSurface(tmpImage); - - GLenum error = glGetError(); - if (error) - { - std::string errmsg = "Unknown error"; - switch (error) - { - case GL_INVALID_ENUM: - errmsg = "GL_INVALID_ENUM"; - break; - case GL_INVALID_VALUE: - errmsg = "GL_INVALID_VALUE"; - break; - case GL_INVALID_OPERATION: - errmsg = "GL_INVALID_OPERATION"; - break; - case GL_STACK_OVERFLOW: - errmsg = "GL_STACK_OVERFLOW"; - break; - case GL_STACK_UNDERFLOW: - errmsg = "GL_STACK_UNDERFLOW"; - break; - case GL_OUT_OF_MEMORY: - errmsg = "GL_OUT_OF_MEMORY"; - break; - } - logger->log("Error: Image GL import failed: %s", errmsg.c_str()); - return NULL; - } - - return new Image(texture, width, height, realWidth, realHeight); + return _GLload(tmpImage); } #endif - bool hasAlpha = false; - - if (tmpImage->format->BitsPerPixel == 32) - { - // Figure out whether the image uses its alpha layer - for (int i = 0; i < tmpImage->w * tmpImage->h; ++i) - { - Uint8 r, g, b, a; - SDL_GetRGBA( - ((Uint32*) tmpImage->pixels)[i], - tmpImage->format, - &r, &g, &b, &a); - - if (a != 255) - { - hasAlpha = true; - break; - } - } - } - - SDL_Surface *image; - - // Convert the surface to the current display format - if (hasAlpha) - image = SDL_DisplayFormatAlpha(tmpImage); - else - image = SDL_DisplayFormat(tmpImage); - - if (!image) - { - logger->log("Error: Image convert failed."); - return NULL; - } - - return new Image(image); + return _SDLload(tmpImage); } void Image::unload() @@ -313,7 +183,7 @@ void Image::setAlpha(float a) } } -Image* Image::merge(Image *image, int x, int y) +Image* Image::SDLmerge(Image *image, int x, int y) { SDL_Surface* surface = new SDL_Surface(*(image->mImage)); @@ -388,11 +258,6 @@ Image* Image::merge(Image *image, int x, int y) return newImage; } -float Image::getAlpha() const -{ - return mAlpha; -} - Image* Image::SDLgetScaledImage(int width, int height) { // No scaling on incorrect new values. @@ -421,7 +286,150 @@ Image* Image::SDLgetScaledImage(int width, int height) return scaledImage; } +Image *Image::_SDLload(SDL_Surface *tmpImage) +{ + if (!tmpImage) + return NULL; + + bool hasAlpha = false; + + if (tmpImage->format->BitsPerPixel == 32) + { + // Figure out whether the image uses its alpha layer + for (int i = 0; i < tmpImage->w * tmpImage->h; ++i) + { + Uint8 r, g, b, a; + SDL_GetRGBA( + ((Uint32*) tmpImage->pixels)[i], + tmpImage->format, + &r, &g, &b, &a); + + if (a != 255) + { + hasAlpha = true; + break; + } + } + } + + SDL_Surface *image; + + // Convert the surface to the current display format + if (hasAlpha) + image = SDL_DisplayFormatAlpha(tmpImage); + else + image = SDL_DisplayFormat(tmpImage); + + if (!image) + { + logger->log("Error: Image convert failed."); + return NULL; + } + + return new Image(image); +} + #ifdef USE_OPENGL +Image *Image::_GLload(SDL_Surface *tmpImage) +{ + // Flush current error flag. + glGetError(); + + int width = tmpImage->w; + int height = tmpImage->h; + int realWidth = powerOfTwo(width); + int realHeight = powerOfTwo(height); + + if (realWidth < width || realHeight < height) + { + logger->log("Warning: image too large, cropping to %dx%d texture!", + tmpImage->w, tmpImage->h); + } + + // Make sure the alpha channel is not used, but copied to destination + SDL_SetAlpha(tmpImage, 0, SDL_ALPHA_OPAQUE); + + // Determine 32-bit masks based on byte order + Uint32 rmask, gmask, bmask, amask; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; +#else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; +#endif + + SDL_Surface *oldImage = tmpImage; + tmpImage = SDL_CreateRGBSurface(SDL_SWSURFACE, realWidth, realHeight, + 32, rmask, gmask, bmask, amask); + + if (!tmpImage) + { + logger->log("Error, image convert failed: out of memory"); + return NULL; + } + + SDL_BlitSurface(oldImage, NULL, tmpImage, NULL); + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(mTextureType, texture); + + if (SDL_MUSTLOCK(tmpImage)) + SDL_LockSurface(tmpImage); + + glTexImage2D( + mTextureType, 0, 4, + tmpImage->w, tmpImage->h, + 0, GL_RGBA, GL_UNSIGNED_BYTE, + tmpImage->pixels); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(mTextureType, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(mTextureType, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + if (SDL_MUSTLOCK(tmpImage)) { + SDL_UnlockSurface(tmpImage); + } + + SDL_FreeSurface(tmpImage); + + GLenum error = glGetError(); + if (error) + { + std::string errmsg = "Unknown error"; + switch (error) + { + case GL_INVALID_ENUM: + errmsg = "GL_INVALID_ENUM"; + break; + case GL_INVALID_VALUE: + errmsg = "GL_INVALID_VALUE"; + break; + case GL_INVALID_OPERATION: + errmsg = "GL_INVALID_OPERATION"; + break; + case GL_STACK_OVERFLOW: + errmsg = "GL_STACK_OVERFLOW"; + break; + case GL_STACK_UNDERFLOW: + errmsg = "GL_STACK_UNDERFLOW"; + break; + case GL_OUT_OF_MEMORY: + errmsg = "GL_OUT_OF_MEMORY"; + break; + } + logger->log("Error: Image GL import failed: %s", errmsg.c_str()); + return NULL; + } + + return new Image(texture, width, height, realWidth, realHeight); +} + void Image::setLoadAsOpenGL(bool useOpenGL) { Image::mUseOpenGL = useOpenGL; diff --git a/src/resources/image.h b/src/resources/image.h index f497f608..824881a3 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -87,16 +87,6 @@ class Image : public Resource */ static Image *load(SDL_Surface *); - /** - * Gets an scaled instance of an image. - * - * @param width The desired width of the scaled image. - * @param height The desired height of the scaled image. - * - * @return A new Image* object. - */ - Image* SDLgetScaledImage(int width, int height); - /** * Frees the resources created by SDL. */ @@ -120,6 +110,17 @@ class Image : public Resource */ bool isAnOpenGLOne() const; + /** + * Sets the alpha value of this image. + */ + virtual void setAlpha(float alpha); + + /** + * Returns the alpha value of this image. + */ + float getAlpha() const + { return mAlpha; } + /** * Creates a new image with the desired clipping rectangle. * @@ -128,17 +129,32 @@ class Image : public Resource */ virtual Image *getSubImage(int x, int y, int width, int height); + + // SDL only public functions + /** - * Sets the alpha value of this image. + * Gets an scaled instance of an image. + * + * @param width The desired width of the scaled image. + * @param height The desired height of the scaled image. + * + * @return A new Image* object. */ - virtual void setAlpha(float alpha); + Image* SDLgetScaledImage(int width, int height); /** - * Returns the alpha value of this image. + * Merges two image SDL_Surfaces together. This is for SDL use only, as + * reducing the number of surfaces that SDL has to render can cut down + * on the number of blit operations necessary, which in turn can help + * improve overall framerates. Don't use unless you are using it to + * reduce the number of overall layers that need to be drawn through SDL. */ - float getAlpha() const; + Image *SDLmerge(Image *image, int x, int y); #ifdef USE_OPENGL + + // OpenGL only public functions + /** * Sets the target image format. Use false for SDL and * true for OpenGL. @@ -150,20 +166,36 @@ class Image : public Resource static int getTextureType() { return mTextureType; } #endif - /** - * Merges two image SDL_Surfaces together. This is for SDL use only, as - * reducing the number of surfaces that SDL has to render can cut down - * on the number of blit operations necessary, which in turn can help - * improve overall framerates. Don't use unless you are using it to - * reduce the number of overall layers that need to be drawn through SDL. - */ - Image *merge(Image *image, int x, int y); - protected: + + // ----------------------- + // Generic protected members + // ----------------------- + + SDL_Rect mBounds; + bool mLoaded; + float mAlpha; + + // ----------------------- + // SDL protected members + // ----------------------- + + /** SDL Constructor */ + Image(SDL_Surface *image); + + static Image *_SDLload(SDL_Surface *tmpImage); + + + SDL_Surface *mImage; + + + // ----------------------- + // OpenGL protected members + // ----------------------- +#ifdef USE_OPENGL /** - * Constructor. + * OpenGL Constructor. */ -#ifdef USE_OPENGL Image(GLuint glimage, int width, int height, int texWidth, int texHeight); @@ -171,13 +203,9 @@ class Image : public Resource * Returns the first power of two equal or bigger than the input. */ static int powerOfTwo(int input); -#endif - Image(SDL_Surface *image); - SDL_Rect mBounds; - bool mLoaded; + static Image *_GLload(SDL_Surface *tmpImage); -#ifdef USE_OPENGL GLuint mGLImage; int mTexWidth, mTexHeight; @@ -185,8 +213,6 @@ class Image : public Resource static int mTextureType; static int mTextureSize; #endif - SDL_Surface *mImage; - float mAlpha; }; /** -- cgit v1.2.3-70-g09d2 From 35979e4ee13898d99f16b2777292d257e91f8bf2 Mon Sep 17 00:00:00 2001 From: Bertram Date: Thu, 13 Aug 2009 20:21:54 +0200 Subject: Changed mImage member to mSDLSurface as it is SDL specific... --- src/graphics.cpp | 36 ++++++++++++++++++++---------------- src/resources/image.cpp | 36 ++++++++++++++++++------------------ src/resources/image.h | 2 +- 3 files changed, 39 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/graphics.cpp b/src/graphics.cpp index 75db11f4..14a2b852 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -117,7 +117,10 @@ int Graphics::getHeight() const bool Graphics::drawImage(Image *image, int x, int y) { - return drawImage(image, 0, 0, x, y, image->mBounds.w, image->mBounds.h); + if (image) + return drawImage(image, 0, 0, x, y, image->mBounds.w, image->mBounds.h); + else + return false; } bool Graphics::drawRescaledImage(Image *image, int srcX, int srcY, @@ -128,12 +131,13 @@ bool Graphics::drawRescaledImage(Image *image, int srcX, int srcY, { // Check that preconditions for blitting are met. if (!mScreen || !image) return false; - if (!image->mImage) return false; + if (!image->mSDLSurface) return false; Image *tmpImage = image->SDLgetScaledImage(desiredWidth, desiredHeight); bool returnValue = false; + if (!tmpImage) return false; - if (!tmpImage->mImage) return false; + if (!tmpImage->mSDLSurface) return false; dstX += mClipStack.top().xOffset; dstY += mClipStack.top().yOffset; @@ -148,7 +152,7 @@ bool Graphics::drawRescaledImage(Image *image, int srcX, int srcY, srcRect.w = width; srcRect.h = height; - returnValue = !(SDL_BlitSurface(tmpImage->mImage, &srcRect, mScreen, &dstRect) < 0); + returnValue = !(SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect, mScreen, &dstRect) < 0); delete tmpImage; @@ -160,7 +164,7 @@ bool Graphics::drawImage(Image *image, int srcX, int srcY, int dstX, int dstY, { // Check that preconditions for blitting are met. if (!mScreen || !image) return false; - if (!image->mImage) return false; + if (!image->mSDLSurface) return false; dstX += mClipStack.top().xOffset; dstY += mClipStack.top().yOffset; @@ -175,7 +179,7 @@ bool Graphics::drawImage(Image *image, int srcX, int srcY, int dstX, int dstY, srcRect.w = width; srcRect.h = height; - return !(SDL_BlitSurface(image->mImage, &srcRect, mScreen, &dstRect) < 0); + return !(SDL_BlitSurface(image->mSDLSurface, &srcRect, mScreen, &dstRect) < 0); } void Graphics::drawImage(gcn::Image const *image, int srcX, int srcY, @@ -191,12 +195,12 @@ void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h) { // Check that preconditions for blitting are met. if (!mScreen || !image) return; - if (!image->mImage) return; + if (!image->mSDLSurface) return; const int iw = image->getWidth(); const int ih = image->getHeight(); - - if (iw == 0 || ih == 0) return; + + if (iw == 0 || ih == 0) return; for (int py = 0; py < h; py += ih) // Y position on pattern plane { @@ -204,7 +208,7 @@ void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h) int srcY = image->mBounds.y; int dstY = y + py + mClipStack.top().yOffset; - for (int px = 0; px < w; px += iw) // X position on pattern plane + for (int px = 0; px < w; px += iw) // X position on pattern plane { int dw = (px + iw >= w) ? w - px : iw; int srcX = image->mBounds.x; @@ -216,7 +220,7 @@ void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h) srcRect.x = srcX; srcRect.y = srcY; srcRect.w = dw; srcRect.h = dh; - SDL_BlitSurface(image->mImage, &srcRect, mScreen, &dstRect); + SDL_BlitSurface(image->mSDLSurface, &srcRect, mScreen, &dstRect); } } } @@ -226,7 +230,7 @@ void Graphics::drawRescaledImagePattern(Image *image, int x, int y, { // Check that preconditions for blitting are met. if (!mScreen || !image) return; - if (!image->mImage) return; + if (!image->mSDLSurface) return; if (scaledHeight == 0 || scaledWidth == 0) return; @@ -235,8 +239,8 @@ void Graphics::drawRescaledImagePattern(Image *image, int x, int y, const int iw = tmpImage->getWidth(); const int ih = tmpImage->getHeight(); - - if (iw == 0 || ih == 0) return; + + if (iw == 0 || ih == 0) return; for (int py = 0; py < h; py += ih) // Y position on pattern plane { @@ -244,7 +248,7 @@ void Graphics::drawRescaledImagePattern(Image *image, int x, int y, int srcY = tmpImage->mBounds.y; int dstY = y + py + mClipStack.top().yOffset; - for (int px = 0; px < w; px += iw) // X position on pattern plane + for (int px = 0; px < w; px += iw) // X position on pattern plane { int dw = (px + iw >= w) ? w - px : iw; int srcX = tmpImage->mBounds.x; @@ -256,7 +260,7 @@ void Graphics::drawRescaledImagePattern(Image *image, int x, int y, srcRect.x = srcX; srcRect.y = srcY; srcRect.w = dw; srcRect.h = dh; - SDL_BlitSurface(tmpImage->mImage, &srcRect, mScreen, &dstRect); + SDL_BlitSurface(tmpImage->mSDLSurface, &srcRect, mScreen, &dstRect); } } diff --git a/src/resources/image.cpp b/src/resources/image.cpp index b51e1e1e..408668eb 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -38,13 +38,13 @@ Image::Image(SDL_Surface *image): #ifdef USE_OPENGL mGLImage(0), #endif - mImage(image), + mSDLSurface(image), mAlpha(1.0f) { mBounds.x = 0; mBounds.y = 0; - mBounds.w = mImage->w; - mBounds.h = mImage->h; + mBounds.w = mSDLSurface->w; + mBounds.h = mSDLSurface->h; } #ifdef USE_OPENGL @@ -52,7 +52,7 @@ Image::Image(GLuint glimage, int width, int height, int texWidth, int texHeight) mGLImage(glimage), mTexWidth(texWidth), mTexHeight(texHeight), - mImage(0), + mSDLSurface(0), mAlpha(1.0) { mBounds.x = 0; @@ -144,11 +144,11 @@ void Image::unload() { mLoaded = false; - if (mImage) + if (mSDLSurface) { // Free the image surface. - SDL_FreeSurface(mImage); - mImage = NULL; + SDL_FreeSurface(mSDLSurface); + mSDLSurface = NULL; } #ifdef USE_OPENGL @@ -176,27 +176,27 @@ void Image::setAlpha(float a) mAlpha = a; - if (mImage) + if (mSDLSurface) { // Set the alpha value this image is drawn at - SDL_SetAlpha(mImage, SDL_SRCALPHA, (int) (255 * mAlpha)); + SDL_SetAlpha(mSDLSurface, SDL_SRCALPHA, (int) (255 * mAlpha)); } } Image* Image::SDLmerge(Image *image, int x, int y) { - SDL_Surface* surface = new SDL_Surface(*(image->mImage)); + SDL_Surface* surface = new SDL_Surface(*(image->mSDLSurface)); Uint32 surface_pix, cur_pix; Uint8 r, g, b, a, p_r, p_g, p_b, p_a; double f_a, f_ca, f_pa; - SDL_PixelFormat *current_fmt = mImage->format; + SDL_PixelFormat *current_fmt = mSDLSurface->format; SDL_PixelFormat *surface_fmt = surface->format; int current_offset, surface_offset; int offset_x, offset_y; SDL_LockSurface(surface); - SDL_LockSurface(mImage); + SDL_LockSurface(mSDLSurface); // for each pixel lines of a source image for (offset_x = (x > 0 ? 0 : -x); offset_x < image->getWidth() && x + offset_x < getWidth(); offset_x++) @@ -210,7 +210,7 @@ Image* Image::SDLmerge(Image *image, int x, int y) // Retrieving a pixel to merge surface_pix = ((Uint32*) surface->pixels)[surface_offset]; - cur_pix = ((Uint32*) mImage->pixels)[current_offset]; + cur_pix = ((Uint32*) mSDLSurface->pixels)[current_offset]; // Retreiving each channel of the pixel using pixel format r = (Uint8)(((surface_pix & surface_fmt->Rmask) >> @@ -251,7 +251,7 @@ Image* Image::SDLmerge(Image *image, int x, int y) } } SDL_UnlockSurface(surface); - SDL_UnlockSurface(mImage); + SDL_UnlockSurface(mSDLSurface); Image *newImage = new Image(surface); @@ -271,9 +271,9 @@ Image* Image::SDLgetScaledImage(int width, int height) Image* scaledImage = NULL; SDL_Surface* scaledSurface = NULL; - if (mImage) + if (mSDLSurface) { - scaledSurface = _SDLzoomSurface(mImage, + scaledSurface = _SDLzoomSurface(mSDLSurface, (double) width / getWidth(), (double) height / getHeight(), 1); @@ -463,7 +463,7 @@ Image *Image::getSubImage(int x, int y, int width, int height) mTexWidth, mTexHeight); #endif - return new SubImage(this, mImage, x, y, width, height); + return new SubImage(this, mSDLSurface, x, y, width, height); } //============================================================================ @@ -504,7 +504,7 @@ SubImage::SubImage(Image *parent, GLuint image, SubImage::~SubImage() { // Avoid destruction of the image - mImage = 0; + mSDLSurface = 0; #ifdef USE_OPENGL mGLImage = 0; #endif diff --git a/src/resources/image.h b/src/resources/image.h index 824881a3..91ecbb54 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -186,7 +186,7 @@ class Image : public Resource static Image *_SDLload(SDL_Surface *tmpImage); - SDL_Surface *mImage; + SDL_Surface *mSDLSurface; // ----------------------- -- cgit v1.2.3-70-g09d2 From 1f2a31c0a97ee2ff858fe142e778c49011b93f71 Mon Sep 17 00:00:00 2001 From: Bertram Date: Fri, 14 Aug 2009 00:00:57 +0200 Subject: Made the mLoaded member working again. --- src/resources/image.cpp | 24 ++++++++++++++++++++++-- src/resources/image.h | 6 ++++++ 2 files changed, 28 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 408668eb..b3f7140d 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -43,8 +43,19 @@ Image::Image(SDL_Surface *image): { mBounds.x = 0; mBounds.y = 0; - mBounds.w = mSDLSurface->w; - mBounds.h = mSDLSurface->h; + + if (mSDLSurface) + { + mBounds.w = mSDLSurface->w; + mBounds.h = mSDLSurface->h; + mLoaded = true; + } + else + { + logger->log( + "Image::Image(SDL_Surface*): Couldn't load invalid Surface!"); + mLoaded = false; + } } #ifdef USE_OPENGL @@ -59,6 +70,15 @@ Image::Image(GLuint glimage, int width, int height, int texWidth, int texHeight) mBounds.y = 0; mBounds.w = width; mBounds.h = height; + + if (mGLImage) + mLoaded = true; + else + { + logger->log( + "Image::Image(GLuint*, ...): Couldn't load invalid Surface!"); + mLoaded = false; + } } #endif diff --git a/src/resources/image.h b/src/resources/image.h index 91ecbb54..c97523a9 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -92,6 +92,12 @@ class Image : public Resource */ virtual void unload(); + /** + * Tells is the image is loaded + */ + bool isLoaded() + { return mLoaded; } + /** * Returns the width of the image. */ -- cgit v1.2.3-70-g09d2 From 32e63222acc750fce68048211df3434256802ec4 Mon Sep 17 00:00:00 2001 From: Bertram Date: Fri, 14 Aug 2009 00:19:00 +0200 Subject: Added a new function to know if an image is using an alpha channel. This all will be useful for my next patch: Repair windows opacity break in SDL mode. --- src/resources/image.cpp | 42 +++++++++++++++++++++++++++++++++++++++++- src/resources/image.h | 10 ++++++++-- 2 files changed, 49 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/resources/image.cpp b/src/resources/image.cpp index b3f7140d..0540d543 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -48,6 +48,8 @@ Image::Image(SDL_Surface *image): { mBounds.w = mSDLSurface->w; mBounds.h = mSDLSurface->h; + + mAlphaChannel = hasAlphaChannel(); mLoaded = true; } else @@ -64,7 +66,8 @@ Image::Image(GLuint glimage, int width, int height, int texWidth, int texHeight) mTexWidth(texWidth), mTexHeight(texHeight), mSDLSurface(0), - mAlpha(1.0) + mAlpha(1.0), + mAlphaChannel(true) { mBounds.x = 0; mBounds.y = 0; @@ -189,6 +192,43 @@ bool Image::isAnOpenGLOne() const #endif } +bool Image::hasAlphaChannel() +{ + if (mLoaded) + return mAlphaChannel; + +#ifdef USE_OPENGL + if (mUseOpenGL) + return true; +#endif + + if (!mSDLSurface) + return false; + + bool hasAlpha = false; + + if (mSDLSurface->format->BitsPerPixel == 32) + { + // Figure out whether the image uses its alpha layer + for (int i = 0; i < mSDLSurface->w * mSDLSurface->h; ++i) + { + Uint8 r, g, b, a; + SDL_GetRGBA( + ((Uint32*) mSDLSurface->pixels)[i], + mSDLSurface->format, + &r, &g, &b, &a); + + if (a != 255) + { + hasAlpha = true; + break; + } + } + } + + return hasAlpha; +} + void Image::setAlpha(float a) { if (mAlpha == a) diff --git a/src/resources/image.h b/src/resources/image.h index c97523a9..535a3536 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -111,11 +111,17 @@ class Image : public Resource { return mBounds.h; } /** - * Tells if the image was loade using OpenGL or SDL + * Tells if the image was loaded using OpenGL or SDL * @return true if OpenGL, false if SDL. */ bool isAnOpenGLOne() const; + /** + * Tells if the image has got an alpha channel + * @return true if OpenGL, false if SDL. + */ + bool hasAlphaChannel(); + /** * Sets the alpha value of this image. */ @@ -181,6 +187,7 @@ class Image : public Resource SDL_Rect mBounds; bool mLoaded; float mAlpha; + bool mAlphaChannel; // ----------------------- // SDL protected members @@ -191,7 +198,6 @@ class Image : public Resource static Image *_SDLload(SDL_Surface *tmpImage); - SDL_Surface *mSDLSurface; -- cgit v1.2.3-70-g09d2 From d6f3fde56c562a0a060c5e472c831c577c9a33c1 Mon Sep 17 00:00:00 2001 From: Bertram Date: Fri, 14 Aug 2009 00:26:12 +0200 Subject: Reliability fix in Image::Image(SDL_Surface*)... --- src/resources/image.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 0540d543..4b913b57 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -44,6 +44,8 @@ Image::Image(SDL_Surface *image): mBounds.x = 0; mBounds.y = 0; + mLoaded = false; + if (mSDLSurface) { mBounds.w = mSDLSurface->w; @@ -53,11 +55,8 @@ Image::Image(SDL_Surface *image): mLoaded = true; } else - { logger->log( "Image::Image(SDL_Surface*): Couldn't load invalid Surface!"); - mLoaded = false; - } } #ifdef USE_OPENGL -- cgit v1.2.3-70-g09d2 From 2f2443e9b2dab7c69c5713ece18b95f4b03e0e85 Mon Sep 17 00:00:00 2001 From: Bertram Date: Fri, 14 Aug 2009 00:29:29 +0200 Subject: Prevented another possible segfault... --- src/resources/image.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 4b913b57..8e4360e6 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -244,6 +244,9 @@ void Image::setAlpha(float a) Image* Image::SDLmerge(Image *image, int x, int y) { + if (!mSDLSurface) + return NULL; + SDL_Surface* surface = new SDL_Surface(*(image->mSDLSurface)); Uint32 surface_pix, cur_pix; -- cgit v1.2.3-70-g09d2 From ed8025fe0dfcb1ca54c62ffc2905c1cb48772cde Mon Sep 17 00:00:00 2001 From: Bertram Date: Fri, 14 Aug 2009 00:33:02 +0200 Subject: Minor update... --- src/resources/image.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 8e4360e6..172ff0f0 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -154,11 +154,8 @@ Image *Image::load(SDL_Surface *tmpImage) { #ifdef USE_OPENGL if (mUseOpenGL) - { return _GLload(tmpImage); - } #endif - return _SDLload(tmpImage); } -- cgit v1.2.3-70-g09d2 From 0c9ee8a74e62fe65acb551370db07ca568e3a0b3 Mon Sep 17 00:00:00 2001 From: Bertram Date: Fri, 14 Aug 2009 01:05:49 +0200 Subject: Added a Alpha Channel copier for 32 bit SDL based images. This will later be used to keep the original alpha value... --- src/resources/image.cpp | 40 +++++++++++++++++++++++++++++++++++----- src/resources/image.h | 11 ++++++++++- 2 files changed, 45 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 172ff0f0..1689aa1d 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -38,8 +38,9 @@ Image::Image(SDL_Surface *image): #ifdef USE_OPENGL mGLImage(0), #endif - mSDLSurface(image), - mAlpha(1.0f) + mAlpha(1.0f), + mAlphaChannel(0), + mSDLSurface(image) { mBounds.x = 0; mBounds.y = 0; @@ -51,7 +52,7 @@ Image::Image(SDL_Surface *image): mBounds.w = mSDLSurface->w; mBounds.h = mSDLSurface->h; - mAlphaChannel = hasAlphaChannel(); + mHasAlphaChannel = hasAlphaChannel(); mLoaded = true; } else @@ -64,9 +65,10 @@ Image::Image(GLuint glimage, int width, int height, int texWidth, int texHeight) mGLImage(glimage), mTexWidth(texWidth), mTexHeight(texHeight), - mSDLSurface(0), mAlpha(1.0), - mAlphaChannel(true) + mHasAlphaChannel(true), + mAlphaChannel(0), + mSDLSurface(0) { mBounds.x = 0; mBounds.y = 0; @@ -388,6 +390,34 @@ Image *Image::_SDLload(SDL_Surface *tmpImage) return new Image(image); } +Uint8 *Image::_SDLgetAlphaChannel() +{ + if (!mSDLSurface) + return NULL; + + // If an old channel was stored, we free it. + free(mAlphaChannel); + mAlphaChannel = NULL; + + // We allocate the place to put our data + Uint8* mAlphaChannel = (Uint8*)malloc(mSDLSurface->w * mSDLSurface->h * sizeof(Uint8)); + + if (mSDLSurface->format->BitsPerPixel == 32) + { + // Figure out whether the image uses its alpha layer + for (int i = 0; i < mSDLSurface->w * mSDLSurface->h; ++i) + { + Uint8 r, g, b, a; + SDL_GetRGBA( + ((Uint32*) mSDLSurface->pixels)[i], + mSDLSurface->format, + &r, &g, &b, &a); + + mAlphaChannel[i] = a; + } + } +} + #ifdef USE_OPENGL Image *Image::_GLload(SDL_Surface *tmpImage) { diff --git a/src/resources/image.h b/src/resources/image.h index 535a3536..34ec2887 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -187,7 +187,7 @@ class Image : public Resource SDL_Rect mBounds; bool mLoaded; float mAlpha; - bool mAlphaChannel; + bool mHasAlphaChannel; // ----------------------- // SDL protected members @@ -196,8 +196,17 @@ class Image : public Resource /** SDL Constructor */ Image(SDL_Surface *image); + /** SDL_Surface to SDL_Surface Image loader */ static Image *_SDLload(SDL_Surface *tmpImage); + /** + * Make a converted copy of the alpha channel + * used for 32 bits SDLbased images + * in order to support changing the opacity. + */ + Uint8 *_SDLgetAlphaChannel(); + Uint8* mAlphaChannel; + SDL_Surface *mSDLSurface; -- cgit v1.2.3-70-g09d2 From be85ca9d91ff867faf140328d0bcbb2062b58cdf Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Thu, 13 Aug 2009 10:31:23 -0600 Subject: Make NPC inherit from Being instead of Player No need for NPCs to inherit from Player. Player has functions NPC doesn't need and overrides that NPC doesn't need. This change reduces the number of functions needed to be overrided by NPC. --- src/npc.cpp | 13 +------------ src/npc.h | 4 +--- 2 files changed, 2 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/npc.cpp b/src/npc.cpp index a49ef406..f7172d4b 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -36,7 +36,7 @@ bool NPC::isTalking = false; int current_npc = 0; NPC::NPC(int id, int job, Map *map): - Player(id, job, map) + Being(id, job, map) { NPCInfo info = NPCDB::get(job); @@ -89,17 +89,6 @@ void NPC::setName(const std::string &name) Being::setName(displayName + " (NPC)"); } -void NPC::setGender(Gender gender) -{ - Being::setGender(gender); -} - -void NPC::setSprite(int slot, int id, std::string color) -{ - // Fix this later should it not be adequate enough. - Being::setSprite(slot, id, color); -} - Being::Type NPC::getType() const { return Being::NPC; diff --git a/src/npc.h b/src/npc.h index fc6f3459..392ee8c5 100644 --- a/src/npc.h +++ b/src/npc.h @@ -27,7 +27,7 @@ class Graphics; class Text; -class NPC : public Player +class NPC : public Being { public: NPC(int id, int job, Map *map); @@ -35,8 +35,6 @@ class NPC : public Player ~NPC(); void setName(const std::string &name); - void setGender(Gender gender); - void setSprite(int slot, int id, std::string color); virtual Type getType() const; -- cgit v1.2.3-70-g09d2 From f46cfb91278b27f4943f5512778129fe985c678e Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Thu, 13 Aug 2009 17:30:59 -0600 Subject: Clean up Being and it's derivatives Move stuff only needed for Players into Player (like slots and sprite limits). Move name handling into Being (no need for three copies of this code). Clean up terminology (including Map terminology). Remove hair-related variables. --- src/being.cpp | 147 +++++++++++++++++++--------------- src/being.h | 104 ++++++------------------ src/flooritem.cpp | 4 +- src/flooritem.h | 6 +- src/gui/charcreatedialog.cpp | 46 +++++++---- src/gui/charcreatedialog.h | 8 +- src/gui/charselectdialog.h | 3 +- src/gui/playerbox.cpp | 6 +- src/localplayer.cpp | 27 +++---- src/localplayer.h | 10 ++- src/map.cpp | 8 +- src/map.h | 12 +-- src/monster.cpp | 62 +++++--------- src/monster.h | 15 +--- src/net/ea/beinghandler.cpp | 91 ++++++++++++--------- src/net/ea/charserverhandler.cpp | 25 +++--- src/net/ea/partyhandler.cpp | 2 - src/net/logindata.h | 2 +- src/net/tmwserv/beinghandler.cpp | 11 +-- src/net/tmwserv/charserverhandler.cpp | 4 +- src/npc.cpp | 36 +-------- src/npc.h | 9 +-- src/player.cpp | 127 +++++++++-------------------- src/player.h | 71 +++++++++------- src/playerrelations.cpp | 2 +- src/resources/iteminfo.h | 2 +- 26 files changed, 365 insertions(+), 475 deletions(-) (limited to 'src') diff --git a/src/being.cpp b/src/being.cpp index 23b87e6c..37ae2200 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -77,18 +77,11 @@ Being::Being(int id, int job, Map *map): mSpriteDirection(DIRECTION_DOWN), mMap(NULL), mParticleEffects(config.getValue("particleeffects", 1)), + mDispName(0), + mShowName(false), mEquippedWeapon(NULL), -#ifdef TMWSERV_SUPPORT - mHairStyle(0), -#else - mHairStyle(1), -#endif - mHairColor(0), - mGender(GENDER_UNSPECIFIED), + mText(0), mStunMode(0), - mSprites(VECTOREND_SPRITE, NULL), - mSpriteIDs(VECTOREND_SPRITE, 0), - mSpriteColors(VECTOREND_SPRITE, ""), mStatusParticleEffects(&mStunParticleEffects, false), mChildParticleEffects(&mStatusParticleEffects, false), mMustResetParticles(false), @@ -105,8 +98,8 @@ Being::Being(int id, int job, Map *map): mSpeechBubble = new SpeechBubble; - mNameColor = &guiPalette->getColor(Palette::CHAT); - mText = 0; + mNameColor = &guiPalette->getColor(Palette::NPC); + mTextColor = &guiPalette->getColor(Palette::CHAT); } Being::~Being() @@ -120,6 +113,7 @@ Being::~Being() setMap(NULL); delete mSpeechBubble; + delete mDispName; delete mText; } @@ -218,19 +212,6 @@ void Being::setPath(const Path &path) #endif } -void Being::setHairStyle(int style, int color) -{ - mHairStyle = style < 0 ? mHairStyle : style % mNumberOfHairstyles; - mHairColor = color < 0 ? mHairColor : color % ColorDB::size(); -} - -void Being::setSprite(int slot, int id, const std::string &color) -{ - assert(slot >= BASE_SPRITE && slot < VECTOREND_SPRITE); - mSpriteIDs[slot] = id; - mSpriteColors[slot] = color; -} - void Being::setSpeech(const std::string &text, int time) { mSpeech = text; @@ -368,17 +349,42 @@ void Being::handleAttack(Being *victim, int damage, AttackType type) #endif } +void Being::setName(const std::string &name) +{ + mName = name; + + if (getShowName()) + showName(); +} + +void Being::setShowName(bool doShowName) +{ + bool oldShow = mShowName; + mShowName = doShowName; + + if (doShowName != oldShow) + { + if (doShowName) + showName(); + else + { + delete mDispName; + mDispName = 0; + } + } +} + void Being::setMap(Map *map) { // Remove sprite from potential previous map if (mMap) - mMap->removeSprite(mSpriteIterator); + mMap->removeSprite(mMapSprite); mMap = map; // Add sprite to potential new map if (mMap) - mSpriteIterator = mMap->addSprite(this); + mMapSprite = mMap->addSprite(this); // Clear particle effect list because child particles became invalid mChildParticleEffects.clear(); @@ -408,11 +414,9 @@ void Being::setAction(Action action, int attackType) else currentAction = ACTION_ATTACK; - for (int i = 0; i < VECTOREND_SPRITE; i++) - { - if (mSprites[i]) - mSprites[i]->reset(); - } + for (SpriteIterator it = mSprites.begin(); it != mSprites.end(); it++) + if (*it) + (*it)->reset(); break; case HURT: //currentAction = ACTION_HURT; // Buggy: makes the player stop @@ -429,11 +433,9 @@ void Being::setAction(Action action, int attackType) if (currentAction != ACTION_INVALID) { - for (int i = 0; i < VECTOREND_SPRITE; i++) - { - if (mSprites[i]) - mSprites[i]->play(currentAction); - } + for (SpriteIterator it = mSprites.begin(); it != mSprites.end(); it++) + if (*it) + (*it)->play(currentAction); mAction = action; } } @@ -461,11 +463,9 @@ void Being::setDirection(Uint8 direction) dir = DIRECTION_LEFT; mSpriteDirection = dir; - for (int i = 0; i < VECTOREND_SPRITE; i++) - { - if (mSprites[i]) - mSprites[i]->setDirection(dir); - } + for (SpriteIterator it = mSprites.begin(); it != mSprites.end(); it++) + if (*it) + (*it)->setDirection(dir); } #ifdef EATHENA_SUPPORT @@ -573,11 +573,9 @@ void Being::logic() if (mUsedTargetCursor) mUsedTargetCursor->update(tick_time * 10); - for (int i = 0; i < VECTOREND_SPRITE; i++) - { - if (mSprites[i]) - mSprites[i]->update(tick_time * 10); - } + for (SpriteIterator it = mSprites.begin(); it != mSprites.end(); it++) + if (*it) + (*it)->update(tick_time * 10); // Restart status/particle effects, if needed if (mMustResetParticles) { @@ -605,13 +603,9 @@ void Being::draw(Graphics *graphics, int offsetX, int offsetY) const if (mUsedTargetCursor) mUsedTargetCursor->draw(graphics, px, py); - for (int i = 0; i < VECTOREND_SPRITE; i++) - { - if (mSprites[i]) - { - mSprites[i]->draw(graphics, px, py); - } - } + for (SpriteConstIterator it = mSprites.begin(); it != mSprites.end(); it++) + if (*it) + (*it)->draw(graphics, px, py); } void Being::drawEmotion(Graphics *graphics, int offsetX, int offsetY) @@ -650,7 +644,7 @@ void Being::drawSpeech(int offsetX, int offsetY) mText = NULL; } - mSpeechBubble->setCaption(showName ? mName : "", mNameColor); + mSpeechBubble->setCaption(showName ? mName : "", mTextColor); mSpeechBubble->setText(mSpeech, showName); mSpeechBubble->setPosition(px - (mSpeechBubble->getWidth() / 2), @@ -680,11 +674,6 @@ void Being::drawSpeech(int offsetX, int offsetY) } } -Being::Type Being::getType() const -{ - return UNKNOWN; -} - void Being::setStatusEffectBlock(int offset, Uint16 newEffects) { for (int i = 0; i < STATUS_EFFECTS; i++) { @@ -765,7 +754,13 @@ int Being::getOffset(char pos, char neg) const int Being::getWidth() const { - if (AnimatedSprite *base = mSprites[BASE_SPRITE]) + AnimatedSprite *base = NULL; + + for (SpriteConstIterator it = mSprites.begin(); it != mSprites.end(); it++) + if ((base = (*it))) + break; + + if (base) return std::max(base->getWidth(), DEFAULT_WIDTH); else return DEFAULT_WIDTH; @@ -773,7 +768,13 @@ int Being::getWidth() const int Being::getHeight() const { - if (AnimatedSprite *base = mSprites[BASE_SPRITE]) + AnimatedSprite *base = NULL; + + for (SpriteConstIterator it = mSprites.begin(); it != mSprites.end(); it++) + if ((base = (*it))) + break; + + if (base) return std::max(base->getHeight(), DEFAULT_HEIGHT); else return DEFAULT_HEIGHT; @@ -875,9 +876,27 @@ void Being::internalTriggerEffect(int effectId, bool sfx, bool gfx) } } -int Being::getHairStyleCount() +void Being::updateCoords() { - return mNumberOfHairstyles; + if (mDispName) + { + mDispName->adviseXY(getPixelX(), getPixelY()); + } +} + +void Being::flashName(int time) +{ + if (mDispName) + mDispName->flash(time); +} + +void Being::showName() +{ + delete mDispName; + mDispName = 0; + + mDispName = new FlashText(mName, getPixelX(), getPixelY(), + gcn::Graphics::CENTER, mNameColor); } void Being::load() diff --git a/src/being.h b/src/being.h index 6e90b39d..ad7f3459 100644 --- a/src/being.h +++ b/src/being.h @@ -46,11 +46,11 @@ #define SPEECH_MAX_TIME 1000 class AnimatedSprite; +class FlashText; +class Graphics; class Image; class ItemInfo; class Item; -class Map; -class Graphics; class Particle; class Position; class SimpleAnimation; @@ -59,16 +59,6 @@ class Text; class StatusEffect; -typedef std::list Sprites; -typedef Sprites::iterator SpriteIterator; - -enum Gender -{ - GENDER_MALE = 0, - GENDER_FEMALE = 1, - GENDER_UNSPECIFIED = 2 -}; - class Being : public Sprite, public ConfigListener { public: @@ -95,29 +85,6 @@ class Being : public Sprite, public ConfigListener HURT }; - enum Sprite - { - BASE_SPRITE = 0, - SHOE_SPRITE, - BOTTOMCLOTHES_SPRITE, - TOPCLOTHES_SPRITE, -#ifdef EATHENA_SUPPORT - MISC1_SPRITE, - MISC2_SPRITE, -#endif - HAIR_SPRITE, - HAT_SPRITE, -#ifdef EATHENA_SUPPORT - CAPE_SPRITE, - GLOVES_SPRITE, -#endif - WEAPON_SPRITE, -#ifdef EATHENA_SUPPORT - SHIELD_SPRITE, -#endif - VECTOREND_SPRITE - }; - enum TargetCursorSize { TC_SMALL = 0, @@ -246,42 +213,17 @@ class Being : public Sprite, public ConfigListener * * @param name The name that should appear. */ - virtual void setName(const std::string &name) - { mName = name; } + virtual void setName(const std::string &name); - /** - * Gets the hair color for this being. - */ - int getHairColor() const { return mHairColor; } + const bool getShowName() const { return mShowName; } - /** - * Gets the hair style for this being. - */ - int getHairStyle() const { return mHairStyle; } + virtual void setShowName(bool doShowName); /** * Get the number of hairstyles implemented */ static int getNumOfHairstyles() { return mNumberOfHairstyles; } - /** - * Sets the hair style and color for this being. - */ - virtual void setHairStyle(int style, int color); - - /** - * Sets visible equipments for this being. - */ - virtual void setSprite(int slot, int id, - const std::string &color = ""); - - /** - * Sets the gender of this being. - */ - virtual void setGender(Gender gender) { mGender = gender; } - - Gender getGender() const { return mGender; } - #ifdef EATHENA_SUPPORT /** * Makes this being take the next step of his path. @@ -307,7 +249,7 @@ class Being : public Sprite, public ConfigListener /** * Returns the type of the being. */ - virtual Type getType() const; + virtual Type getType() const { return UNKNOWN; } /** * Sets the walk speed (in pixels per second). @@ -496,14 +438,14 @@ class Being : public Sprite, public ConfigListener internalTriggerEffect(effectId, false, true); } - static int getHairStyleCount(); - virtual AnimatedSprite *getSprite(int index) const { return mSprites[index]; } static void load(); - void optionChanged(const std::string &value) {} + virtual void optionChanged(const std::string &value) {} + + void flashName(int time); protected: /** @@ -512,9 +454,9 @@ class Being : public Sprite, public ConfigListener void setPath(const Path &path); /** - * Let the sub-classes react to a replacement. + * Updates name's location. */ - virtual void updateCoords() {} + virtual void updateCoords(); /** * Gets the way the object blocks pathfinding for other objects @@ -551,14 +493,23 @@ class Being : public Sprite, public ConfigListener */ virtual void handleStatusEffect(StatusEffect *effect, int effectId); + virtual void showName(); + int mId; /**< Unique sprite id */ Uint8 mDirection; /**< Facing direction */ Uint8 mSpriteDirection; /**< Facing direction */ Map *mMap; /**< Map on which this being resides */ std::string mName; /**< Name of character */ - SpriteIterator mSpriteIterator; + MapSprite mMapSprite; bool mParticleEffects; /**< Whether to display particles or not */ + /** + * Holds a text object when the being displays it's name, 0 otherwise + */ + FlashText *mDispName; + const gcn::Color *mNameColor; + bool mShowName; + /** Engine-related infos about weapon. */ const ItemInfo *mEquippedWeapon; @@ -567,17 +518,14 @@ class Being : public Sprite, public ConfigListener Path mPath; std::string mSpeech; Text *mText; - int mHairStyle; - int mHairColor; - Gender mGender; + const gcn::Color *mTextColor; Uint16 mStunMode; /**< Stun mode; zero if not stunned */ std::set mStatusEffects; /**< set of active status effects */ - const gcn::Color *mNameColor; - - std::vector mSprites; - std::vector mSpriteIDs; - std::vector mSpriteColors; + typedef std::vector Sprites; + typedef Sprites::iterator SpriteIterator; + typedef Sprites::const_iterator SpriteConstIterator; + Sprites mSprites; ParticleList mStunParticleEffects; ParticleVector mStatusParticleEffects; ParticleList mChildParticleEffects; diff --git a/src/flooritem.cpp b/src/flooritem.cpp index b08258c1..9376dd73 100644 --- a/src/flooritem.cpp +++ b/src/flooritem.cpp @@ -41,13 +41,13 @@ FloorItem::FloorItem(int id, mItem = new Item(itemId); // Add ourselves to the map - mSpriteIterator = mMap->addSprite(this); + mMapSprite = mMap->addSprite(this); } FloorItem::~FloorItem() { // Remove ourselves from the map - mMap->removeSprite(mSpriteIterator); + mMap->removeSprite(mMapSprite); delete mItem; } diff --git a/src/flooritem.h b/src/flooritem.h index 99074943..61e88a70 100644 --- a/src/flooritem.h +++ b/src/flooritem.h @@ -24,14 +24,12 @@ #include +#include "map.h" #include "sprite.h" class Graphics; class Image; class Item; -class Map; - -typedef std::list Sprites; /** * An item lying on the floor. @@ -100,7 +98,7 @@ class FloorItem : public Sprite int mId; int mX, mY; Item *mItem; - Sprites::iterator mSpriteIterator; + MapSprite mMapSprite; Map *mMap; }; diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp index e09eee55..7c2b0ed9 100644 --- a/src/gui/charcreatedialog.cpp +++ b/src/gui/charcreatedialog.cpp @@ -59,8 +59,9 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot): int numberOfHairColors = ColorDB::size(); - mPlayer->setHairStyle(rand() % mPlayer->getNumOfHairstyles(), - rand() % numberOfHairColors); + mHairStyle = rand() % mPlayer->getNumOfHairstyles(); + mHairColor = rand() % numberOfHairColors; + updateHair(); mNameField = new TextField(""); mNameLabel = new Label(_("Name:")); @@ -153,7 +154,6 @@ CharCreateDialog::~CharCreateDialog() void CharCreateDialog::action(const gcn::ActionEvent &event) { - int numberOfColors = ColorDB::size(); if (event.getId() == "create") { if (getName().length() >= 4) @@ -168,8 +168,8 @@ void CharCreateDialog::action(const gcn::ActionEvent &event) } Net::getCharHandler()->newCharacter(getName(), mSlot, - mFemale->isSelected(), mPlayer->getHairStyle(), - mPlayer->getHairColor(), atts); + mFemale->isSelected(), mHairStyle, + mHairColor, atts); } else { @@ -181,19 +181,25 @@ void CharCreateDialog::action(const gcn::ActionEvent &event) else if (event.getId() == "cancel") scheduleDelete(); else if (event.getId() == "nextcolor") - mPlayer->setHairStyle(mPlayer->getHairStyle(), - (mPlayer->getHairColor() + 1) % numberOfColors); + { + mHairColor++; + updateHair(); + } else if (event.getId() == "prevcolor") - mPlayer->setHairStyle(mPlayer->getHairStyle(), - (mPlayer->getHairColor() + numberOfColors - 1) % - numberOfColors); + { + mHairColor--; + updateHair(); + } else if (event.getId() == "nextstyle") - mPlayer->setHairStyle(mPlayer->getHairStyle() + 1, - mPlayer->getHairColor()); + { + mHairStyle++; + updateHair(); + } else if (event.getId() == "prevstyle") - mPlayer->setHairStyle(mPlayer->getHairStyle() + - mPlayer->getNumOfHairstyles() - 1, - mPlayer->getHairColor()); + { + mHairStyle--; + updateHair(); + } else if (event.getId() == "statslider") { updateSliders(); } @@ -334,3 +340,13 @@ void CharCreateDialog::setFixedGender(bool fixed, Gender gender) mFemale->setEnabled(false); } } + +void CharCreateDialog::updateHair() +{ + mHairStyle %= Being::getNumOfHairstyles(); + + mHairColor %= ColorDB::size(); + + mPlayer->setSprite(Player::HAIR_SPRITE, + mHairStyle * -1, ColorDB::get(mHairColor)); +} diff --git a/src/gui/charcreatedialog.h b/src/gui/charcreatedialog.h index 5dbc6050..a30aadd3 100644 --- a/src/gui/charcreatedialog.h +++ b/src/gui/charcreatedialog.h @@ -22,7 +22,7 @@ #ifndef CHAR_CREATE_H #define CHAR_CREATE_H -#include "being.h" +#include "player.h" #include "guichanfwd.h" #include "lockedarray.h" @@ -34,7 +34,6 @@ #include class LocalPlayer; -class Player; class PlayerBox; /** @@ -82,6 +81,8 @@ class CharCreateDialog : public Window, public gcn::ActionListener */ void attemptCharCreate(); + void updateHair(); + gcn::TextField *mNameField; gcn::Label *mNameLabel; gcn::Button *mNextHairColorButton; @@ -108,6 +109,9 @@ class CharCreateDialog : public Window, public gcn::ActionListener Player *mPlayer; PlayerBox *mPlayerBox; + int mHairStyle; + int mHairColor; + int mSlot; }; diff --git a/src/gui/charselectdialog.h b/src/gui/charselectdialog.h index 06ce4b55..4427017e 100644 --- a/src/gui/charselectdialog.h +++ b/src/gui/charselectdialog.h @@ -24,7 +24,7 @@ #include "gui/widgets/window.h" -#include "being.h" +#include "player.h" #include "guichanfwd.h" #include "lockedarray.h" @@ -32,7 +32,6 @@ class LocalPlayer; class LoginData; -class Player; class PlayerBox; /** diff --git a/src/gui/playerbox.cpp b/src/gui/playerbox.cpp index d00194bd..9a1f4805 100644 --- a/src/gui/playerbox.cpp +++ b/src/gui/playerbox.cpp @@ -82,11 +82,11 @@ void PlayerBox::draw(gcn::Graphics *graphics) { // Draw character const int bs = getFrameSize(); -#ifdef TMWSERV_SUPPORT +//#ifdef TMWSERV_SUPPORT const int x = getWidth() / 2 + bs; const int y = getHeight() - bs - 8; mPlayer->draw(static_cast(graphics), x, y); -#else +/*#else const int x = getWidth() / 2 - 16 + bs; const int y = getHeight() / 2 + bs; for (int i = 0; i < Being::VECTOREND_SPRITE; i++) @@ -96,7 +96,7 @@ void PlayerBox::draw(gcn::Graphics *graphics) mPlayer->getSprite(i)->draw(static_cast(graphics), x, y); } } -#endif +#endif*/ } if (config.getValue("guialpha", 0.8) != mAlpha) diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 57dc8981..8fbfe70a 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -118,7 +118,12 @@ LocalPlayer::LocalPlayer(int id, int job, Map *map): mUpdateName = true; + mTextColor = &guiPalette->getColor(Palette::PLAYER); + mNameColor = &guiPalette->getColor(Palette::SELF); + initTargetCursor(); + + config.addListener("showownname", this); } LocalPlayer::~LocalPlayer() @@ -241,20 +246,6 @@ void LocalPlayer::setGMLevel(int level) setGM(true); } -void LocalPlayer::setName(const std::string &name) -{ - if (mName) - { - delete mName; - mName = 0; - } - - if (config.getValue("showownname", false) && mMapInitialized) - Player::setName(name); - else - Being::setName(name); -} - void LocalPlayer::nextStep() { // TODO: Fix picking up when reaching target (this method is obsolete) @@ -1087,3 +1078,11 @@ void LocalPlayer::addMessageToQueue(const std::string &message, { mMessages.push_back(MessagePair(message, color)); } + +void LocalPlayer::optionChanged(const std::string &value) +{ + if (value == "showownname") + { + setShowName(config.getValue("showownname", 1)); + } +} diff --git a/src/localplayer.h b/src/localplayer.h index fa0b8984..ff26e701 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -109,8 +109,6 @@ class LocalPlayer : public Player */ ~LocalPlayer(); - virtual void setName(const std::string &name); - virtual void logic(); virtual void setAction(Action action, int attackType = 0); @@ -361,9 +359,17 @@ class LocalPlayer : public Player void addMessageToQueue(const std::string &message, Palette::ColorType color = Palette::EXP_INFO); + /** + * Called when a option (set with config.addListener()) is changed + */ + void optionChanged(const std::string &value); + protected: virtual void handleStatusEffect(StatusEffect *effect, int effectId); + // Colors don't change for local player + virtual void updateColors() {} + void walk(unsigned char dir); bool mInStorage; /**< Whether storage is currently accessible */ diff --git a/src/map.cpp b/src/map.cpp index dbecda3d..5f6433c2 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -123,7 +123,7 @@ Image* MapLayer::getTile(int x, int y) const void MapLayer::draw(Graphics *graphics, int startX, int startY, int endX, int endY, int scrollX, int scrollY, - const Sprites &sprites) const + const MapSprites &sprites) const { startX -= mX; startY -= mY; @@ -135,7 +135,7 @@ void MapLayer::draw(Graphics *graphics, int startX, int startY, if (endX > mWidth) endX = mWidth; if (endY > mHeight) endY = mHeight; - Sprites::const_iterator si = sprites.begin(); + MapSprites::const_iterator si = sprites.begin(); for (int y = startY; y < endY; y++) { @@ -467,13 +467,13 @@ MetaTile *Map::getMetaTile(int x, int y) const return &mMetaTiles[x + y * mWidth]; } -SpriteIterator Map::addSprite(Sprite *sprite) +MapSprite Map::addSprite(Sprite *sprite) { mSprites.push_front(sprite); return mSprites.begin(); } -void Map::removeSprite(SpriteIterator iterator) +void Map::removeSprite(MapSprite iterator) { mSprites.erase(iterator); } diff --git a/src/map.h b/src/map.h index 6baf7411..9c04f354 100644 --- a/src/map.h +++ b/src/map.h @@ -39,8 +39,8 @@ class Sprite; class Tileset; typedef std::vector Tilesets; -typedef std::list Sprites; -typedef Sprites::iterator SpriteIterator; +typedef std::list MapSprites; +typedef MapSprites::iterator MapSprite; typedef std::vector Layers; /** @@ -128,7 +128,7 @@ class MapLayer int startX, int startY, int endX, int endY, int scrollX, int scrollY, - const Sprites &sprites) const; + const MapSprites &sprites) const; private: int mX, mY; @@ -266,12 +266,12 @@ class Map : public Properties /** * Adds a sprite to the map. */ - SpriteIterator addSprite(Sprite *sprite); + MapSprite addSprite(Sprite *sprite); /** * Removes a sprite from the map. */ - void removeSprite(SpriteIterator iterator); + void removeSprite(MapSprite iterator); /** * Adds a particle effect @@ -317,7 +317,7 @@ class Map : public Properties MetaTile *mMetaTiles; Layers mLayers; Tilesets mTilesets; - Sprites mSprites; + MapSprites mSprites; // Pathfinding members int mOnClosedList, mOnOpenList; diff --git a/src/monster.cpp b/src/monster.cpp index 3bdf1a62..cc2285fe 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -33,29 +33,24 @@ #include "resources/monsterinfo.h" Monster::Monster(int id, int job, Map *map): - Being(id, job, map), - mText(0) + Being(id, job, map) { const MonsterInfo& info = getInfo(); // Setup Monster sprites - int c = BASE_SPRITE; const std::list &sprites = info.getSprites(); for (std::list::const_iterator i = sprites.begin(); i != sprites.end(); i++) { - if (c == VECTOREND_SPRITE) break; - std::string file = "graphics/sprites/" + *i; - mSprites[c] = AnimatedSprite::load(file); - c++; + mSprites.push_back(AnimatedSprite::load(file)); } // Ensure that something is shown - if (c == BASE_SPRITE) + if (mSprites.size() == 0) { - mSprites[c] = AnimatedSprite::load("graphics/sprites/error.xml"); + mSprites.push_back(AnimatedSprite::load("graphics/sprites/error.xml")); } if (mParticleEffects) @@ -69,15 +64,11 @@ Monster::Monster(int id, int job, Map *map): } mNameColor = &guiPalette->getColor(Palette::MONSTER); + mTextColor = &guiPalette->getColor(Palette::MONSTER); Being::setName(getInfo().getName()); } -Monster::~Monster() -{ - delete mText; -} - #ifdef EATHENA_SUPPORT void Monster::logic() { @@ -93,11 +84,6 @@ void Monster::logic() } #endif -Being::Type Monster::getType() const -{ - return MONSTER; -} - void Monster::setAction(Action action, int attackType) { SpriteAction currentAction = ACTION_INVALID; @@ -115,7 +101,8 @@ void Monster::setAction(Action action, int attackType) break; case ATTACK: currentAction = getInfo().getAttackAction(attackType); - mSprites[BASE_SPRITE]->reset(); + for (SpriteIterator it = mSprites.begin(); it != mSprites.end(); it++) + (*it)->reset(); //attack particle effect particleEffect = getInfo().getAttackParticleEffect(attackType); @@ -147,11 +134,9 @@ void Monster::setAction(Action action, int attackType) if (currentAction != ACTION_INVALID) { - for (int i = 0; i < VECTOREND_SPRITE; i++) - { - if (mSprites[i]) - mSprites[i]->play(currentAction); - } + for (SpriteIterator it = mSprites.begin(); it != mSprites.end(); it++) + if (*it) + (*it)->play(currentAction); mAction = action; } } @@ -183,29 +168,18 @@ const MonsterInfo &Monster::getInfo() const return MonsterDB::get(mJob); } -void Monster::setShowName(bool show) +void Monster::updateCoords() { - delete mText; - - if (show) - { - mText = new Text(getInfo().getName(), - getPixelX(), - getPixelY() - getHeight(), - gcn::Graphics::CENTER, - &guiPalette->getColor(Palette::MONSTER)); - } - else + if (mDispName) { - mText = 0; + mDispName->adviseXY(getPixelX(), + getPixelY() - getHeight() - mDispName->getHeight()); } } -void Monster::updateCoords() +void Monster::showName() { - if (mText) - { - mText->adviseXY(getPixelX(), - getPixelY() - getHeight() - mText->getHeight()); - } + Being::showName(); + + updateCoords(); } diff --git a/src/monster.h b/src/monster.h index 29b04eab..1cfb8e93 100644 --- a/src/monster.h +++ b/src/monster.h @@ -32,15 +32,13 @@ class Monster : public Being public: Monster(int id, int job, Map *map); - ~Monster(); - #ifdef EATHENA_SUPPORT virtual void logic(); #endif virtual void setAction(Action action, int attackType = 0); - virtual Type getType() const; + virtual Type getType() const { return MONSTER; } virtual TargetCursorSize getTargetCursorSize() const; @@ -69,11 +67,6 @@ class Monster : public Being */ const MonsterInfo& getInfo() const; - /** - * Determine whether the mob should show it's name - */ - void setShowName(bool show); - /** * Gets the way the monster is blocked by other objects */ @@ -96,11 +89,7 @@ class Monster : public Being */ void updateCoords(); - private: - /** - * holds a text object when the mod displays it's name, 0 otherwise - */ - Text *mText; + void showName(); }; #endif diff --git a/src/net/ea/beinghandler.cpp b/src/net/ea/beinghandler.cpp index 1d780a60..96c5986b 100644 --- a/src/net/ea/beinghandler.cpp +++ b/src/net/ea/beinghandler.cpp @@ -37,6 +37,8 @@ #include "gui/partywindow.h" +#include "resources/colordb.h" + #include namespace EAthena { @@ -98,7 +100,7 @@ Being *createBeing(int id, short job) void BeingHandler::handleMessage(MessageIn &msg) { int id; - short job, speed; + short job, speed, gender; Uint16 headTop, headMid, headBottom; Uint16 shoes, gloves; Uint16 weapon, shield; @@ -109,6 +111,7 @@ void BeingHandler::handleMessage(MessageIn &msg) int type; Uint16 status; Being *srcBeing, *dstBeing; + Player *player; int hairStyle, hairColor, flag; switch (msg.getId()) @@ -137,6 +140,8 @@ void BeingHandler::handleMessage(MessageIn &msg) dstBeing = createBeing(id, job); } + player = dynamic_cast(dstBeing); + // Fix monster jobs if (dstBeing->getType() == Being::MONSTER) { @@ -158,7 +163,7 @@ void BeingHandler::handleMessage(MessageIn &msg) dstBeing->setWalkSpeed(speed); dstBeing->mJob = job; hairStyle = msg.readInt16(); - dstBeing->setSprite(Being::WEAPON_SPRITE, msg.readInt16()); + weapon = msg.readInt16(); headBottom = msg.readInt16(); if (msg.getId() == SMSG_BEING_MOVE) @@ -166,7 +171,7 @@ void BeingHandler::handleMessage(MessageIn &msg) msg.readInt32(); // server tick } - dstBeing->setSprite(Being::SHIELD_SPRITE, msg.readInt16()); + shield = msg.readInt16(); headTop = msg.readInt16(); headMid = msg.readInt16(); hairColor = msg.readInt16(); @@ -178,16 +183,22 @@ void BeingHandler::handleMessage(MessageIn &msg) msg.readInt16(); // manner dstBeing->setStatusEffectBlock(32, msg.readInt16()); // opt3 msg.readInt8(); // karma - dstBeing->setGender( - (msg.readInt8() == 0) ? GENDER_FEMALE : GENDER_MALE); + gender = msg.readInt8(); - // Set these after the gender, as the sprites may be gender-specific - dstBeing->setSprite(Being::BOTTOMCLOTHES_SPRITE, headBottom); - dstBeing->setSprite(Being::TOPCLOTHES_SPRITE, headMid); - dstBeing->setSprite(Being::HAT_SPRITE, headTop); - dstBeing->setSprite(Being::SHOE_SPRITE, shoes); - dstBeing->setSprite(Being::GLOVES_SPRITE, gloves); - dstBeing->setHairStyle(hairStyle, hairColor); + if (player) + { + player->setGender((gender == 0) + ? GENDER_FEMALE : GENDER_MALE); + // Set these after the gender, as the sprites may be gender-specific + player->setSprite(Player::HAIR_SPRITE, hairStyle * -1, ColorDB::get(hairColor)); + player->setSprite(Player::BOTTOMCLOTHES_SPRITE, headBottom); + player->setSprite(Player::TOPCLOTHES_SPRITE, headMid); + player->setSprite(Player::HAT_SPRITE, headTop); + player->setSprite(Player::SHOE_SPRITE, shoes); + player->setSprite(Player::GLOVES_SPRITE, gloves); + player->setSprite(Player::WEAPON_SPRITE, weapon); + player->setSprite(Player::SHIELD_SPRITE, shield); + } if (msg.getId() == SMSG_BEING_MOVE) { @@ -371,6 +382,8 @@ void BeingHandler::handleMessage(MessageIn &msg) break; } + player = dynamic_cast(dstBeing); + int type = msg.readInt8(); int id = 0; int id2 = 0; @@ -384,41 +397,42 @@ void BeingHandler::handleMessage(MessageIn &msg) switch (type) { case 1: // eAthena LOOK_HAIR - dstBeing->setHairStyle(id, -1); + player->setSprite(Player::HAIR_SPRITE, id * -1, + ColorDB::get(id2)); break; case 2: // Weapon ID in id, Shield ID in id2 - dstBeing->setSprite(Being::WEAPON_SPRITE, id); - dstBeing->setSprite(Being::SHIELD_SPRITE, id2); + player->setSprite(Player::WEAPON_SPRITE, id); + player->setSprite(Player::SHIELD_SPRITE, id2); break; case 3: // Change lower headgear for eAthena, pants for us - dstBeing->setSprite(Being::BOTTOMCLOTHES_SPRITE, id); + player->setSprite(Player::BOTTOMCLOTHES_SPRITE, id); break; case 4: // Change upper headgear for eAthena, hat for us - dstBeing->setSprite(Being::HAT_SPRITE, id); + player->setSprite(Player::HAT_SPRITE, id); break; case 5: // Change middle headgear for eathena, armor for us - dstBeing->setSprite(Being::TOPCLOTHES_SPRITE, id); + player->setSprite(Player::TOPCLOTHES_SPRITE, id); break; case 6: // eAthena LOOK_HAIR_COLOR - dstBeing->setHairStyle(-1, id); + // ignored (duplicate of LOOK_HAIR) break; case 8: // eAthena LOOK_SHIELD - dstBeing->setSprite(Being::SHIELD_SPRITE, id); + player->setSprite(Player::SHIELD_SPRITE, id); break; case 9: // eAthena LOOK_SHOES - dstBeing->setSprite(Being::SHOE_SPRITE, id); + player->setSprite(Player::SHOE_SPRITE, id); break; case 10: // LOOK_GLOVES - dstBeing->setSprite(Being::GLOVES_SPRITE, id); + player->setSprite(Player::GLOVES_SPRITE, id); break; case 11: // LOOK_CAPE - dstBeing->setSprite(Being::CAPE_SPRITE, id); + player->setSprite(Player::CAPE_SPRITE, id); break; case 12: - dstBeing->setSprite(Being::MISC1_SPRITE, id); + player->setSprite(Player::MISC1_SPRITE, id); break; case 13: - dstBeing->setSprite(Being::MISC2_SPRITE, id); + player->setSprite(Player::MISC2_SPRITE, id); break; default: logger->log("SMSG_BEING_CHANGE_LOOKS: unsupported type: " @@ -466,15 +480,16 @@ void BeingHandler::handleMessage(MessageIn &msg) dstBeing = createBeing(id, job); } + player = dynamic_cast(dstBeing); + { PartyMember *member = partyWindow->findMember(id); if (member && member->online) { - dynamic_cast(dstBeing)->setInParty(true); + player->setInParty(true); } } - dstBeing->setWalkSpeed(speed); dstBeing->mJob = job; hairStyle = msg.readInt16(); @@ -497,19 +512,19 @@ void BeingHandler::handleMessage(MessageIn &msg) msg.readInt16(); // manner dstBeing->setStatusEffectBlock(32, msg.readInt16()); // opt3 msg.readInt8(); // karma - dstBeing->setGender( - (msg.readInt8() == 0) ? GENDER_FEMALE : GENDER_MALE); + player->setGender((msg.readInt8() == 0) + ? GENDER_FEMALE : GENDER_MALE); // Set these after the gender, as the sprites may be gender-specific - dstBeing->setSprite(Being::WEAPON_SPRITE, weapon); - dstBeing->setSprite(Being::SHIELD_SPRITE, shield); - dstBeing->setSprite(Being::BOTTOMCLOTHES_SPRITE, headBottom); - dstBeing->setSprite(Being::TOPCLOTHES_SPRITE, headMid); - dstBeing->setSprite(Being::HAT_SPRITE, headTop); - //dstBeing->setSprite(Being::CAPE_SPRITE, cape); - //dstBeing->setSprite(Being::MISC1_SPRITE, misc1); - //dstBeing->setSprite(Being::MISC2_SPRITE, misc2); - dstBeing->setHairStyle(hairStyle, hairColor); + player->setSprite(Player::WEAPON_SPRITE, weapon); + player->setSprite(Player::SHIELD_SPRITE, shield); + player->setSprite(Player::BOTTOMCLOTHES_SPRITE, headBottom); + player->setSprite(Player::TOPCLOTHES_SPRITE, headMid); + player->setSprite(Player::HAT_SPRITE, headTop); + //player->setSprite(Player::CAPE_SPRITE, cape); + //player->setSprite(Player::MISC1_SPRITE, misc1); + //player->setSprite(Player::MISC2_SPRITE, misc2); + player->setSprite(Player::HAIR_SPRITE, hairStyle * -1, ColorDB::get(hairColor)); if (msg.getId() == SMSG_PLAYER_MOVE) { diff --git a/src/net/ea/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp index 6fae1864..47d454a8 100644 --- a/src/net/ea/charserverhandler.cpp +++ b/src/net/ea/charserverhandler.cpp @@ -35,6 +35,8 @@ #include "gui/charcreatedialog.h" #include "gui/okdialog.h" +#include "resources/colordb.h" + #include "utils/gettext.h" #include "utils/stringutils.h" @@ -176,10 +178,10 @@ LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot) int temp = msg.readInt32(); tempPlayer->setAttributeBase(JOB, temp); tempPlayer->setAttributeEffective(JOB, temp); - tempPlayer->setSprite(Being::SHOE_SPRITE, msg.readInt16()); - tempPlayer->setSprite(Being::GLOVES_SPRITE, msg.readInt16()); - tempPlayer->setSprite(Being::CAPE_SPRITE, msg.readInt16()); - tempPlayer->setSprite(Being::MISC1_SPRITE, msg.readInt16()); + tempPlayer->setSprite(Player::SHOE_SPRITE, msg.readInt16()); + tempPlayer->setSprite(Player::GLOVES_SPRITE, msg.readInt16()); + tempPlayer->setSprite(Player::CAPE_SPRITE, msg.readInt16()); + tempPlayer->setSprite(Player::MISC1_SPRITE, msg.readInt16()); msg.readInt32(); // option msg.readInt32(); // karma msg.readInt32(); // manner @@ -192,16 +194,15 @@ LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot) msg.readInt16(); // class int hairStyle = msg.readInt16(); Uint16 weapon = msg.readInt16(); - tempPlayer->setSprite(Being::WEAPON_SPRITE, weapon); + tempPlayer->setSprite(Player::WEAPON_SPRITE, weapon); tempPlayer->setLevel(msg.readInt16()); msg.readInt16(); // skill point - tempPlayer->setSprite(Being::BOTTOMCLOTHES_SPRITE, msg.readInt16()); // head bottom - tempPlayer->setSprite(Being::SHIELD_SPRITE, msg.readInt16()); - tempPlayer->setSprite(Being::HAT_SPRITE, msg.readInt16()); // head option top - tempPlayer->setSprite(Being::TOPCLOTHES_SPRITE, msg.readInt16()); // head option mid - int hairColor = msg.readInt16(); - tempPlayer->setHairStyle(hairStyle, hairColor); - tempPlayer->setSprite(Being::MISC2_SPRITE, msg.readInt16()); + tempPlayer->setSprite(Player::BOTTOMCLOTHES_SPRITE, msg.readInt16()); // head bottom + tempPlayer->setSprite(Player::SHIELD_SPRITE, msg.readInt16()); + tempPlayer->setSprite(Player::HAT_SPRITE, msg.readInt16()); // head option top + tempPlayer->setSprite(Player::TOPCLOTHES_SPRITE, msg.readInt16()); // head option mid + tempPlayer->setSprite(Player::HAIR_SPRITE, hairStyle * -1, ColorDB::get(msg.readInt16())); + tempPlayer->setSprite(Player::MISC2_SPRITE, msg.readInt16()); tempPlayer->setName(msg.readString(24)); for (int i = 0; i < 6; i++) { tempPlayer->setAttributeBase(i + STR, msg.readInt8()); diff --git a/src/net/ea/partyhandler.cpp b/src/net/ea/partyhandler.cpp index a4a84b07..f514c3b6 100644 --- a/src/net/ea/partyhandler.cpp +++ b/src/net/ea/partyhandler.cpp @@ -139,7 +139,6 @@ void PartyHandler::handleMessage(MessageIn &msg) break; } std::string nick; - int gender = 0; std::string partyName = ""; if (being->getType() != Being::PLAYER) { @@ -148,7 +147,6 @@ void PartyHandler::handleMessage(MessageIn &msg) else { nick = being->getName(); - gender = being->getGender(); partyName = msg.readString(24); } partyWindow->showPartyInvite(nick, partyName); diff --git a/src/net/logindata.h b/src/net/logindata.h index 4cf989cb..db7aafff 100644 --- a/src/net/logindata.h +++ b/src/net/logindata.h @@ -24,7 +24,7 @@ #include -#include "being.h" +#include "player.h" struct LoginData { diff --git a/src/net/tmwserv/beinghandler.cpp b/src/net/tmwserv/beinghandler.cpp index acd6b62c..d5092782 100644 --- a/src/net/tmwserv/beinghandler.cpp +++ b/src/net/tmwserv/beinghandler.cpp @@ -37,6 +37,8 @@ #include "gui/okdialog.h" +#include "resources/colordb.h" + #include "utils/gettext.h" #include "net/tmwserv/gameserver/player.h" @@ -95,8 +97,8 @@ static void handleLooks(Player *being, MessageIn &msg) // Order of sent slots. Has to be in sync with the server code. static int const nb_slots = 4; static int const slots[nb_slots] = - { Being::WEAPON_SPRITE, Being::HAT_SPRITE, Being::TOPCLOTHES_SPRITE, - Being::BOTTOMCLOTHES_SPRITE }; + { Player::WEAPON_SPRITE, Player::HAT_SPRITE, Player::TOPCLOTHES_SPRITE, + Player::BOTTOMCLOTHES_SPRITE }; int mask = msg.readInt8(); @@ -144,7 +146,7 @@ void BeingHandler::handleBeingEnterMessage(MessageIn &msg) } Player *p = static_cast< Player * >(being); int hs = msg.readInt8(), hc = msg.readInt8(); - p->setHairStyle(hs, hc); + p->setSprite(Player::HAIR_SPRITE, hs * -1, ColorDB::get(hc)); p->setGender(msg.readInt8() == GENDER_MALE ? GENDER_MALE : GENDER_FEMALE); handleLooks(p, msg); @@ -304,8 +306,7 @@ void BeingHandler::handleBeingLooksChangeMessage(MessageIn &msg) { int style = msg.readInt16(); int color = msg.readInt16(); - player->setHairStyle(style, color); - player->setGender((Gender)msg.readInt16()); + player->setSprite(Player::HAIR_SPRITE, style * -1, ColorDB::get(color)); } } diff --git a/src/net/tmwserv/charserverhandler.cpp b/src/net/tmwserv/charserverhandler.cpp index 0146babb..93181a93 100644 --- a/src/net/tmwserv/charserverhandler.cpp +++ b/src/net/tmwserv/charserverhandler.cpp @@ -38,6 +38,8 @@ #include "gui/charcreatedialog.h" #include "gui/okdialog.h" +#include "resources/colordb.h" + #include "utils/gettext.h" extern Net::Connection *gameServerConnection; @@ -229,7 +231,7 @@ LocalPlayer* CharServerHandler::readPlayerData(MessageIn &msg, int &slot) tempPlayer->setName(msg.readString()); tempPlayer->setGender(msg.readInt8() == GENDER_MALE ? GENDER_MALE : GENDER_FEMALE); int hs = msg.readInt8(), hc = msg.readInt8(); - tempPlayer->setHairStyle(hs, hc); + tempPlayer->setSprite(Player::HAIR_SPRITE, hs * -1, ColorDB::get(hc)); tempPlayer->setLevel(msg.readInt16()); tempPlayer->setCharacterPoints(msg.readInt16()); tempPlayer->setCorrectionPoints(msg.readInt16()); diff --git a/src/npc.cpp b/src/npc.cpp index f7172d4b..dbae24e4 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -41,18 +41,13 @@ NPC::NPC(int id, int job, Map *map): NPCInfo info = NPCDB::get(job); // Setup NPC sprites - int c = BASE_SPRITE; for (std::list::const_iterator i = info.sprites.begin(); i != info.sprites.end(); i++) { - if (c == VECTOREND_SPRITE) - break; - std::string file = "graphics/sprites/" + (*i)->sprite; int variant = (*i)->variant; - mSprites[c] = AnimatedSprite::load(file, variant); - c++; + mSprites.push_back(AnimatedSprite::load(file, variant)); } if (mParticleEffects) @@ -66,32 +61,15 @@ NPC::NPC(int id, int job, Map *map): this->controlParticle(p); } } - mName = 0; - - mNameColor = &guiPalette->getColor(Palette::NPC); -} -NPC::~NPC() -{ - delete mName; + setShowName(true); } void NPC::setName(const std::string &name) { const std::string displayName = name.substr(0, name.find('#', 0)); - delete mName; - mName = new Text(displayName, - getPixelX(), - getPixelY(), - gcn::Graphics::CENTER, - &guiPalette->getColor(Palette::NPC)); - Being::setName(displayName + " (NPC)"); -} - -Being::Type NPC::getType() const -{ - return Being::NPC; + Being::setName(displayName); } void NPC::talk() @@ -103,11 +81,3 @@ void NPC::talk() Net::getNpcHandler()->talk(mId); } - -void NPC::updateCoords() -{ - if (mName) - { - mName->adviseXY(getPixelX(), getPixelY()); - } -} diff --git a/src/npc.h b/src/npc.h index 392ee8c5..5335d8cd 100644 --- a/src/npc.h +++ b/src/npc.h @@ -32,11 +32,9 @@ class NPC : public Being public: NPC(int id, int job, Map *map); - ~NPC(); - void setName(const std::string &name); - virtual Type getType() const; + virtual Type getType() const { return Being::NPC; } void talk(); @@ -58,11 +56,6 @@ class NPC : public Being */ virtual Map::BlockType getBlockType() const { return Map::BLOCKTYPE_CHARACTER; } //blocks like a player character - - void updateCoords(); - - private: - Text *mName; }; extern int current_npc; diff --git a/src/player.cpp b/src/player.cpp index fd7cd0d6..55888654 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -40,53 +40,23 @@ Player::Player(int id, int job, Map *map): Being(id, job, map), - mName(0), + mGender(GENDER_UNSPECIFIED), + mSpriteIDs(VECTOREND_SPRITE, 0), + mSpriteColors(VECTOREND_SPRITE, ""), mIsGM(false), mInParty(false) { + for (int i = 0; i < VECTOREND_SPRITE; i++) + mSprites.push_back(NULL); mShowName = config.getValue("visiblenames", 1); config.addListener("visiblenames", this); + + updateColors(); } Player::~Player() { config.removeListener("visiblenames", this); - delete mName; -} - -void Player::setName(const std::string &name) -{ - if (!mName && mShowName) - { - mNameColor = &guiPalette->getColor(Palette::PLAYER); - - const gcn::Color *color; - if (this == player_node) - { - color = &guiPalette->getColor(Palette::SELF); - } - else if (mIsGM) - { - mNameColor = &guiPalette->getColor(Palette::GM); - color = &guiPalette->getColor(Palette::GM_NAME); - } - else if (mInParty) - { - color = &guiPalette->getColor(Palette::PARTY); - } - else - { - color = &guiPalette->getColor(Palette::PC); - } - - mName = new FlashText(name, - getPixelX(), - getPixelY(), - gcn::Graphics::CENTER, - color); - } - - Being::setName(name); } #ifdef EATHENA_SUPPORT @@ -149,31 +119,20 @@ void Player::logic() } #endif -Being::Type Player::getType() const -{ - return PLAYER; -} - -void Player::flash(int time) -{ - if (mName) - mName->flash(time); -} - void Player::setGender(Gender gender) { if (gender != mGender) { - Being::setGender(gender); + mGender = gender; /* Human base sprite. When implementing different races remove this * line and set the base sprite when setting the race of the player * character. */ - setSprite(Being::BASE_SPRITE, -100); + setSprite(BASE_SPRITE, -100); // Reload all subsprites - for (int i = 1; i < VECTOREND_SPRITE; i++) + for (unsigned int i = 1; i < mSprites.size(); i++) { if (mSpriteIDs.at(i) != 0) setSprite(i, mSpriteIDs.at(i), mSpriteColors.at(i)); @@ -185,28 +144,12 @@ void Player::setGM(bool gm) { mIsGM = gm; - if (gm && mName) - mName->setColor(&guiPalette->getColor(Palette::GM)); -} - -void Player::setHairStyle(int style, int color) -{ - style = style < 0 ? mHairStyle : style % mNumberOfHairstyles; - color = color < 0 ? mHairColor : color % ColorDB::size(); - if (style == mHairStyle && color == mHairColor) return; - - Being::setHairStyle(style, color); - - setSprite(HAIR_SPRITE, style * -1, ColorDB::get(color)); - - setAction(mAction); + updateColors(); } void Player::setSprite(int slot, int id, const std::string &color) { - // TODO: Find a better way - if (getType() == NPC) - return; + assert(slot >= BASE_SPRITE && slot < VECTOREND_SPRITE); // id = 0 means unequip if (id == 0) @@ -237,6 +180,7 @@ void Player::setSprite(int slot, int id, const std::string &color) equipmentSprite->setDirection(getSpriteDirection()); delete mSprites[slot]; + mSprites[slot] = equipmentSprite; if (slot == WEAPON_SPRITE) @@ -245,13 +189,8 @@ void Player::setSprite(int slot, int id, const std::string &color) setAction(mAction); } - Being::setSprite(slot, id, color); -} - -void Player::updateCoords() -{ - if (mName) - mName->adviseXY(getPixelX(), getPixelY()); + mSpriteIDs[slot] = id; + mSpriteColors[slot] = color; } #ifdef TMWSERV_SUPPORT @@ -305,26 +244,32 @@ void Player::setInParty(bool inParty) { mInParty = inParty; - if (this != player_node && mName) + updateColors(); +} + +void Player::optionChanged(const std::string &value) +{ + if (value == "visiblenames") { - Palette::ColorType colorType = mInParty ? Palette::PARTY : Palette::PC; - mName->setColor(&guiPalette->getColor(colorType)); + setShowName(config.getValue("visiblenames", 1)); } } -void Player::optionChanged(const std::string &value) +void Player::updateColors() { - if (value == "visiblenames" && getType() == Being::PLAYER && player_node != this) + mTextColor = &guiPalette->getColor(Palette::PLAYER); + + if (mIsGM) { - mShowName = config.getValue("visiblenames", 1); - if (!mShowName && mName) - { - delete mName; - mName = NULL; - } - else if (mShowName && !mName && !(getName().empty())) - { - setName(getName()); - } + mTextColor = &guiPalette->getColor(Palette::GM); + mNameColor = &guiPalette->getColor(Palette::GM_NAME); + } + else if (mInParty) + { + mNameColor = &guiPalette->getColor(Palette::PARTY); + } + else + { + mNameColor = &guiPalette->getColor(Palette::PC); } } diff --git a/src/player.h b/src/player.h index 9a5c6c94..36f0266e 100644 --- a/src/player.h +++ b/src/player.h @@ -24,13 +24,19 @@ #include "being.h" -class FlashText; class Graphics; class Map; #ifdef TMWSERV_SUPPORT class Guild; #endif +enum Gender +{ + GENDER_MALE = 0, + GENDER_FEMALE = 1, + GENDER_UNSPECIFIED = 2 +}; + /** * A player being. Players have their name drawn beneath them. This class also * implements player-specific loading of base sprite, hair sprite and equipment @@ -39,6 +45,29 @@ class Guild; class Player : public Being { public: + enum Sprite + { + BASE_SPRITE = 0, + SHOE_SPRITE, + BOTTOMCLOTHES_SPRITE, + TOPCLOTHES_SPRITE, +#ifdef EATHENA_SUPPORT + MISC1_SPRITE, + MISC2_SPRITE, +#endif + HAIR_SPRITE, + HAT_SPRITE, +#ifdef EATHENA_SUPPORT + CAPE_SPRITE, + GLOVES_SPRITE, +#endif + WEAPON_SPRITE, +#ifdef EATHENA_SUPPORT + SHIELD_SPRITE, +#endif + VECTOREND_SPRITE + }; + /** * Constructor. */ @@ -46,19 +75,19 @@ class Player : public Being ~Player(); - /** - * Set up mName to be the character's name - */ - virtual void setName(const std::string &name); - #ifdef EATHENA_SUPPORT virtual void logic(); #endif - virtual Type getType() const; + virtual Type getType() const { return PLAYER; } + /** + * Sets the gender of this being. + */ virtual void setGender(Gender gender); + Gender getGender() const { return mGender; } + /** * Whether or not this player is a GM. */ @@ -69,28 +98,11 @@ class Player : public Being */ virtual void setGM(bool gm); - /** - * Sets the hair style and color for this player. - * - * Only for convenience in 0.0 client. When porting - * this to the trunk remove this function and - * call setSprite directly instead. The server should - * provide the hair ID and coloring in the same way - * it does for other equipment pieces. - * - */ - void setHairStyle(int style, int color); - /** * Sets visible equipments for this player. */ virtual void setSprite(int slot, int id, const std::string &color = ""); - /** - * Flash the player's name - */ - void flash(int time); - #ifdef TMWSERV_SUPPORT /** * Adds a guild to the player. @@ -137,7 +149,7 @@ class Player : public Being /** * Called when a option (set with config.addListener()) is changed */ - void optionChanged(const std::string &value); + virtual void optionChanged(const std::string &value); protected: /** @@ -146,16 +158,17 @@ class Player : public Being virtual Map::BlockType getBlockType() const { return Map::BLOCKTYPE_CHARACTER; } - virtual void updateCoords(); + virtual void updateColors(); + + Gender mGender; + std::vector mSpriteIDs; + std::vector mSpriteColors; #ifdef TMWSERV_SUPPORT // Character guild information std::map mGuilds; #endif - bool mShowName; - FlashText *mName; - bool mIsGM; private: diff --git a/src/playerrelations.cpp b/src/playerrelations.cpp index 7bc1b14d..2825d114 100644 --- a/src/playerrelations.cpp +++ b/src/playerrelations.cpp @@ -329,7 +329,7 @@ public: virtual void ignore(Player *player, unsigned int flags) { - player->flash(200); + player->flashName(200); } }; diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h index 0c87b585..6c033490 100644 --- a/src/resources/iteminfo.h +++ b/src/resources/iteminfo.h @@ -24,7 +24,7 @@ #include "resources/spritedef.h" -#include "being.h" +#include "player.h" #include #include -- cgit v1.2.3-70-g09d2 From 75ba2b04b8af02ba2e005f701f1433e739ef7c5a Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Thu, 13 Aug 2009 19:23:25 -0600 Subject: Fix compile errors --- src/resources/image.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 1689aa1d..b08478b5 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -35,12 +35,12 @@ int Image::mTextureSize = 0; #endif Image::Image(SDL_Surface *image): -#ifdef USE_OPENGL - mGLImage(0), -#endif mAlpha(1.0f), mAlphaChannel(0), - mSDLSurface(image) + mSDLSurface(image), +#ifdef USE_OPENGL + mGLImage(0) +#endif { mBounds.x = 0; mBounds.y = 0; @@ -62,13 +62,13 @@ Image::Image(SDL_Surface *image): #ifdef USE_OPENGL Image::Image(GLuint glimage, int width, int height, int texWidth, int texHeight): - mGLImage(glimage), - mTexWidth(texWidth), - mTexHeight(texHeight), mAlpha(1.0), mHasAlphaChannel(true), mAlphaChannel(0), - mSDLSurface(0) + mSDLSurface(0), + mGLImage(glimage), + mTexWidth(texWidth), + mTexHeight(texHeight) { mBounds.x = 0; mBounds.y = 0; @@ -416,6 +416,8 @@ Uint8 *Image::_SDLgetAlphaChannel() mAlphaChannel[i] = a; } } + + return mAlphaChannel; } #ifdef USE_OPENGL -- cgit v1.2.3-70-g09d2 From afc879b5ca185cfd93e604942aac45e76dc3c322 Mon Sep 17 00:00:00 2001 From: Bertram Date: Fri, 14 Aug 2009 20:11:04 +0200 Subject: Fixed the compilation without OpenGL Support, and remove a too young function. --- src/resources/image.cpp | 41 +++++------------------------------------ src/resources/image.h | 8 -------- 2 files changed, 5 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/resources/image.cpp b/src/resources/image.cpp index b08478b5..a9005509 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -36,12 +36,12 @@ int Image::mTextureSize = 0; Image::Image(SDL_Surface *image): mAlpha(1.0f), - mAlphaChannel(0), - mSDLSurface(image), + mSDLSurface(image) +{ #ifdef USE_OPENGL - mGLImage(0) + mGLImage = 0; #endif -{ + mBounds.x = 0; mBounds.y = 0; @@ -64,7 +64,6 @@ Image::Image(SDL_Surface *image): Image::Image(GLuint glimage, int width, int height, int texWidth, int texHeight): mAlpha(1.0), mHasAlphaChannel(true), - mAlphaChannel(0), mSDLSurface(0), mGLImage(glimage), mTexWidth(texWidth), @@ -193,7 +192,7 @@ bool Image::isAnOpenGLOne() const bool Image::hasAlphaChannel() { if (mLoaded) - return mAlphaChannel; + return mHasAlphaChannel; #ifdef USE_OPENGL if (mUseOpenGL) @@ -390,36 +389,6 @@ Image *Image::_SDLload(SDL_Surface *tmpImage) return new Image(image); } -Uint8 *Image::_SDLgetAlphaChannel() -{ - if (!mSDLSurface) - return NULL; - - // If an old channel was stored, we free it. - free(mAlphaChannel); - mAlphaChannel = NULL; - - // We allocate the place to put our data - Uint8* mAlphaChannel = (Uint8*)malloc(mSDLSurface->w * mSDLSurface->h * sizeof(Uint8)); - - if (mSDLSurface->format->BitsPerPixel == 32) - { - // Figure out whether the image uses its alpha layer - for (int i = 0; i < mSDLSurface->w * mSDLSurface->h; ++i) - { - Uint8 r, g, b, a; - SDL_GetRGBA( - ((Uint32*) mSDLSurface->pixels)[i], - mSDLSurface->format, - &r, &g, &b, &a); - - mAlphaChannel[i] = a; - } - } - - return mAlphaChannel; -} - #ifdef USE_OPENGL Image *Image::_GLload(SDL_Surface *tmpImage) { diff --git a/src/resources/image.h b/src/resources/image.h index 34ec2887..dfa319ab 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -199,14 +199,6 @@ class Image : public Resource /** SDL_Surface to SDL_Surface Image loader */ static Image *_SDLload(SDL_Surface *tmpImage); - /** - * Make a converted copy of the alpha channel - * used for 32 bits SDLbased images - * in order to support changing the opacity. - */ - Uint8 *_SDLgetAlphaChannel(); - Uint8* mAlphaChannel; - SDL_Surface *mSDLSurface; -- cgit v1.2.3-70-g09d2 From 9d1fbb5a538b3c5a1ba7d5ab55f39033ddb880f1 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Fri, 14 Aug 2009 12:21:07 -0600 Subject: Add functions to more easily work with equipment Move hair changes back over to them; related server change was reverted. Also move NPCs back over to extending Player. NPCs will have equipment in the future too, but for now, disable that part while we finish the system. --- src/net/ea/beinghandler.cpp | 5 ++--- src/npc.cpp | 9 ++++++++- src/npc.h | 8 +++++++- src/player.cpp | 41 ++++++++++++++++++++++++++++------------- src/player.h | 10 ++++++++-- 5 files changed, 53 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/net/ea/beinghandler.cpp b/src/net/ea/beinghandler.cpp index 96c5986b..29c10900 100644 --- a/src/net/ea/beinghandler.cpp +++ b/src/net/ea/beinghandler.cpp @@ -397,8 +397,7 @@ void BeingHandler::handleMessage(MessageIn &msg) switch (type) { case 1: // eAthena LOOK_HAIR - player->setSprite(Player::HAIR_SPRITE, id * -1, - ColorDB::get(id2)); + player->setSpriteID(Player::HAIR_SPRITE, id *-1); break; case 2: // Weapon ID in id, Shield ID in id2 player->setSprite(Player::WEAPON_SPRITE, id); @@ -414,7 +413,7 @@ void BeingHandler::handleMessage(MessageIn &msg) player->setSprite(Player::TOPCLOTHES_SPRITE, id); break; case 6: // eAthena LOOK_HAIR_COLOR - // ignored (duplicate of LOOK_HAIR) + player->setSpriteColor(Player::HAIR_SPRITE, ColorDB::get(id)); break; case 8: // eAthena LOOK_SHIELD player->setSprite(Player::SHIELD_SPRITE, id); diff --git a/src/npc.cpp b/src/npc.cpp index dbae24e4..882f1b42 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -36,7 +36,7 @@ bool NPC::isTalking = false; int current_npc = 0; NPC::NPC(int id, int job, Map *map): - Being(id, job, map) + Player(id, job, map, true) { NPCInfo info = NPCDB::get(job); @@ -48,6 +48,8 @@ NPC::NPC(int id, int job, Map *map): std::string file = "graphics/sprites/" + (*i)->sprite; int variant = (*i)->variant; mSprites.push_back(AnimatedSprite::load(file, variant)); + mSpriteIDs.push_back(0); + mSpriteColors.push_back(""); } if (mParticleEffects) @@ -81,3 +83,8 @@ void NPC::talk() Net::getNpcHandler()->talk(mId); } + +void NPC::setSprite(unsigned int slot, int id, const std::string &color) +{ + // Do nothing +} diff --git a/src/npc.h b/src/npc.h index 5335d8cd..46e48184 100644 --- a/src/npc.h +++ b/src/npc.h @@ -27,7 +27,7 @@ class Graphics; class Text; -class NPC : public Being +class NPC : public Player { public: NPC(int id, int job, Map *map); @@ -38,6 +38,9 @@ class NPC : public Being void talk(); + void setSprite(unsigned int slot, int id, + const std::string &color = ""); + /** * Gets the way an NPC is blocked by other things on the map */ @@ -56,6 +59,9 @@ class NPC : public Being */ virtual Map::BlockType getBlockType() const { return Map::BLOCKTYPE_CHARACTER; } //blocks like a player character + + // Colors don't change for NPCs + virtual void updateColors() {} }; extern int current_npc; diff --git a/src/player.cpp b/src/player.cpp index 55888654..288c565d 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -38,16 +38,27 @@ #include "utils/stringutils.h" -Player::Player(int id, int job, Map *map): +Player::Player(int id, int job, Map *map, bool isNPC): Being(id, job, map), mGender(GENDER_UNSPECIFIED), - mSpriteIDs(VECTOREND_SPRITE, 0), - mSpriteColors(VECTOREND_SPRITE, ""), mIsGM(false), mInParty(false) { - for (int i = 0; i < VECTOREND_SPRITE; i++) - mSprites.push_back(NULL); + if (!isNPC) + { + for (int i = 0; i < VECTOREND_SPRITE; i++) + { + mSprites.push_back(NULL); + mSpriteIDs.push_back(0); + mSpriteColors.push_back(""); + } + + /* Human base sprite. When implementing different races remove this + * line and set the base sprite when setting the race of the player + * character. + */ + setSprite(BASE_SPRITE, -100); + } mShowName = config.getValue("visiblenames", 1); config.addListener("visiblenames", this); @@ -125,14 +136,8 @@ void Player::setGender(Gender gender) { mGender = gender; - /* Human base sprite. When implementing different races remove this - * line and set the base sprite when setting the race of the player - * character. - */ - setSprite(BASE_SPRITE, -100); - // Reload all subsprites - for (unsigned int i = 1; i < mSprites.size(); i++) + for (unsigned int i = 0; i < mSprites.size(); i++) { if (mSpriteIDs.at(i) != 0) setSprite(i, mSpriteIDs.at(i), mSpriteColors.at(i)); @@ -147,7 +152,7 @@ void Player::setGM(bool gm) updateColors(); } -void Player::setSprite(int slot, int id, const std::string &color) +void Player::setSprite(unsigned int slot, int id, const std::string &color) { assert(slot >= BASE_SPRITE && slot < VECTOREND_SPRITE); @@ -193,6 +198,16 @@ void Player::setSprite(int slot, int id, const std::string &color) mSpriteColors[slot] = color; } +void Player::setSpriteID(unsigned int slot, int id) +{ + setSprite(slot, id, mSpriteColors[slot]); +} + +void Player::setSpriteColor(unsigned int slot, const std::string &color) +{ + setSprite(slot, mSpriteIDs[slot], color); +} + #ifdef TMWSERV_SUPPORT Guild* Player::addGuild(short guildId, short rights) { diff --git a/src/player.h b/src/player.h index 36f0266e..3c4cc258 100644 --- a/src/player.h +++ b/src/player.h @@ -71,7 +71,7 @@ class Player : public Being /** * Constructor. */ - Player(int id, int job, Map *map); + Player(int id, int job, Map *map, bool isNPC = false); ~Player(); @@ -101,7 +101,13 @@ class Player : public Being /** * Sets visible equipments for this player. */ - virtual void setSprite(int slot, int id, const std::string &color = ""); + virtual void setSprite(unsigned int slot, int id, + const std::string &color = ""); + + virtual void setSpriteID(unsigned int slot, int id); + + virtual void setSpriteColor(unsigned int slot, + const std::string &color = ""); #ifdef TMWSERV_SUPPORT /** -- cgit v1.2.3-70-g09d2 From b45392a7cde35aac471813beec94686a8ec240ca Mon Sep 17 00:00:00 2001 From: Bertram Date: Sat, 15 Aug 2009 01:49:18 +0200 Subject: Mantis #783: Fixed window opacity breaks in software (SDL) mode. --- src/resources/image.cpp | 100 ++++++++++++++++++++++++++++++------------------ src/resources/image.h | 13 ++++++- 2 files changed, 74 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/resources/image.cpp b/src/resources/image.cpp index a9005509..877bb998 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -27,6 +27,7 @@ #include #include "resources/sdlrescalefacility.h" +#include #ifdef USE_OPENGL bool Image::mUseOpenGL = false; @@ -34,9 +35,11 @@ int Image::mTextureType = 0; int Image::mTextureSize = 0; #endif -Image::Image(SDL_Surface *image): +Image::Image(SDL_Surface *image, bool hasAlphaChannel, Uint8 *alphaChannel): mAlpha(1.0f), - mSDLSurface(image) + mSDLSurface(image), + mHasAlphaChannel(hasAlphaChannel), + mAlphaChannel(alphaChannel) { #ifdef USE_OPENGL mGLImage = 0; @@ -52,7 +55,6 @@ Image::Image(SDL_Surface *image): mBounds.w = mSDLSurface->w; mBounds.h = mSDLSurface->h; - mHasAlphaChannel = hasAlphaChannel(); mLoaded = true; } else @@ -62,9 +64,10 @@ Image::Image(SDL_Surface *image): #ifdef USE_OPENGL Image::Image(GLuint glimage, int width, int height, int texWidth, int texHeight): - mAlpha(1.0), + mAlpha(1.0f), mHasAlphaChannel(true), mSDLSurface(0), + mAlphaChannel(0), mGLImage(glimage), mTexWidth(texWidth), mTexHeight(texHeight) @@ -169,6 +172,9 @@ void Image::unload() // Free the image surface. SDL_FreeSurface(mSDLSurface); mSDLSurface = NULL; + + delete[] mAlphaChannel; + mAlphaChannel = NULL; } #ifdef USE_OPENGL @@ -199,44 +205,49 @@ bool Image::hasAlphaChannel() return true; #endif - if (!mSDLSurface) - return false; + return false; +} - bool hasAlpha = false; +void Image::setAlpha(float alpha) +{ + if (mAlpha == alpha) + return; + + if (alpha < 0.0f || alpha > 1.0f) + return; - if (mSDLSurface->format->BitsPerPixel == 32) + mAlpha = alpha; + + if (mSDLSurface) { - // Figure out whether the image uses its alpha layer - for (int i = 0; i < mSDLSurface->w * mSDLSurface->h; ++i) + if (!hasAlphaChannel()) { - Uint8 r, g, b, a; - SDL_GetRGBA( - ((Uint32*) mSDLSurface->pixels)[i], - mSDLSurface->format, - &r, &g, &b, &a); - - if (a != 255) - { - hasAlpha = true; - break; - } + // Set the alpha value this image is drawn at + SDL_SetAlpha(mSDLSurface, SDL_SRCALPHA, (int) (255 * mAlpha)); } - } + else + { + if (SDL_MUSTLOCK(mSDLSurface)) + SDL_LockSurface(mSDLSurface); - return hasAlpha; -} + for (int i = 0; i < mSDLSurface->w * mSDLSurface->h; ++i) + { + Uint8 r, g, b, a; + SDL_GetRGBA( + ((Uint32*) mSDLSurface->pixels)[i], + mSDLSurface->format, + &r, &g, &b, &a); -void Image::setAlpha(float a) -{ - if (mAlpha == a) - return; + a = (Uint8) (mAlphaChannel[i] * mAlpha); - mAlpha = a; + // Here is the pixel we want to set + ((Uint32 *)(mSDLSurface->pixels))[i] = + SDL_MapRGBA(mSDLSurface->format, r, g, b, a); + } - if (mSDLSurface) - { - // Set the alpha value this image is drawn at - SDL_SetAlpha(mSDLSurface, SDL_SRCALPHA, (int) (255 * mAlpha)); + if (SDL_MUSTLOCK(mSDLSurface)) + SDL_UnlockSurface(mSDLSurface); + } } } @@ -353,6 +364,9 @@ Image *Image::_SDLload(SDL_Surface *tmpImage) bool hasAlpha = false; + // The alpha channel to be filled with alpha values + Uint8 *alphaChannel = new Uint8[tmpImage->w * tmpImage->h]; + if (tmpImage->format->BitsPerPixel == 32) { // Figure out whether the image uses its alpha layer @@ -365,10 +379,9 @@ Image *Image::_SDLload(SDL_Surface *tmpImage) &r, &g, &b, &a); if (a != 255) - { hasAlpha = true; - break; - } + + alphaChannel[i] = a; } } @@ -378,15 +391,23 @@ Image *Image::_SDLload(SDL_Surface *tmpImage) if (hasAlpha) image = SDL_DisplayFormatAlpha(tmpImage); else + { image = SDL_DisplayFormat(tmpImage); + // We also delete the alpha channel since + // it's not used. + delete[] alphaChannel; + alphaChannel = NULL; + } + if (!image) { logger->log("Error: Image convert failed."); + delete[] alphaChannel; return NULL; } - return new Image(image); + return new Image(image, hasAlpha, alphaChannel); } #ifdef USE_OPENGL @@ -537,6 +558,9 @@ SubImage::SubImage(Image *parent, SDL_Surface *image, { mParent->incRef(); + mHasAlphaChannel = mParent->hasAlphaChannel(); + mAlphaChannel = mParent->SDLgetAlphaChannel(); + // Set up the rectangle. mBounds.x = x; mBounds.y = y; @@ -565,6 +589,8 @@ SubImage::~SubImage() { // Avoid destruction of the image mSDLSurface = 0; + // Avoid possible destruction of its alpha channel + mAlphaChannel = 0; #ifdef USE_OPENGL mGLImage = 0; #endif diff --git a/src/resources/image.h b/src/resources/image.h index dfa319ab..9c0f9da7 100644 --- a/src/resources/image.h +++ b/src/resources/image.h @@ -118,7 +118,7 @@ class Image : public Resource /** * Tells if the image has got an alpha channel - * @return true if OpenGL, false if SDL. + * @return true if it's true, false otherwise. */ bool hasAlphaChannel(); @@ -163,6 +163,12 @@ class Image : public Resource */ Image *SDLmerge(Image *image, int x, int y); + /** + * Get the alpha Channel of a SDL surface. + */ + Uint8 *SDLgetAlphaChannel() const + { return mAlphaChannel; } + #ifdef USE_OPENGL // OpenGL only public functions @@ -194,13 +200,16 @@ class Image : public Resource // ----------------------- /** SDL Constructor */ - Image(SDL_Surface *image); + Image(SDL_Surface *image, bool hasAlphaChannel = false, + Uint8 *alphaChannel = NULL); /** SDL_Surface to SDL_Surface Image loader */ static Image *_SDLload(SDL_Surface *tmpImage); SDL_Surface *mSDLSurface; + /** Alpha Channel pointer used for 32bit based SDL surfaces */ + Uint8 *mAlphaChannel; // ----------------------- // OpenGL protected members -- cgit v1.2.3-70-g09d2 From a38976c47120dc80cf370018f1479ec591d4560c Mon Sep 17 00:00:00 2001 From: Bertram Date: Sat, 15 Aug 2009 02:54:28 +0200 Subject: Removed unused include. --- src/resources/image.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 877bb998..73965e19 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -27,7 +27,6 @@ #include #include "resources/sdlrescalefacility.h" -#include #ifdef USE_OPENGL bool Image::mUseOpenGL = false; -- cgit v1.2.3-70-g09d2 From 7f83b173354b3e9efe0b9c99879d8db5bc800e17 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Fri, 14 Aug 2009 20:31:49 -0600 Subject: Remove some uneeded code This should've been removed earlier with the layout fixes. --- src/gui/skilldialog.cpp | 10 ---------- src/gui/skilldialog.h | 3 --- src/gui/specialswindow.cpp | 10 ---------- src/gui/specialswindow.h | 3 --- 4 files changed, 26 deletions(-) (limited to 'src') diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index f6ab226a..6e7b3e70 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -122,16 +122,6 @@ void SkillDialog::action(const gcn::ActionEvent &event) } } -void SkillDialog::logic() -{ - Window::logic(); - - Tab *tab = dynamic_cast(mTabs->getSelectedTab()); - if (tab != mCurrentTab) { - mCurrentTab = tab; - } -} - std::string SkillDialog::update(int id) { SkillMap::iterator i = mSkills.find(id); diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h index 8fa7443d..12cb3581 100644 --- a/src/gui/skilldialog.h +++ b/src/gui/skilldialog.h @@ -54,8 +54,6 @@ class SkillDialog : public Window, public gcn::ActionListener */ void action(const gcn::ActionEvent &event); - void logic(); - /** * Update the given skill's display */ @@ -73,7 +71,6 @@ class SkillDialog : public Window, public gcn::ActionListener private: typedef std::map SkillMap; SkillMap mSkills; - Tab *mCurrentTab; TabbedArea *mTabs; Label *mPointsLabel; }; diff --git a/src/gui/specialswindow.cpp b/src/gui/specialswindow.cpp index 5d2ab676..35839b39 100644 --- a/src/gui/specialswindow.cpp +++ b/src/gui/specialswindow.cpp @@ -126,16 +126,6 @@ void SpecialsWindow::action(const gcn::ActionEvent &event) } } -void SpecialsWindow::logic() -{ - Window::logic(); - - Tab *tab = dynamic_cast(mTabs->getSelectedTab()); - if (tab != mCurrentTab) { - mCurrentTab = tab; - } -} - std::string SpecialsWindow::update(int id) { // TODO diff --git a/src/gui/specialswindow.h b/src/gui/specialswindow.h index 17c29597..cc2a68b3 100644 --- a/src/gui/specialswindow.h +++ b/src/gui/specialswindow.h @@ -48,8 +48,6 @@ class SpecialsWindow : public Window, public gcn::ActionListener { */ void action(const gcn::ActionEvent &actionEvent); - void logic(); - /** * Update the given special's display */ @@ -60,7 +58,6 @@ class SpecialsWindow : public Window, public gcn::ActionListener { private: typedef std::map SpecialMap; SpecialMap mSpecials; - Tab *mCurrentTab; TabbedArea *mTabs; }; -- cgit v1.2.3-70-g09d2 From 3a114a6ba32b828f99915d3fab48f303d98643d6 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Sat, 15 Aug 2009 15:23:01 -0600 Subject: Fix some compile errors --- src/resources/image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/resources/image.cpp b/src/resources/image.cpp index 73965e19..d2a1c82e 100644 --- a/src/resources/image.cpp +++ b/src/resources/image.cpp @@ -36,8 +36,8 @@ int Image::mTextureSize = 0; Image::Image(SDL_Surface *image, bool hasAlphaChannel, Uint8 *alphaChannel): mAlpha(1.0f), - mSDLSurface(image), mHasAlphaChannel(hasAlphaChannel), + mSDLSurface(image), mAlphaChannel(alphaChannel) { #ifdef USE_OPENGL -- cgit v1.2.3-70-g09d2 From 7e2673a3b9460fdcd646e23c3bd9039de854565f Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Sat, 15 Aug 2009 22:16:47 -0600 Subject: Fix changing setting for own name visibility --- src/localplayer.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 8fbfe70a..319d9da7 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -133,6 +133,8 @@ LocalPlayer::~LocalPlayer() delete mStorage; #endif + config.removeListener("showownname", this); + for (int i = Being::TC_SMALL; i < Being::NUM_TC; i++) { delete mTargetCursor[0][i]; -- cgit v1.2.3-70-g09d2