summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/branding.xml2
-rw-r--r--data/graphics/gui/CMakeLists.txt3
-rw-r--r--data/graphics/gui/Makefile.am5
-rw-r--r--data/graphics/gui/bg_quad_dis.pngbin5241 -> 0 bytes
-rw-r--r--data/graphics/gui/default.pngbin817 -> 0 bytes
-rw-r--r--data/graphics/gui/gui.xml26
-rw-r--r--data/graphics/gui/window.pngbin0 -> 3410 bytes
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/being.cpp2
-rw-r--r--src/commandhandler.cpp6
-rw-r--r--src/game.cpp66
-rw-r--r--src/gui/connection.cpp2
-rw-r--r--src/gui/connection.h6
-rw-r--r--src/gui/inventorywindow.cpp18
-rw-r--r--src/gui/inventorywindow.h1
-rw-r--r--src/gui/itemcontainer.cpp4
-rw-r--r--src/gui/outfitwindow.cpp306
-rw-r--r--src/gui/outfitwindow.h92
-rw-r--r--src/gui/partywindow.cpp5
-rw-r--r--src/gui/serverselectdialog.cpp2
-rw-r--r--src/gui/serverselectdialog.h6
-rw-r--r--src/gui/setup.cpp2
-rw-r--r--src/gui/skin.cpp10
-rw-r--r--src/gui/textrenderer.h2
-rw-r--r--src/gui/viewport.cpp22
-rw-r--r--src/gui/widgets/avatar.cpp6
-rw-r--r--src/gui/widgets/avatar.h3
-rw-r--r--src/gui/widgets/chattab.cpp20
-rw-r--r--src/gui/widgets/progressbar.cpp14
-rw-r--r--src/gui/windowmenu.cpp1
-rw-r--r--src/keyboardconfig.cpp1
-rw-r--r--src/keyboardconfig.h1
-rw-r--r--src/localplayer.cpp68
-rw-r--r--src/localplayer.h7
-rw-r--r--src/main.cpp45
-rw-r--r--src/main.h9
-rw-r--r--src/net/ea/maphandler.cpp3
-rw-r--r--src/net/ea/playerhandler.cpp4
-rw-r--r--src/net/ea/playerhandler.h2
-rw-r--r--src/net/playerhandler.h2
-rw-r--r--src/net/tmwserv/gameserver/player.cpp7
-rw-r--r--src/net/tmwserv/gameserver/player.h1
-rw-r--r--src/net/tmwserv/playerhandler.cpp6
-rw-r--r--src/net/tmwserv/playerhandler.h2
-rw-r--r--src/net/tmwserv/protocol.h8
-rw-r--r--src/resources/colordb.cpp21
-rw-r--r--src/resources/itemdb.cpp4
-rw-r--r--src/textparticle.cpp17
-rw-r--r--src/textparticle.h2
-rw-r--r--tmw.cbp18
51 files changed, 689 insertions, 175 deletions
diff --git a/data/branding.xml b/data/branding.xml
index 29974ab4..fd5779f6 100644
--- a/data/branding.xml
+++ b/data/branding.xml
@@ -15,7 +15,7 @@ writing a branding.xml for their forks.
<option name="appIcon" value="icons/tmw.png"/>
<option name="loginMusic" value="Magick - Real.ogg"/>
<option name="defaultServer" value="server.themanaworld.org"/>
- <option name="defaultPort" value="9601"/>
+ <option name="defaultPort" value="6901"/>
<option name="defaultUpdateHost" value="http://updates.themanaworld.org"/>
<option name="font" value="fonts/dejavusans.ttf" />
<option name="boldFont" value="fonts/dejavusans-bold.ttf" />
diff --git a/data/graphics/gui/CMakeLists.txt b/data/graphics/gui/CMakeLists.txt
index 78fde595..920f3b88 100644
--- a/data/graphics/gui/CMakeLists.txt
+++ b/data/graphics/gui/CMakeLists.txt
@@ -1,5 +1,4 @@
SET (FILES
- bg_quad_dis.png
bubble.png
button.png
button_disabled.png
@@ -10,7 +9,6 @@ SET (FILES
circle-green.png
close_button.png
deepbox.png
- default.png
gui.xml
hscroll_left_default.png
hscroll_left_highlight.png
@@ -43,6 +41,7 @@ SET (FILES
vscroll_up_default.png
vscroll_up_highlight.png
vscroll_up_pressed.png
+ window.png
)
INSTALL(FILES ${FILES} DESTINATION ${DATA_DIR}/graphics/gui)
diff --git a/data/graphics/gui/Makefile.am b/data/graphics/gui/Makefile.am
index 98a0c2a5..a2bafb29 100644
--- a/data/graphics/gui/Makefile.am
+++ b/data/graphics/gui/Makefile.am
@@ -2,7 +2,6 @@
guidir = $(pkgdatadir)/data/graphics/gui
gui_DATA = \
- bg_quad_dis.png \
bubble.png \
button.png \
button_disabled.png \
@@ -13,7 +12,6 @@ gui_DATA = \
circle-green.png \
close_button.png \
deepbox.png \
- default.png \
gui.xml \
hscroll_left_default.png \
hscroll_left_highlight.png \
@@ -45,7 +43,8 @@ gui_DATA = \
vscroll_grey.png \
vscroll_up_default.png \
vscroll_up_highlight.png \
- vscroll_up_pressed.png
+ vscroll_up_pressed.png \
+ window.png
EXTRA_DIST = \
$(gui_DATA)
diff --git a/data/graphics/gui/bg_quad_dis.png b/data/graphics/gui/bg_quad_dis.png
deleted file mode 100644
index 3a0354bb..00000000
--- a/data/graphics/gui/bg_quad_dis.png
+++ /dev/null
Binary files differ
diff --git a/data/graphics/gui/default.png b/data/graphics/gui/default.png
deleted file mode 100644
index a8bc5baf..00000000
--- a/data/graphics/gui/default.png
+++ /dev/null
Binary files differ
diff --git a/data/graphics/gui/gui.xml b/data/graphics/gui/gui.xml
index fe62528e..f27dbc7f 100644
--- a/data/graphics/gui/gui.xml
+++ b/data/graphics/gui/gui.xml
@@ -1,18 +1,18 @@
-<skinset name="Default" image="default.png">
- <widget type="Window">
- <!-- Top Row -->
- <part type="top-left-corner" xpos="0" ypos="0" width="4" height="4" />
- <part type="top-edge" xpos="4" ypos="0" width="3" height="4" />
- <part type="top-right-corner" xpos="7" ypos="0" width="4" height="4" />
+<skinset name="Default" image="window.png">
+ <widget type="Window">
+ <!-- Top Row -->
+ <part type="top-left-corner" xpos="0" ypos="0" width="4" height="4" />
+ <part type="top-edge" xpos="4" ypos="0" width="32" height="4" />
+ <part type="top-right-corner" xpos="36" ypos="0" width="4" height="4" />
<!-- Middle Row -->
- <part type="left-edge" xpos="0" ypos="4" width="4" height="10" />
- <part type="bg-quad" xpos="11" ypos="0" width="32" height="32" />
- <part type="right-edge" xpos="7" ypos="4" width="4" height="10" />
+ <part type="left-edge" xpos="0" ypos="4" width="4" height="216" />
+ <part type="bg-quad" xpos="4" ypos="4" width="32" height="216" />
+ <part type="right-edge" xpos="36" ypos="4" width="4" height="216" />
<!-- Bottom Row -->
- <part type="bottom-left-corner" xpos="0" ypos="15" width="4" height="4" />
- <part type="bottom-edge" xpos="4" ypos="15" width="3" height="4" />
- <part type="bottom-right-corner" xpos="7" ypos="15" width="4" height="4" />
+ <part type="bottom-left-corner" xpos="0" ypos="220" width="4" height="4" />
+ <part type="bottom-edge" xpos="4" ypos="220" width="32" height="4" />
+ <part type="bottom-right-corner" xpos="36" ypos="220" width="4" height="4" />
</widget>
-</skinset> \ No newline at end of file
+</skinset>
diff --git a/data/graphics/gui/window.png b/data/graphics/gui/window.png
new file mode 100644
index 00000000..f0ef1af4
--- /dev/null
+++ b/data/graphics/gui/window.png
Binary files differ
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 08110c43..a295f249 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -167,6 +167,8 @@ SET(SRCS
gui/npcpostdialog.h
gui/okdialog.cpp
gui/okdialog.h
+ gui/outfitwindow.cpp
+ gui/outfitwindow.h
gui/palette.cpp
gui/palette.h
gui/partywindow.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index 47d27ede..a474c963 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -116,6 +116,8 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
gui/npcpostdialog.h \
gui/okdialog.cpp \
gui/okdialog.h \
+ gui/outfitwindow.cpp \
+ gui/outfitwindow.h \
gui/palette.cpp \
gui/palette.h \
gui/partywindow.cpp \
diff --git a/src/being.cpp b/src/being.cpp
index 2b31e9ec..37cb6987 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -448,7 +448,7 @@ void Being::takeDamage(Being *attacker, int amount, AttackType type)
// Show damage number
particleEngine->addTextSplashEffect(damage,
- mPx + 16, mPy + 16,
+ mPx, mPy - 16,
color, font, true);
if (amount > 0)
diff --git a/src/commandhandler.cpp b/src/commandhandler.cpp
index 462cb3b9..f2fafed4 100644
--- a/src/commandhandler.cpp
+++ b/src/commandhandler.cpp
@@ -279,9 +279,9 @@ void CommandHandler::handleWhere(const std::string &args, ChatTab *tab)
{
std::ostringstream where;
where << map_path << ", coordinates: "
- << (player_node->getPixelX() / 32) << ", "
- << ((player_node->getPixelY() / 32) - 1); // Not real sure why we remove 1,
- // but it makes it in sync with @where
+ << ((player_node->getPixelX() - 16) / 32) << ", "
+ << ((player_node->getPixelY() - 32) / 32);
+
tab->chatLog(where.str(), BY_SERVER);
}
diff --git a/src/game.cpp b/src/game.cpp
index 59c57607..98985e74 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -57,6 +57,7 @@
#include "gui/ministatus.h"
#include "gui/npcdialog.h"
#include "gui/okdialog.h"
+#include "gui/outfitwindow.h"
#include "gui/sdlinput.h"
#include "gui/sell.h"
#include "gui/setup.h"
@@ -138,6 +139,7 @@ HelpWindow *helpWindow;
DebugWindow *debugWindow;
ShortcutWindow *itemShortcutWindow;
ShortcutWindow *emoteShortcutWindow;
+OutfitWindow *outfitWindow;
BeingManager *beingManager = NULL;
FloorItemManager *floorItemManager = NULL;
@@ -232,6 +234,7 @@ static void createGuiWindows()
new ItemShortcutContainer);
emoteShortcutWindow = new ShortcutWindow("EmoteShortcut",
new EmoteShortcutContainer);
+ outfitWindow = new OutfitWindow();
localChatTab = new ChatTab(_("General"));
@@ -277,6 +280,7 @@ static void destroyGuiWindows()
delete itemShortcutWindow;
delete emoteShortcutWindow;
delete storageWindow;
+ delete outfitWindow;
}
Game::Game():
@@ -606,6 +610,65 @@ void Game::handleInput()
}
}
+ if (event.key.keysym.mod & KMOD_RCTRL && !chatWindow->isInputFocused())
+ {
+ switch (event.key.keysym.sym)
+ {
+ case SDLK_1:
+ outfitWindow->wearOutfit(0);
+ used = true;
+ break;
+
+ case SDLK_2:
+ outfitWindow->wearOutfit(1);
+ used = true;
+ break;
+
+ case SDLK_3:
+ outfitWindow->wearOutfit(2);
+ used = true;
+ break;
+
+ case SDLK_4:
+ outfitWindow->wearOutfit(3);
+ used = true;
+ break;
+
+ case SDLK_5:
+ outfitWindow->wearOutfit(4);
+ used = true;
+ break;
+
+ case SDLK_6:
+ outfitWindow->wearOutfit(5);
+ used = true;
+ break;
+
+ case SDLK_7:
+ outfitWindow->wearOutfit(6);
+ used = true;
+ break;
+
+ case SDLK_8:
+ outfitWindow->wearOutfit(7);
+ used = true;
+ break;
+
+ case SDLK_9:
+ outfitWindow->wearOutfit(8);
+ used = true;
+ break;
+
+ case SDLK_0:
+ outfitWindow->wearOutfit(9);
+ used = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
const int tKey = keyboard.getKeyIndex(event.key.keysym.sym);
switch (tKey)
{
@@ -782,6 +845,9 @@ void Game::handleInput()
case KeyboardConfig::KEY_WINDOW_EMOTE_SHORTCUT:
requestedWindow = emoteShortcutWindow;
break;
+ case KeyboardConfig::KEY_WINDOW_OUTFIT:
+ requestedWindow = outfitWindow;
+ break;
case KeyboardConfig::KEY_SCREENSHOT:
// Screenshot (picture, hence the p)
saveScreenshot();
diff --git a/src/gui/connection.cpp b/src/gui/connection.cpp
index 0862ee69..4863edcd 100644
--- a/src/gui/connection.cpp
+++ b/src/gui/connection.cpp
@@ -30,7 +30,7 @@
#include "utils/gettext.h"
-ConnectionDialog::ConnectionDialog(int previousState):
+ConnectionDialog::ConnectionDialog(State previousState):
Window("Info"), mProgress(0), mPreviousState(previousState)
{
setContentSize(200, 100);
diff --git a/src/gui/connection.h b/src/gui/connection.h
index 62441fa9..d6059c3f 100644
--- a/src/gui/connection.h
+++ b/src/gui/connection.h
@@ -24,6 +24,8 @@
#include "gui/widgets/window.h"
+#include "main.h"
+
#include <guichan/actionlistener.hpp>
class ProgressBar;
@@ -41,7 +43,7 @@ class ConnectionDialog : public Window, gcn::ActionListener
*
* @see Window::Window
*/
- ConnectionDialog(int previousState);
+ ConnectionDialog(State previousState);
/**
* Called when the user presses Cancel. Restores the global state to
@@ -54,7 +56,7 @@ class ConnectionDialog : public Window, gcn::ActionListener
private:
ProgressBar *mProgressBar;
float mProgress;
- int mPreviousState;
+ State mPreviousState;
};
#endif
diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp
index d6cd3a84..c44ae9e7 100644
--- a/src/gui/inventorywindow.cpp
+++ b/src/gui/inventorywindow.cpp
@@ -79,6 +79,7 @@ InventoryWindow::InventoryWindow(int invSize):
mUseButton = new Button(longestUseString, "use", this);
mDropButton = new Button(_("Drop"), "drop", this);
mSplitButton = new Button(_("Split"), "split", this);
+ mOutfitButton = new Button(_("Outfits"), "outfit", this);
mItems = new ItemContainer(player_node->getInventory());
mItems->addSelectionListener(this);
@@ -103,6 +104,7 @@ InventoryWindow::InventoryWindow(int invSize):
place(0, 2, mUseButton);
place(1, 2, mDropButton);
place(2, 2, mSplitButton);
+ place(6, 2, mOutfitButton);
Layout &layout = getLayout();
layout.setRowHeight(1, Layout::AUTO_SET);
@@ -156,6 +158,16 @@ void InventoryWindow::logic()
void InventoryWindow::action(const gcn::ActionEvent &event)
{
+ if (event.getId() == "outfit")
+ {
+ extern Window *outfitWindow;
+ outfitWindow->setVisible(!outfitWindow->isVisible());
+ if (outfitWindow->isVisible())
+ {
+ outfitWindow->requestMoveToTop();
+ }
+ }
+
Item *item = mItems->getSelectedItem();
if (!item)
@@ -163,7 +175,7 @@ void InventoryWindow::action(const gcn::ActionEvent &event)
if (event.getId() == "use")
{
- if (item->isEquipment())
+ if (item->isEquipment())
{
if (item->isEquipped())
Net::getInventoryHandler()->unequipItem(item);
@@ -258,10 +270,10 @@ void InventoryWindow::updateButtons()
mDropButton->setEnabled(false);
return;
}
-
+
mUseButton->setEnabled(true);
mDropButton->setEnabled(true);
-
+
if (selectedItem->isEquipment())
{
if (selectedItem->isEquipped())
diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h
index 6e34666d..fbda5ac7 100644
--- a/src/gui/inventorywindow.h
+++ b/src/gui/inventorywindow.h
@@ -109,6 +109,7 @@ class InventoryWindow : public Window,
gcn::Button *mUseButton;
gcn::Button *mDropButton;
gcn::Button *mSplitButton;
+ gcn::Button *mOutfitButton;
gcn::Label *mWeightLabel;
gcn::Label *mSlotsLabel;
diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp
index 54aa818b..d8ae6e20 100644
--- a/src/gui/itemcontainer.cpp
+++ b/src/gui/itemcontainer.cpp
@@ -23,6 +23,7 @@
#include "gui/chat.h"
#include "gui/itempopup.h"
+#include "gui/outfitwindow.h"
#include "gui/palette.h"
#include "gui/sdlinput.h"
#include "gui/viewport.h"
@@ -162,6 +163,7 @@ void ItemContainer::selectNone()
{
setSelectedIndex(-1);
mSelectionStatus = SEL_NONE;
+ outfitWindow->setItemSelected(-1);
}
void ItemContainer::setSelectedIndex(int newIndex)
@@ -260,6 +262,8 @@ void ItemContainer::mousePressed(gcn::MouseEvent &event)
mSelectionStatus = SEL_SELECTING;
itemShortcut->setItemSelected(item->getId());
+ if (item->isEquipment())
+ outfitWindow->setItemSelected(item->getId());
}
else
{
diff --git a/src/gui/outfitwindow.cpp b/src/gui/outfitwindow.cpp
new file mode 100644
index 00000000..f43e1440
--- /dev/null
+++ b/src/gui/outfitwindow.cpp
@@ -0,0 +1,306 @@
+/*
+ * 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 "outfitwindow.h"
+
+#include "configuration.h"
+#include "localplayer.h"
+#include "graphics.h"
+#include "inventory.h"
+#include "equipment.h"
+#include "item.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/checkbox.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+
+#include "resources/image.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <vector>
+
+OutfitWindow::OutfitWindow():
+ Window(_("Outfits")),
+ mBoxWidth(33),
+ mBoxHeight(33),
+ mGridWidth(3),
+ mGridHeight(3),
+ mItemClicked(false),
+ mItemMoved(NULL),
+ mItemSelected(-1),
+ mCurrentOutfit(0)
+{
+ setWindowName("Outfits");
+ setCloseButton(true);
+ setDefaultSize(250, 250, 118, 180); //160
+
+ mPreviousButton = new Button("<", "previous", this);
+ mNextButton = new Button(">", "next", this);
+ mCurrentLabel = new Label("Outfit: 1");
+ mCurrentLabel->setAlignment(gcn::Graphics::CENTER);
+ mUnequipCheck = new CheckBox(_("Unequip first"),
+ config.getValue("OutfitUnequip", true));
+
+ place(0, 3, mPreviousButton, 1);
+ place(1, 3, mCurrentLabel, 2);
+ place(3, 3, mNextButton, 1);
+ place(0, 4, mUnequipCheck, 4);
+
+ Layout &layout = getLayout();
+ layout.setRowHeight(0, Layout::AUTO_SET);
+ layout.setColWidth(4, Layout::CENTER);
+
+ loadWindowState();
+
+ load();
+}
+
+OutfitWindow::~OutfitWindow()
+{
+ save();
+}
+
+void OutfitWindow::load()
+{
+ memset(mItems, -1, sizeof(mItems));
+ for (int o = 0; o < 10; o++)
+ {
+ std::string outfit = config.getValue("Outfit" + toString(o), "-1");
+ std::string buf;
+ std::stringstream ss(outfit);
+
+ std::vector<int> tokens;
+
+ while (ss >> buf) {
+ tokens.push_back(atoi(buf.c_str()));
+ }
+
+ for (int i = 0; i < (int)tokens.size(); i++)
+ {
+ mItems[o][i] = tokens[i];
+ }
+ }
+}
+
+void OutfitWindow::save()
+{
+ std::string outfitStr;
+ for (int o = 0; o < 10; o++)
+ {
+ for (int i = 0; i < 9; i++)
+ {
+ outfitStr += mItems[o][i] ? toString(mItems[o][i]) : toString(-1);
+ if (i <8) outfitStr += " ";
+ }
+ config.setValue("Outfit" + toString(o), outfitStr);
+ outfitStr = "";
+ }
+ config.setValue("OutfitUnequip", mUnequipCheck->isSelected());
+}
+
+void OutfitWindow::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "next")
+ {
+ if (mCurrentOutfit < 9) {
+ mCurrentOutfit++;
+ } else {
+ mCurrentOutfit = 0;
+ }
+ }
+ else if (event.getId() == "previous")
+ {
+ if (mCurrentOutfit > 0) {
+ mCurrentOutfit--;
+ } else {
+ mCurrentOutfit = 9;
+ }
+ }
+ mCurrentLabel->setCaption("Outfit: " + toString(mCurrentOutfit + 1));
+}
+
+void OutfitWindow::wearOutfit(int outfit)
+{
+ Item *item;
+ if (mUnequipCheck->isSelected())
+ {
+ for (int i = 0; i < 11; i++)
+ {
+ //non vis is 3,4,7
+ if (i != 3 && i != 4 && i != 7)
+ {
+#ifdef TMWSERV_SUPPORT
+ if (!(item = player_node->mEquipment.get()->getEquipment(i)))
+ continue;
+#else
+ if (!(item = player_node->getInventory()->getItem(
+ player_node->mEquipment.get()->getEquipment(i))))
+ continue;
+#endif
+ Net::getInventoryHandler()->unequipItem(item);
+ }
+ }
+ }
+
+ for (int i = 0; i < 9; i++)
+ {
+ item = player_node->getInventory()->findItem(mItems[outfit][i]);
+ if (item && item->getQuantity())
+ {
+ if (item->isEquipment()) {
+ Net::getInventoryHandler()->equipItem(item);
+ }
+ }
+ }
+}
+
+void OutfitWindow::draw(gcn::Graphics *graphics)
+{
+ Window::draw(graphics);
+ Graphics *g = static_cast<Graphics*>(graphics);
+
+ for (int i = 0; i < 9; i++)
+ {
+ const int itemX = 10 + (i % mGridWidth) * mBoxWidth;
+ const int itemY = 25 + (i / mGridWidth) * mBoxHeight;
+
+ graphics->setColor(gcn::Color(0, 0, 0, 64));
+ graphics->drawRectangle(gcn::Rectangle(itemX, itemY, 32, 32));
+ graphics->setColor(gcn::Color(255, 255, 255, 32));
+ graphics->fillRectangle(gcn::Rectangle(itemX, itemY, 32, 32));
+
+ if (mItems[mCurrentOutfit][i] < 0)
+ continue;
+
+ Item *item =
+ player_node->getInventory()->findItem(mItems[mCurrentOutfit][i]);
+ if (item) {
+ // Draw item icon.
+ Image* image = item->getImage();
+ if (image) {
+ g->drawImage(image, itemX, itemY);
+ }
+ }
+ }
+ if (mItemMoved)
+ {
+ // Draw the item image being dragged by the cursor.
+ Image* image = mItemMoved->getImage();
+ if (image)
+ {
+ const int tPosX = mCursorPosX - (image->getWidth() / 2);
+ const int tPosY = mCursorPosY - (image->getHeight() / 2);
+
+ g->drawImage(image, tPosX, tPosY);
+ }
+ }
+}
+
+
+void OutfitWindow::mouseDragged(gcn::MouseEvent &event)
+{
+ Window::mouseDragged(event);
+ if (event.getButton() == gcn::MouseEvent::LEFT) {
+ if (!mItemMoved && mItemClicked) {
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+ if (index == -1) {
+ return;
+ }
+ const int itemId = mItems[mCurrentOutfit][index];
+ if (itemId < 0)
+ return;
+ Item *item = player_node->getInventory()->findItem(itemId);
+ if (item)
+ {
+ mItemMoved = item;
+ mItems[mCurrentOutfit][index] = -1;
+ }
+ }
+ if (mItemMoved) {
+ mCursorPosX = event.getX();
+ mCursorPosY = event.getY();
+ }
+ }
+}
+
+void OutfitWindow::mousePressed(gcn::MouseEvent &event)
+{
+ Window::mousePressed(event);
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+ if (index == -1) {
+ return;
+ }
+
+ // Stores the selected item if there is one.
+ if (isItemSelected()) {
+ mItems[mCurrentOutfit][index] = mItemSelected;
+ mItemSelected = -1;
+ }
+ else if (mItems[mCurrentOutfit][index]) {
+ mItemClicked = true;
+ }
+}
+
+void OutfitWindow::mouseReleased(gcn::MouseEvent &event)
+{
+ Window::mouseReleased(event);
+ if (event.getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (isItemSelected())
+ {
+ mItemSelected = -1;
+ }
+ const int index = getIndexFromGrid(event.getX(), event.getY());
+ if (index == -1) {
+ mItemMoved = NULL;
+ return;
+ }
+ if (mItemMoved) {
+ mItems[mCurrentOutfit][index] = mItemMoved->getId();
+ mItemMoved = NULL;
+ }
+ if (mItemClicked) {
+ mItemClicked = false;
+ }
+ }
+}
+
+int OutfitWindow::getIndexFromGrid(int pointX, int pointY) const
+{
+ const gcn::Rectangle tRect = gcn::Rectangle(
+ 10, 25, 10 + mGridWidth * mBoxWidth, 25 + mGridHeight * mBoxHeight);
+ if (!tRect.isPointInRect(pointX, pointY)) {
+ return -1;
+ }
+ const int index = (((pointY - 25) / mBoxHeight) * mGridWidth) +
+ (pointX - 10) / mBoxWidth;
+ if (index >= 9)
+ {
+ return -1;
+ }
+ return index;
+}
diff --git a/src/gui/outfitwindow.h b/src/gui/outfitwindow.h
new file mode 100644
index 00000000..3e70815c
--- /dev/null
+++ b/src/gui/outfitwindow.h
@@ -0,0 +1,92 @@
+/*
+ * 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
+ */
+
+#ifndef OUTFITWINDOW_H
+#define OUTFITWINDOW_H
+
+#include "gui/widgets/window.h"
+
+#include <guichan/actionlistener.hpp>
+
+class Button;
+class CheckBox;
+class Item;
+class Label;
+
+class OutfitWindow : public Window, gcn::ActionListener
+{
+ public:
+ /**
+ * Constructor.
+ */
+ OutfitWindow();
+
+ /**
+ * Destructor.
+ */
+ ~OutfitWindow();
+
+ void action(const gcn::ActionEvent &event);
+
+ void draw(gcn::Graphics *graphics);
+
+ void mousePressed(gcn::MouseEvent &event);
+
+ void mouseDragged(gcn::MouseEvent &event);
+
+ void mouseReleased(gcn::MouseEvent &event);
+
+ void load();
+
+ void setItemSelected(int itemId)
+ { mItemSelected = itemId; }
+
+ bool isItemSelected()
+ { return mItemSelected > -1; }
+
+ void wearOutfit(int outfit);
+
+ private:
+ Button *mPreviousButton;
+ Button *mNextButton;
+ Label *mCurrentLabel;
+ CheckBox *mUnequipCheck;
+
+ int getIndexFromGrid(int pointX, int pointY) const;
+
+ int mBoxWidth;
+ int mBoxHeight;
+ int mCursorPosX, mCursorPosY;
+ int mGridWidth, mGridHeight;
+ bool mItemClicked;
+ Item *mItemMoved;
+
+ void save();
+
+ int mItems[10][9];
+ int mItemSelected;
+
+ int mCurrentOutfit;
+};
+
+extern OutfitWindow *outfitWindow;
+
+#endif
diff --git a/src/gui/partywindow.cpp b/src/gui/partywindow.cpp
index 1260a2c3..5e384413 100644
--- a/src/gui/partywindow.cpp
+++ b/src/gui/partywindow.cpp
@@ -54,8 +54,8 @@ PartyWindow::PartyWindow() :
setSaveVisible(true);
setCloseButton(true);
setMinWidth(120);
- setMinHeight(200);
- setDefaultSize(590, 200, 150, 200);
+ setMinHeight(55);
+ setDefaultSize(590, 200, 150, 60);
loadWindowState();
}
@@ -123,6 +123,7 @@ void PartyWindow::updateMember(int id, const std::string &memberName,
member->name = memberName;
member->leader = leader;
member->online = online;
+ member->avatar->setDisplayBold(leader);
member->avatar->setName(memberName);
member->avatar->setOnline(online);
diff --git a/src/gui/serverselectdialog.cpp b/src/gui/serverselectdialog.cpp
index ccdf2bb6..f492ebc7 100644
--- a/src/gui/serverselectdialog.cpp
+++ b/src/gui/serverselectdialog.cpp
@@ -55,7 +55,7 @@ class ServerListModel : public gcn::ListModel
}
};
-ServerSelectDialog::ServerSelectDialog(LoginData *loginData, int nextState):
+ServerSelectDialog::ServerSelectDialog(LoginData *loginData, State nextState):
Window(_("Select Server")),
mLoginData(loginData),
mNextState(nextState)
diff --git a/src/gui/serverselectdialog.h b/src/gui/serverselectdialog.h
index b80ad286..fd1484af 100644
--- a/src/gui/serverselectdialog.h
+++ b/src/gui/serverselectdialog.h
@@ -24,6 +24,8 @@
#include "gui/widgets/window.h"
+#include "main.h"
+
#include <guichan/actionlistener.hpp>
#include <guichan/listmodel.hpp>
@@ -42,7 +44,7 @@ class ServerSelectDialog : public Window, public gcn::ActionListener {
*
* @see Window::Window
*/
- ServerSelectDialog(LoginData *loginData, int nextState);
+ ServerSelectDialog(LoginData *loginData, State nextState);
/**
* Destructor.
@@ -59,7 +61,7 @@ class ServerSelectDialog : public Window, public gcn::ActionListener {
ServerListModel *mServerListModel;
gcn::ListBox *mServerList;
gcn::Button *mOkButton;
- int mNextState;
+ State mNextState;
};
#endif
diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp
index e73f9b74..aebcf61b 100644
--- a/src/gui/setup.cpp
+++ b/src/gui/setup.cpp
@@ -46,6 +46,7 @@ extern Window *inventoryWindow;
extern Window *npcTextDialog;
extern Window *npcStringDialog;
extern Window *skillDialog;
+extern Window *partyWindow;
extern Window *minimap;
extern Window *equipmentWindow;
extern Window *tradeWindow;
@@ -145,6 +146,7 @@ void Setup::action(const gcn::ActionEvent &event)
#endif
inventoryWindow->resetToDefaultSize();
skillDialog->resetToDefaultSize();
+ partyWindow->resetToDefaultSize();
minimap->resetToDefaultSize();
equipmentWindow->resetToDefaultSize();
tradeWindow->resetToDefaultSize();
diff --git a/src/gui/skin.cpp b/src/gui/skin.cpp
index f6eb0d58..5881a073 100644
--- a/src/gui/skin.cpp
+++ b/src/gui/skin.cpp
@@ -101,16 +101,14 @@ void Skin::updateAlpha()
int Skin::getMinWidth() const
{
- return (mBorder.grid[ImageRect::UPPER_LEFT]->getWidth() +
- mBorder.grid[ImageRect::UPPER_CENTER]->getWidth()) +
- mBorder.grid[ImageRect::UPPER_RIGHT]->getWidth();
+ return mBorder.grid[ImageRect::UPPER_LEFT]->getWidth() +
+ mBorder.grid[ImageRect::UPPER_RIGHT]->getWidth();
}
int Skin::getMinHeight() const
{
- return (mBorder.grid[ImageRect::UPPER_LEFT]->getHeight() +
- mBorder.grid[ImageRect::LEFT]->getHeight()) +
- mBorder.grid[ImageRect::LOWER_LEFT]->getHeight();
+ return mBorder.grid[ImageRect::UPPER_LEFT]->getHeight() +
+ mBorder.grid[ImageRect::LOWER_LEFT]->getHeight();
}
SkinLoader::SkinLoader()
diff --git a/src/gui/textrenderer.h b/src/gui/textrenderer.h
index 712c1312..c8ff5833 100644
--- a/src/gui/textrenderer.h
+++ b/src/gui/textrenderer.h
@@ -50,7 +50,7 @@ class TextRenderer
if (shadow)
{
graphics->setColor(guiPalette->getColor(Palette::SHADOW,
- alpha / 2));
+ alpha / 2));
if (outline)
{
graphics->drawText(text, x + 2, y + 2, align);
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index f92a81b8..787723c0 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -195,7 +195,7 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
mMap->drawCollision(graphics,
(int) mPixelViewX,
(int) mPixelViewY);
-#if 0
+#if EATHENA_SUPPORT
drawDebugPath(graphics);
#endif
}
@@ -265,8 +265,8 @@ void Viewport::drawDebugPath(Graphics *graphics)
const Vector &playerPos = player_node->getPosition();
Path debugPath = mMap->findPath(
- (int) playerPos.x / 32,
- (int) playerPos.y / 32,
+ (int) (playerPos.x - 16) / 32,
+ (int) (playerPos.y - 32) / 32,
mouseTileX, mouseTileY, 0xFF);
drawPath(graphics, debugPath);
@@ -357,24 +357,12 @@ void Viewport::mousePressed(gcn::MouseEvent &event)
if (player_node->withinAttackRange(being) ||
keyboard.isKeyActive(keyboard.KEY_ATTACK))
{
- player_node->setGotoTarget(being);
-//TODO: This can be changed when TMWServ moves to target based combat
-#ifdef TMWSERV_SUPPORT
- player_node->attack();
-#else
player_node->attack(being,
!keyboard.isKeyActive(keyboard.KEY_TARGET));
-#endif
-
}
else
{
-#ifdef TMWSERV_SUPPORT
- player_node->setDestination(event.getX() + (int) mPixelViewX,
- event.getY() + (int) mPixelViewY);
-#else
- player_node->setDestination(tilex, tiley);
-#endif
+ player_node->setGotoTarget(being);
}
break;
default:
@@ -403,9 +391,9 @@ void Viewport::mousePressed(gcn::MouseEvent &event)
event.getY() + (int) mPixelViewY);
}
#else
- player_node->stopAttack();
player_node->setDestination(tilex, tiley);
#endif
+ player_node->stopAttack();
mPlayerFollowMouse = true;
}
}
diff --git a/src/gui/widgets/avatar.cpp b/src/gui/widgets/avatar.cpp
index 16c77233..f7273c75 100644
--- a/src/gui/widgets/avatar.cpp
+++ b/src/gui/widgets/avatar.cpp
@@ -23,6 +23,7 @@
#include "localplayer.h"
+#include "gui/gui.h"
#include "gui/widgets/icon.h"
#include "gui/widgets/label.h"
@@ -39,7 +40,8 @@ namespace {
Avatar::Avatar():
mHp(0),
- mMaxHp(0)
+ mMaxHp(0),
+ mDisplayBold(false)
{
setOpaque(false);
@@ -111,6 +113,8 @@ void Avatar::updateAvatarLabel()
if (mName != player_node->getName() && mMaxHp != 0)
ss << " (" << mHp << "/" << mMaxHp << ")";
+ if (mDisplayBold)
+ mLabel->setFont(boldFont);
mLabel->setCaption(ss.str());
mLabel->adjustSize();
}
diff --git a/src/gui/widgets/avatar.h b/src/gui/widgets/avatar.h
index 32586668..dbe30a94 100644
--- a/src/gui/widgets/avatar.h
+++ b/src/gui/widgets/avatar.h
@@ -51,6 +51,8 @@ public:
void setMaxHp(int maxHp);
+ void setDisplayBold(bool displayBold) { mDisplayBold = displayBold; }
+
private:
void updateAvatarLabel();
@@ -59,6 +61,7 @@ private:
int mMaxHp;
Icon *mStatus;
gcn::Label *mLabel;
+ bool mDisplayBold;
};
#endif // AVATAR_H
diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp
index 711680d1..85353bf7 100644
--- a/src/gui/widgets/chattab.cpp
+++ b/src/gui/widgets/chattab.cpp
@@ -227,15 +227,19 @@ void ChatTab::chatInput(std::string &msg)
std::string temp = msg.substr(start + 1, end - start - 1);
- toLower(trim(temp));
-
- const ItemInfo itemInfo = ItemDB::get(temp);
- if (itemInfo.getName() != _("Unknown item"))
+ // Do not parse an empty string (it crashes the client)
+ if (!temp.empty())
{
- msg.insert(end, "@@");
- msg.insert(start+1, "|");
- msg.insert(start+1, toString(itemInfo.getId()));
- msg.insert(start+1, "@@");
+ toLower(trim(temp));
+
+ const ItemInfo itemInfo = ItemDB::get(temp);
+ if (itemInfo.getName() != _("Unknown item"))
+ {
+ msg.insert(end, "@@");
+ msg.insert(start+1, "|");
+ msg.insert(start+1, toString(itemInfo.getId()));
+ msg.insert(start+1, "@@");
+ }
}
}
start = msg.find('[', start + 1);
diff --git a/src/gui/widgets/progressbar.cpp b/src/gui/widgets/progressbar.cpp
index 58f24651..c673ffb3 100644
--- a/src/gui/widgets/progressbar.cpp
+++ b/src/gui/widgets/progressbar.cpp
@@ -31,6 +31,8 @@
#include "resources/image.h"
#include "resources/resourcemanager.h"
+#include "utils/dtor.h"
+
#include <guichan/font.hpp>
ImageRect ProgressBar::mBorder;
@@ -59,7 +61,7 @@ ProgressBar::ProgressBar(float progress,
mBorder.grid[1] = dBorders->getSubImage(4, 0, 3, 4);
mBorder.grid[2] = dBorders->getSubImage(7, 0, 4, 4);
mBorder.grid[3] = dBorders->getSubImage(0, 4, 4, 10);
- mBorder.grid[4] = resman->getImage("graphics/gui/bg_quad_dis.png");
+ mBorder.grid[4] = dBorders->getSubImage(4, 4, 3, 10);
mBorder.grid[5] = dBorders->getSubImage(7, 4, 4, 10);
mBorder.grid[6] = dBorders->getSubImage(0, 15, 4, 4);
mBorder.grid[7] = dBorders->getSubImage(4, 15, 3, 4);
@@ -82,15 +84,7 @@ ProgressBar::~ProgressBar()
if (mInstances == 0)
{
- delete mBorder.grid[0];
- delete mBorder.grid[1];
- delete mBorder.grid[2];
- delete mBorder.grid[3];
- mBorder.grid[4]->decRef();
- delete mBorder.grid[5];
- delete mBorder.grid[6];
- delete mBorder.grid[7];
- delete mBorder.grid[8];
+ for_each(mBorder.grid, mBorder.grid + 9, dtor<Image*>());
}
}
diff --git a/src/gui/windowmenu.cpp b/src/gui/windowmenu.cpp
index 5e33a4ed..8964f072 100644
--- a/src/gui/windowmenu.cpp
+++ b/src/gui/windowmenu.cpp
@@ -48,7 +48,6 @@ extern Window *guildWindow;
extern Window *magicDialog;
#endif
-
WindowMenu::WindowMenu():
mEmotePopup(0)
{
diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp
index b5db3de5..ca6804f4 100644
--- a/src/keyboardconfig.cpp
+++ b/src/keyboardconfig.cpp
@@ -80,6 +80,7 @@ static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = {
{"keyWindowDebug", SDLK_F10, _("Debug Window")},
{"keyWindowParty", SDLK_F11, _("Party Window")},
{"keyWindowEmoteBar", SDLK_F12, _("Emote Shortcut Window")},
+ {"keyWindowOutfit", SDLK_o, _("Outfits Window")},
{"keyEmoteShortcut1", SDLK_1, strprintf(_("Emote Shortcut %d"), 1)},
{"keyEmoteShortcut2", SDLK_2, strprintf(_("Emote Shortcut %d"), 2)},
{"keyEmoteShortcut3", SDLK_3, strprintf(_("Emote Shortcut %d"), 3)},
diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h
index 68a5efa6..b6a07f16 100644
--- a/src/keyboardconfig.h
+++ b/src/keyboardconfig.h
@@ -191,6 +191,7 @@ class KeyboardConfig
KEY_WINDOW_DEBUG,
KEY_WINDOW_PARTY,
KEY_WINDOW_EMOTE_SHORTCUT,
+ KEY_WINDOW_OUTFIT,
KEY_EMOTE_1,
KEY_EMOTE_2,
KEY_EMOTE_3,
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index c1423190..c9dc771d 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -193,6 +193,8 @@ void LocalPlayer::logic()
mLastTarget = -1;
}
+#endif
+
if (mTarget)
{
if (mTarget->getType() == Being::NPC)
@@ -203,13 +205,18 @@ void LocalPlayer::logic()
}
else
{
+#ifdef TMWSERV_SUPPORT
+ // Find whether target is in range
+ const int rangeX = abs(mTarget->getPosition().x - getPosition().x);
+ const int rangeY = abs(mTarget->getPosition().y - getPosition().y);
+#else
// Find whether target is in range
const int rangeX = abs(mTarget->mX - mX);
const int rangeY = abs(mTarget->mY - mY);
+#endif
const int attackRange = getAttackRange();
const int inRange = rangeX > attackRange || rangeY > attackRange
? 1 : 0;
-
mTarget->setTargetAnimation(
mTargetCursor[inRange][mTarget->getTargetCursorSize()]);
@@ -220,7 +227,6 @@ void LocalPlayer::logic()
attack(mTarget, true);
}
}
-#endif
Player::logic();
}
@@ -280,9 +286,7 @@ void LocalPlayer::nextStep()
if (mGoingToTarget && mTarget && withinAttackRange(mTarget))
{
mAction = Being::STAND;
-#ifdef EATHENA_SUPPORT
attack(mTarget, true);
-#endif
mGoingToTarget = false;
mPath.clear();
return;
@@ -606,7 +610,7 @@ void LocalPlayer::emote(Uint8 emotion)
}
#ifdef TMWSERV_SUPPORT
-
+/*
void LocalPlayer::attack()
{
if (mLastAction != -1)
@@ -656,16 +660,25 @@ void LocalPlayer::attack()
}
Net::GameServer::Player::attack(getSpriteDirection());
}
-
+*/
void LocalPlayer::useSpecial(int special)
{
Net::GameServer::Player::useSpecial(special);
}
-#else
+#endif
void LocalPlayer::attack(Being *target, bool keep)
{
+#ifdef TMWSERV_SUPPORT
+ if (mLastAction != -1)
+ return;
+
+ // Can only attack when standing still
+ if (mAction != STAND && mAction != ATTACK)
+ return;
+#endif
+
mKeepAttacking = keep;
if (!target || target->getType() == Being::NPC)
@@ -676,13 +689,19 @@ void LocalPlayer::attack(Being *target, bool keep)
mLastTarget = -1;
setTarget(target);
}
-
+#ifdef TMWSERV_SUPPORT
+ Vector plaPos = this->getPosition();
+ Vector tarPos = mTarget->getPosition();
+ int dist_x = plaPos.x - tarPos.x;
+ int dist_y = plaPos.y - tarPos.y;
+#else
int dist_x = target->mX - mX;
int dist_y = target->mY - mY;
// Must be standing to attack
if (mAction != STAND)
return;
+#endif
if (abs(dist_y) >= abs(dist_x))
{
@@ -699,8 +718,12 @@ void LocalPlayer::attack(Being *target, bool keep)
setDirection(LEFT);
}
+#ifdef TMWSERV_SUPPORT
+ mLastAction = tick_time;
+#else
mWalkTime = tick_time;
mTargetTime = tick_time;
+#endif
setAction(ATTACK);
@@ -715,22 +738,24 @@ void LocalPlayer::attack(Being *target, bool keep)
sound.playSfx("sfx/fist-swish.ogg");
}
- Net::getPlayerHandler()->attack(target);
-
+#ifdef TMWSERV_SUPPORT
+ if (mLastAction == STAND)
+#endif
+ Net::getPlayerHandler()->attack(target->getId());
+#ifdef EATHENA_SUPPORT
if (!keep)
stopAttack();
+#endif
}
-#endif // no TMWSERV_SUPPORT
-
void LocalPlayer::stopAttack()
{
if (mTarget)
{
- setAction(STAND);
- mLastTarget = -1;
+ if (mAction == ATTACK)
+ setAction(STAND);
+ setTarget(NULL);
}
- setTarget(NULL);
mLastTarget = -1;
}
@@ -812,8 +837,8 @@ void LocalPlayer::setXp(int xp)
// Show XP number
particleEngine->addTextRiseFadeOutEffect(
text,
- getPixelX() + 16,
- getPixelY() - 16,
+ getPixelX(),
+ getPixelY() - 48,
&guiPalette->getColor(Palette::EXP_INFO),
gui->getInfoParticleFont(), true);
}
@@ -829,8 +854,8 @@ void LocalPlayer::pickedUp(const std::string &item)
// Show pickup notification
particleEngine->addTextRiseFadeOutEffect(
item,
- getPixelX() + 16,
- getPixelY() - 16,
+ getPixelX(),
+ getPixelY() - 48,
&guiPalette->getColor(Palette::PICKUP_INFO),
gui->getInfoParticleFont(), true);
}
@@ -845,7 +870,7 @@ int LocalPlayer::getAttackRange()
const ItemInfo info = weapon->getInfo();
return info.getAttackRange();
}
- return 32; // unarmed range
+ return 48; // unarmed range
#else
return mAttackRange;
#endif
@@ -946,7 +971,8 @@ void LocalPlayer::initTargetCursor()
true, TC_LARGE);
}
-void LocalPlayer::loadTargetCursor(std::string filename, int width, int height,
+void LocalPlayer::loadTargetCursor(const std::string &filename,
+ int width, int height,
bool outRange, TargetCursorSize size)
{
assert(size > -1);
diff --git a/src/localplayer.h b/src/localplayer.h
index add5c049..85681e03 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -214,11 +214,9 @@ class LocalPlayer : public Player
void setTrading(bool trading) { mTrading = trading; }
#ifdef TMWSERV_SUPPORT
- void attack();
void useSpecial(int id);
-#else
- void attack(Being *target = NULL, bool keep = false);
#endif
+ void attack(Being *target = NULL, bool keep = false);
/**
* Triggers whether or not to show the name as a GM name.
@@ -490,7 +488,8 @@ class LocalPlayer : public Player
/**
* Helper function for loading target cursors
*/
- void loadTargetCursor(std::string filename, int width, int height,
+ void loadTargetCursor(const std::string &filename,
+ int width, int height,
bool outRange, Being::TargetCursorSize size);
/** Images of the target cursor. */
diff --git a/src/main.cpp b/src/main.cpp
index 40b30899..7c48e728 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -126,6 +126,12 @@
#include <sys/stat.h>
#endif
+#ifdef TWMSERV_SUPPORT
+#define DEFAULT_PORT 9601
+#else
+#define DEFAULT_PORT 6901
+#endif
+
namespace
{
struct SetupListener : public gcn::ActionListener
@@ -159,8 +165,9 @@ extern Net::Connection *accountServerConnection;
#endif
Graphics *graphics;
+Game *game = 0;
-unsigned char state;
+State state = STATE_NULL;
std::string errorMessage;
Sound sound;
@@ -214,6 +221,7 @@ struct Options
std::string configPath;
std::string updateHost;
std::string dataPath;
+ std::string homeDir;
std::string serverName;
short serverPort;
@@ -302,11 +310,16 @@ static void setUpdatesDir()
* Initializes the home directory. On UNIX and FreeBSD, ~/.tmw is used. On
* Windows and other systems we use the current working directory.
*/
-static void initHomeDir()
+static void initHomeDir(const Options &options)
{
- homeDir = std::string(PHYSFS_getUserDir()) +
- "/." +
- branding.getValue("appShort", "tmw");
+ homeDir = options.homeDir;
+
+ if (homeDir.empty())
+ {
+ homeDir = std::string(PHYSFS_getUserDir()) +
+ "/." +
+ branding.getValue("appShort", "tmw");
+ }
#if defined WIN32
if (!CreateDirectory(homeDir.c_str(), 0) &&
GetLastError() != ERROR_ALREADY_EXISTS)
@@ -340,11 +353,7 @@ static void initConfiguration(const Options &options)
std::string defaultHost = branding.getValue("defaultServer",
"server.themanaworld.org");
config.setValue("host", defaultHost);
-#ifdef TWMSERV_SUPPORT
- int defaultPort = (int)branding.getValue("defaultPort", 9601);
-#else
- int defaultPort = (int)branding.getValue("defaultPort", 6901);
-#endif
+ int defaultPort = (int)branding.getValue("defaultPort", DEFAULT_PORT);
config.setValue("port", defaultPort);
config.setValue("hwaccel", false);
#if (defined __APPLE__ || defined WIN32) && defined USE_OPENGL
@@ -659,7 +668,7 @@ static void parseOptions(int argc, char *argv[], Options &options)
options.printVersion = true;
break;
case 'S':
- homeDir = optarg;
+ options.homeDir = optarg;
break;
case 'O':
options.noOpenGL = true;
@@ -893,7 +902,7 @@ int main(int argc, char *argv[])
// Load branding information
branding.init("data/branding.xml");
- initHomeDir();
+ initHomeDir(options);
// Configure logger
logger = new Logger;
@@ -910,7 +919,6 @@ int main(int argc, char *argv[])
// Needs to be created in main, as the updater uses it
guiPalette = new Palette;
- Game *game = NULL;
Window *currentDialog = NULL;
#ifdef TMWSERV_SUPPORT
QuitDialog* quitDialog = NULL;
@@ -947,7 +955,7 @@ int main(int argc, char *argv[])
"server.themanaworld.org").c_str();
}
if (options.serverPort == 0) {
- loginData.port = (short) branding.getValue("defaultPort", 9601);
+ loginData.port = (short) branding.getValue("defaultPort", DEFAULT_PORT);
}
if (loginData.username.empty() && loginData.remember) {
loginData.username = config.getValue("username", "");
@@ -969,7 +977,7 @@ int main(int argc, char *argv[])
desktop->setSize(screenWidth, screenHeight);
- unsigned int oldstate = !state; // We start with a status change.
+ State oldstate = STATE_EXIT; // We start with a status change
SDL_Event event;
@@ -1290,6 +1298,7 @@ int main(int argc, char *argv[])
game = new Game;
game->logic();
delete game;
+ game = 0;
state = STATE_EXIT;
@@ -1422,9 +1431,9 @@ int main(int argc, char *argv[])
}
else
{
- int nextState = STATE_UPDATE;
+ State nextState = STATE_UPDATE;
currentDialog = new ServerSelectDialog(&loginData,
- nextState);
+ nextState);
positionDialog(currentDialog, screenWidth,
screenHeight);
if (options.chooseDefault)
@@ -1467,9 +1476,9 @@ int main(int argc, char *argv[])
desktop = NULL;
logger->log("State: GAME");
- game = new Game;
game->logic();
delete game;
+ game = 0;
state = STATE_EXIT;
break;
diff --git a/src/main.h b/src/main.h
index 49a034f5..75343944 100644
--- a/src/main.h
+++ b/src/main.h
@@ -78,7 +78,7 @@
/*
* Client different States
*/
-enum {
+enum State {
STATE_EXIT,
STATE_LOADDATA,
STATE_LOGIN,
@@ -107,15 +107,16 @@ enum {
STATE_LOGOUT_ATTEMPT,
STATE_CONNECT_GAME,
STATE_WAIT,
- STATE_FORCE_QUIT
+ STATE_FORCE_QUIT,
#else
STATE_ACCOUNT,
STATE_CHAR_CONNECT,
STATE_CHAR_SERVER,
STATE_CHAR_NEW,
STATE_CHAR_DEL,
- STATE_CONNECTING
+ STATE_CONNECTING,
#endif
+ STATE_NULL
};
/* length definitions for several char[]s in order
@@ -135,7 +136,7 @@ const short maxSlot = 2;
extern std::string token;
extern char n_server, n_character;
-extern unsigned char state;
+extern State state;
extern std::string errorMessage;
#endif
diff --git a/src/net/ea/maphandler.cpp b/src/net/ea/maphandler.cpp
index 76b3c480..c7ff0ec7 100644
--- a/src/net/ea/maphandler.cpp
+++ b/src/net/ea/maphandler.cpp
@@ -27,6 +27,7 @@
#include "net/messagein.h"
#include "net/messageout.h"
+#include "game.h"
#include "localplayer.h"
#include "log.h"
#include "main.h"
@@ -37,6 +38,7 @@
#include "utils/stringutils.h"
Net::MapHandler *mapHandler;
+extern Game *game;
namespace EAthena {
@@ -65,6 +67,7 @@ void MapHandler::handleMessage(MessageIn &msg)
logger->log("Protocol: Player start position: (%d, %d), Direction: %d",
player_node->mX, player_node->mY, direction);
state = STATE_GAME;
+ game = new Game;
break;
case SMSG_SERVER_PING:
diff --git a/src/net/ea/playerhandler.cpp b/src/net/ea/playerhandler.cpp
index b7131f0a..8cc4b44f 100644
--- a/src/net/ea/playerhandler.cpp
+++ b/src/net/ea/playerhandler.cpp
@@ -422,10 +422,10 @@ void PlayerHandler::handleMessage(MessageIn &msg)
}
}
-void PlayerHandler::attack(Being *being)
+void PlayerHandler::attack(int id)
{
MessageOut outMsg(CMSG_PLAYER_ATTACK);
- outMsg.writeInt32(being->getId());
+ outMsg.writeInt32(id);
outMsg.writeInt8(0);
}
diff --git a/src/net/ea/playerhandler.h b/src/net/ea/playerhandler.h
index 94ae952f..4429d856 100644
--- a/src/net/ea/playerhandler.h
+++ b/src/net/ea/playerhandler.h
@@ -35,7 +35,7 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
void handleMessage(MessageIn &msg);
- void attack(Being *being);
+ void attack(int id);
void emote(int emoteId);
diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h
index 0998da04..c51c59c0 100644
--- a/src/net/playerhandler.h
+++ b/src/net/playerhandler.h
@@ -31,7 +31,7 @@ namespace Net {
class PlayerHandler
{
public:
- virtual void attack(Being *being) = 0;
+ virtual void attack(int id) = 0;
virtual void emote(int emoteId) = 0;
diff --git a/src/net/tmwserv/gameserver/player.cpp b/src/net/tmwserv/gameserver/player.cpp
index 3f05c954..93853681 100644
--- a/src/net/tmwserv/gameserver/player.cpp
+++ b/src/net/tmwserv/gameserver/player.cpp
@@ -58,13 +58,6 @@ void Net::GameServer::Player::moveItem(int oldSlot, int newSlot, int amount)
Net::GameServer::connection->send(msg);
}
-void Net::GameServer::Player::attack(int direction)
-{
- MessageOut msg(PGMSG_ATTACK);
- msg.writeInt8(direction);
- Net::GameServer::connection->send(msg);
-}
-
void Net::GameServer::Player::useSpecial(int special)
{
MessageOut msg(PGMSG_USE_SPECIAL);
diff --git a/src/net/tmwserv/gameserver/player.h b/src/net/tmwserv/gameserver/player.h
index eddd9102..24b25dc7 100644
--- a/src/net/tmwserv/gameserver/player.h
+++ b/src/net/tmwserv/gameserver/player.h
@@ -43,7 +43,6 @@ namespace Net
void walk(int x, int y);
void pickUp(int x, int y);
void moveItem(int oldSlot, int newSlot, int amount);
- void attack(int direction);
void useSpecial(int special);
void requestTrade(int id);
void acceptTrade(bool accept);
diff --git a/src/net/tmwserv/playerhandler.cpp b/src/net/tmwserv/playerhandler.cpp
index b697e8a8..543d18d8 100644
--- a/src/net/tmwserv/playerhandler.cpp
+++ b/src/net/tmwserv/playerhandler.cpp
@@ -332,9 +332,11 @@ void PlayerHandler::handleMapChangeMessage(MessageIn &msg)
viewport->scrollBy(scrollOffsetX, scrollOffsetY);
}
-void PlayerHandler::attack(Being *being)
+void PlayerHandler::attack(int id)
{
- // TODO
+ MessageOut msg(PGMSG_ATTACK);
+ msg.writeInt16(id);
+ Net::GameServer::connection->send(msg);
}
void PlayerHandler::emote(int emoteId)
diff --git a/src/net/tmwserv/playerhandler.h b/src/net/tmwserv/playerhandler.h
index 5524415e..238da182 100644
--- a/src/net/tmwserv/playerhandler.h
+++ b/src/net/tmwserv/playerhandler.h
@@ -34,7 +34,7 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
void handleMessage(MessageIn &msg);
- void attack(Being *being);
+ void attack(int id);
void emote(int emoteId);
diff --git a/src/net/tmwserv/protocol.h b/src/net/tmwserv/protocol.h
index 7fa3b372..6124263a 100644
--- a/src/net/tmwserv/protocol.h
+++ b/src/net/tmwserv/protocol.h
@@ -106,7 +106,7 @@ enum {
GPMSG_BEING_DIR_CHANGE = 0x0273, // W being id, B direction
GPMSG_BEINGS_MOVE = 0x0280, // { W being id, B flags [, C position, B speed] [, W*2 destination] }*
GPMSG_ITEMS = 0x0281, // { W item id, W*2 position }*
- PGMSG_ATTACK = 0x0290, // B direction
+ PGMSG_ATTACK = 0x0290, // W being id
PGMSG_USE_SPECIAL = 0x0292, // B specialID
GPMSG_BEING_ATTACK = 0x0291, // W being id
PGMSG_SAY = 0x02A0, // S text
@@ -162,9 +162,11 @@ enum {
CPMSG_GUILD_QUIT_RESPONSE = 0x0361, // B error
PCMSG_GUILD_PROMOTE_MEMBER = 0x0365, // W guild, S name, B rights
CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE = 0x0366, // B error
+ PCMSG_GUILD_KICK_MEMBER = 0x0370, // W guild, S name
+ CPMSG_GUILD_KICK_MEMBER_RESPONSE = 0x0371, // B error
- CPMSG_GUILD_INVITED = 0x0370, // S char name, S guild name, W id
- CPMSG_GUILD_REJOIN = 0x0371, // S name, W guild, W rights, W channel, S announce
+ CPMSG_GUILD_INVITED = 0x0388, // S char name, S guild name, W id
+ CPMSG_GUILD_REJOIN = 0x0389, // S name, W guild, W rights, W channel, S announce
// Party
PCMSG_PARTY_INVITE = 0x03A0, // S name
diff --git a/src/resources/colordb.cpp b/src/resources/colordb.cpp
index af498297..e5377aa6 100644
--- a/src/resources/colordb.cpp
+++ b/src/resources/colordb.cpp
@@ -27,9 +27,6 @@
#include <libxml/tree.h>
-#define HAIR_COLOR_FILE "colors.xml"
-#define TMW_COLOR_FILE "hair.xml"
-
namespace
{
ColorDB::Colors mColors;
@@ -42,23 +39,23 @@ void ColorDB::load()
if (mLoaded)
return;
- XML::Document *doc = new XML::Document(HAIR_COLOR_FILE);
+ XML::Document *doc = new XML::Document("hair.xml");
xmlNodePtr root = doc->rootNode();
- bool TMWHair = false;
+ bool hairXml = true;
if (!root || !xmlStrEqual(root->name, BAD_CAST "colors"))
{
- logger->log("Trying TMW's color file, %s.", TMW_COLOR_FILE);
+ logger->log("Trying to fall back on colors.xml");
- TMWHair = true;
+ hairXml = false;
delete doc;
-
- doc = new XML::Document(TMW_COLOR_FILE);
+ doc = new XML::Document("colors.xml");
root = doc->rootNode();
+
if (!root || !xmlStrEqual(root->name, BAD_CAST "colors"))
{
- logger->log("ColorDB: Failed");
+ logger->log("ColorDB: Failed to find any color files.");
mColors[0] = mFail;
mLoaded = true;
@@ -78,8 +75,8 @@ void ColorDB::load()
logger->log("ColorDB: Redefinition of dye ID %d", id);
}
- TMWHair ? mColors[id] = XML::getProperty(node, "value", "#FFFFFF") :
- mColors[id] = XML::getProperty(node, "dye", "#FFFFFF");
+ mColors[id] = hairXml ? XML::getProperty(node, "value", "#FFFFFF") :
+ XML::getProperty(node, "dye", "#FFFFFF");
}
}
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index 99907ca7..fa31c556 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -210,6 +210,10 @@ void ItemDB::load()
}
}
+ if (weaponType > 0)
+ if (attackRange == 0)
+ logger->log("ItemDB: Missing attack range from weapon %i!", id);
+
#define CHECK_PARAM(param, error_value) \
if (param == error_value) \
logger->log("ItemDB: Missing " #param " attribute for item %i!",id)
diff --git a/src/textparticle.cpp b/src/textparticle.cpp
index 04b7abe1..da176087 100644
--- a/src/textparticle.cpp
+++ b/src/textparticle.cpp
@@ -26,7 +26,7 @@
#include "gui/textrenderer.h"
TextParticle::TextParticle(Map *map, const std::string &text,
- const gcn::Color* color,
+ const gcn::Color *color,
gcn::Font *font, bool outline):
Particle(map),
mText(text),
@@ -47,18 +47,15 @@ void TextParticle::draw(Graphics *graphics, int offsetX, int offsetY) const
float alpha = mAlpha * 255.0f;
if (mLifetimeLeft > -1 && mLifetimeLeft < mFadeOut)
- {
- alpha *= mLifetimeLeft;
- alpha /= mFadeOut;
- }
+ alpha = alpha * mLifetimeLeft / mFadeOut;
if (mLifetimePast < mFadeIn)
- {
- alpha *= mLifetimePast;
- alpha /= mFadeIn;
- }
+ alpha = alpha * mLifetimePast / mFadeIn;
+
+ gcn::Color color = *mColor;
+ color.a = (int) alpha;
TextRenderer::renderText(graphics, mText,
screenX, screenY, gcn::Graphics::CENTER,
- *mColor, mTextFont, mOutline, false, (int) alpha);
+ color, mTextFont, mOutline, false, (int) alpha);
}
diff --git a/src/textparticle.h b/src/textparticle.h
index 8b7d3e01..a87137ea 100644
--- a/src/textparticle.h
+++ b/src/textparticle.h
@@ -47,7 +47,7 @@ class TextParticle : public Particle
private:
std::string mText; /**< Text of the particle. */
gcn::Font *mTextFont; /**< Font used for drawing the text. */
- const gcn::Color* mColor; /**< Color used for drawing the text. */
+ const gcn::Color *mColor; /**< Color used for drawing the text. */
bool mOutline; /**< Make the text better readable */
};
diff --git a/tmw.cbp b/tmw.cbp
index 4ab0cebf..b1332b5f 100644
--- a/tmw.cbp
+++ b/tmw.cbp
@@ -218,10 +218,10 @@
<Option target="TMWServ" />
<Option target="Unix TMWSERV" />
</Unit>
- <Unit filename="src/gui/charselectdialog.cpp" />
- <Unit filename="src/gui/charselectdialog.h" />
<Unit filename="src/gui/charcreatedialog.cpp" />
<Unit filename="src/gui/charcreatedialog.h" />
+ <Unit filename="src/gui/charselectdialog.cpp" />
+ <Unit filename="src/gui/charselectdialog.h" />
<Unit filename="src/gui/chat.cpp" />
<Unit filename="src/gui/chat.h" />
<Unit filename="src/gui/confirmdialog.cpp" />
@@ -285,18 +285,18 @@
<Unit filename="src/gui/minimap.h" />
<Unit filename="src/gui/ministatus.cpp" />
<Unit filename="src/gui/ministatus.h" />
- <Unit filename="src/gui/npctextdialog.cpp" />
- <Unit filename="src/gui/npctextdialog.h" />
- <Unit filename="src/gui/npcintegerdialog.cpp" />
+ <Unit filename="src/gui/npcdialog.cpp" />
+ <Unit filename="src/gui/npcdialog.h" />
<Unit filename="src/gui/npcintegerdialog.h" />
- <Unit filename="src/gui/npclistdialog.cpp" />
<Unit filename="src/gui/npclistdialog.h" />
<Unit filename="src/gui/npcpostdialog.cpp" />
<Unit filename="src/gui/npcpostdialog.h" />
- <Unit filename="src/gui/npcstringdialog.cpp" />
<Unit filename="src/gui/npcstringdialog.h" />
+ <Unit filename="src/gui/npctextdialog.h" />
<Unit filename="src/gui/okdialog.cpp" />
<Unit filename="src/gui/okdialog.h" />
+ <Unit filename="src/gui/outfitwindow.cpp" />
+ <Unit filename="src/gui/outfitwindow.h" />
<Unit filename="src/gui/palette.cpp" />
<Unit filename="src/gui/palette.h" />
<Unit filename="src/gui/partywindow.cpp" />
@@ -510,7 +510,6 @@
<Unit filename="src/lockedarray.h" />
<Unit filename="src/log.cpp" />
<Unit filename="src/log.h" />
- <Unit filename="src/logindata.h" />
<Unit filename="src/main.cpp" />
<Unit filename="src/main.h" />
<Unit filename="src/map.cpp" />
@@ -1006,7 +1005,8 @@
<Unit filename="src/resources/spritedef.h" />
<Unit filename="src/resources/wallpaper.cpp" />
<Unit filename="src/resources/wallpaper.h" />
- <Unit filename="src/serverinfo.h" />
+ <Unit filename="src/rotationalparticle.cpp" />
+ <Unit filename="src/rotationalparticle.h" />
<Unit filename="src/shopitem.cpp" />
<Unit filename="src/shopitem.h" />
<Unit filename="src/simpleanimation.cpp" />