summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhilipp Sehmisch <crush@themanaworld.org>2009-08-16 17:47:51 +0200
committerPhilipp Sehmisch <crush@themanaworld.org>2009-08-16 17:47:51 +0200
commite0ba8f7f67ddd08c54f0d453a316b3620d52529d (patch)
tree7324fa33f2c6af04067b77e0ce7f73d9effed1c6 /src
parent346d68307553c18777df4c49f9b3fe57955c5c0d (diff)
parent6460413ee2f50be561fd0824e3eaa9c2c09415b1 (diff)
downloadmana-client-e0ba8f7f67ddd08c54f0d453a316b3620d52529d.tar.gz
mana-client-e0ba8f7f67ddd08c54f0d453a316b3620d52529d.tar.bz2
mana-client-e0ba8f7f67ddd08c54f0d453a316b3620d52529d.tar.xz
mana-client-e0ba8f7f67ddd08c54f0d453a316b3620d52529d.zip
Merged changes from last month with a commit I forgot to commit before I went on vacation.
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt26
-rw-r--r--src/Makefile.am26
-rw-r--r--src/being.cpp50
-rw-r--r--src/being.h28
-rw-r--r--src/beingmanager.cpp13
-rw-r--r--src/commandhandler.cpp4
-rw-r--r--src/engine.cpp2
-rw-r--r--src/equipment.cpp36
-rw-r--r--src/equipment.h56
-rw-r--r--src/game.cpp21
-rw-r--r--src/graphics.cpp83
-rw-r--r--src/graphics.h32
-rw-r--r--src/gui/buy.cpp14
-rw-r--r--src/gui/buysell.cpp2
-rw-r--r--src/gui/changeemaildialog.cpp20
-rw-r--r--src/gui/changepassworddialog.cpp19
-rw-r--r--src/gui/charcreatedialog.cpp16
-rw-r--r--src/gui/charselectdialog.cpp11
-rw-r--r--src/gui/chat.cpp44
-rw-r--r--src/gui/chat.h5
-rw-r--r--src/gui/connectiondialog.cpp2
-rw-r--r--src/gui/debugwindow.cpp34
-rw-r--r--src/gui/debugwindow.h2
-rw-r--r--src/gui/emoteshortcutcontainer.cpp2
-rw-r--r--src/gui/equipmentwindow.cpp65
-rw-r--r--src/gui/equipmentwindow.h47
-rw-r--r--src/gui/guildwindow.cpp22
-rw-r--r--src/gui/help.cpp2
-rw-r--r--src/gui/inventorywindow.cpp2
-rw-r--r--src/gui/itemamount.cpp10
-rw-r--r--src/gui/itempopup.cpp5
-rw-r--r--src/gui/login.cpp2
-rw-r--r--src/gui/magic.cpp2
-rw-r--r--src/gui/minimap.cpp4
-rw-r--r--src/gui/ministatus.cpp86
-rw-r--r--src/gui/ministatus.h18
-rw-r--r--src/gui/npcdialog.cpp13
-rw-r--r--src/gui/outfitwindow.cpp14
-rw-r--r--src/gui/palette.cpp17
-rw-r--r--src/gui/palette.h3
-rw-r--r--src/gui/partywindow.cpp2
-rw-r--r--src/gui/popupmenu.cpp104
-rw-r--r--src/gui/recorder.cpp1
-rw-r--r--src/gui/register.cpp14
-rw-r--r--src/gui/sell.cpp10
-rw-r--r--src/gui/serverdialog.cpp2
-rw-r--r--src/gui/setup.cpp55
-rw-r--r--src/gui/setup.h6
-rw-r--r--src/gui/setup_audio.cpp2
-rw-r--r--src/gui/setup_colors.cpp13
-rw-r--r--src/gui/setup_keyboard.cpp2
-rw-r--r--src/gui/setup_video.cpp46
-rw-r--r--src/gui/shortcutwindow.cpp2
-rw-r--r--src/gui/skill.cpp300
-rw-r--r--src/gui/skill.h85
-rw-r--r--src/gui/skilldialog.cpp425
-rw-r--r--src/gui/skilldialog.h40
-rw-r--r--src/gui/speechbubble.cpp2
-rw-r--r--src/gui/status.cpp414
-rw-r--r--src/gui/status.h107
-rw-r--r--src/gui/statuswindow.cpp689
-rw-r--r--src/gui/statuswindow.h86
-rw-r--r--src/gui/storagewindow.cpp2
-rw-r--r--src/gui/trade.cpp9
-rw-r--r--src/gui/unregisterdialog.cpp19
-rw-r--r--src/gui/updatewindow.cpp10
-rw-r--r--src/gui/viewport.cpp10
-rw-r--r--src/gui/widgets/button.cpp5
-rw-r--r--src/gui/widgets/channeltab.cpp9
-rw-r--r--src/gui/widgets/chattab.cpp2
-rw-r--r--src/gui/widgets/checkbox.cpp46
-rw-r--r--src/gui/widgets/checkbox.h14
-rw-r--r--src/gui/widgets/desktop.cpp36
-rw-r--r--src/gui/widgets/desktop.h3
-rw-r--r--src/gui/widgets/progressbar.cpp9
-rw-r--r--src/gui/widgets/radiobutton.cpp47
-rw-r--r--src/gui/widgets/radiobutton.h17
-rw-r--r--src/gui/widgets/scrollarea.cpp47
-rw-r--r--src/gui/widgets/scrollarea.h18
-rw-r--r--src/gui/widgets/slider.cpp85
-rw-r--r--src/gui/widgets/slider.h13
-rw-r--r--src/gui/widgets/tab.cpp14
-rw-r--r--src/gui/widgets/tabbedarea.cpp10
-rw-r--r--src/gui/widgets/tabbedarea.h5
-rw-r--r--src/gui/widgets/vertcontainer.cpp53
-rw-r--r--src/gui/widgets/vertcontainer.h47
-rw-r--r--src/gui/widgets/whispertab.cpp4
-rw-r--r--src/gui/widgets/window.cpp67
-rw-r--r--src/gui/widgets/window.h9
-rw-r--r--src/gui/windowmenu.cpp4
-rw-r--r--src/inventory.cpp11
-rw-r--r--src/item.cpp2
-rw-r--r--src/localplayer.cpp356
-rw-r--r--src/localplayer.h176
-rw-r--r--src/main.cpp55
-rw-r--r--src/map.cpp49
-rw-r--r--src/map.h7
-rw-r--r--src/net/ea/beinghandler.cpp23
-rw-r--r--src/net/ea/charserverhandler.cpp33
-rw-r--r--src/net/ea/chathandler.cpp2
-rw-r--r--src/net/ea/equipmenthandler.cpp193
-rw-r--r--src/net/ea/equipmenthandler.h6
-rw-r--r--src/net/ea/generalhandler.cpp42
-rw-r--r--src/net/ea/generalhandler.h2
-rw-r--r--src/net/ea/inventoryhandler.cpp45
-rw-r--r--src/net/ea/loginhandler.cpp22
-rw-r--r--src/net/ea/maphandler.cpp20
-rw-r--r--src/net/ea/network.cpp6
-rw-r--r--src/net/ea/partyhandler.cpp1
-rw-r--r--src/net/ea/playerhandler.cpp290
-rw-r--r--src/net/ea/playerhandler.h8
-rw-r--r--src/net/ea/protocol.h25
-rw-r--r--src/net/ea/specialhandler.cpp (renamed from src/net/ea/skillhandler.cpp)87
-rw-r--r--src/net/ea/specialhandler.h (renamed from src/net/ea/skillhandler.h)14
-rw-r--r--src/net/net.cpp8
-rw-r--r--src/net/net.h4
-rw-r--r--src/net/playerhandler.h8
-rw-r--r--src/net/specialhandler.h (renamed from src/net/skillhandler.h)16
-rw-r--r--src/net/tmwserv/beinghandler.cpp64
-rw-r--r--src/net/tmwserv/charserverhandler.cpp38
-rw-r--r--src/net/tmwserv/chathandler.cpp31
-rw-r--r--src/net/tmwserv/gameserver/player.cpp49
-rw-r--r--src/net/tmwserv/gameserver/player.h7
-rw-r--r--src/net/tmwserv/generalhandler.cpp12
-rw-r--r--src/net/tmwserv/loginhandler.cpp42
-rw-r--r--src/net/tmwserv/partyhandler.cpp7
-rw-r--r--src/net/tmwserv/playerhandler.cpp57
-rw-r--r--src/net/tmwserv/playerhandler.h8
-rw-r--r--src/net/tmwserv/protocol.h4
-rw-r--r--src/net/tmwserv/specialhandler.cpp (renamed from src/net/tmwserv/skillhandler.cpp)27
-rw-r--r--src/net/tmwserv/specialhandler.h (renamed from src/net/tmwserv/skillhandler.h)14
-rw-r--r--src/net/tmwserv/tradehandler.cpp12
-rw-r--r--src/openglgraphics.cpp110
-rw-r--r--src/openglgraphics.h16
-rw-r--r--src/player.cpp15
-rw-r--r--src/player.h5
-rw-r--r--src/playerrelations.cpp11
-rw-r--r--src/properties.h22
-rw-r--r--src/resources/ambientoverlay.cpp42
-rw-r--r--src/resources/ambientoverlay.h5
-rw-r--r--src/resources/image.cpp61
-rw-r--r--src/resources/image.h16
-rw-r--r--src/resources/itemdb.cpp2
-rw-r--r--src/resources/resourcemanager.cpp13
-rw-r--r--src/resources/resourcemanager.h9
-rw-r--r--src/resources/sdlrescalefacility.cpp489
-rw-r--r--src/resources/sdlrescalefacility.h52
147 files changed, 3610 insertions, 3022 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 91fe8e06..43726f9d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -110,6 +110,8 @@ SET(SRCS
gui/widgets/textfield.h
gui/widgets/textpreview.cpp
gui/widgets/textpreview.h
+ gui/widgets/vertcontainer.cpp
+ gui/widgets/vertcontainer.h
gui/widgets/whispertab.cpp
gui/widgets/whispertab.h
gui/widgets/window.cpp
@@ -213,10 +215,14 @@ SET(SRCS
gui/shortcutcontainer.h
gui/shortcutwindow.cpp
gui/shortcutwindow.h
+ gui/skilldialog.cpp
+ gui/skilldialog.h
gui/skin.cpp
gui/skin.h
gui/speechbubble.cpp
gui/speechbubble.h
+ gui/statuswindow.cpp
+ gui/statuswindow.h
gui/storagewindow.cpp
gui/storagewindow.h
gui/table.cpp
@@ -258,7 +264,7 @@ SET(SRCS
net/partyhandler.h
net/playerhandler.h
net/serverinfo.h
- net/skillhandler.h
+ net/specialhandler.h
net/tradehandler.h
resources/action.cpp
resources/action.h
@@ -298,6 +304,8 @@ SET(SRCS
resources/resource.h
resources/resourcemanager.cpp
resources/resourcemanager.h
+ resources/sdlrescalefacility.h
+ resources/sdlrescalefacility.cpp
resources/soundeffect.h
resources/soundeffect.cpp
resources/spritedef.h
@@ -416,10 +424,6 @@ SET(SRCS
)
SET(SRCS_EA
- gui/skill.cpp
- gui/skill.h
- gui/status.cpp
- gui/status.h
net/ea/gui/partytab.cpp
net/ea/gui/partytab.h
net/ea/adminhandler.cpp
@@ -455,8 +459,8 @@ SET(SRCS_EA
net/ea/playerhandler.cpp
net/ea/playerhandler.h
net/ea/protocol.h
- net/ea/skillhandler.cpp
- net/ea/skillhandler.h
+ net/ea/specialhandler.cpp
+ net/ea/specialhandler.h
net/ea/tradehandler.cpp
net/ea/tradehandler.h
)
@@ -478,10 +482,6 @@ SET(SRCS_TMW
gui/quitdialog.h
gui/serverdialog.cpp
gui/serverdialog.h
- gui/skilldialog.cpp
- gui/skilldialog.h
- gui/statuswindow.cpp
- gui/statuswindow.h
gui/unregisterdialog.cpp
gui/unregisterdialog.h
net/tmwserv/accountserver/account.cpp
@@ -543,8 +543,8 @@ SET(SRCS_TMW
net/tmwserv/playerhandler.cpp
net/tmwserv/playerhandler.h
net/tmwserv/protocol.h
- net/tmwserv/skillhandler.cpp
- net/tmwserv/skillhandler.h
+ net/tmwserv/specialhandler.cpp
+ net/tmwserv/specialhandler.h
net/tmwserv/tradehandler.cpp
net/tmwserv/tradehandler.h
guild.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index 23de64bc..25fdb140 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,6 +59,8 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
gui/widgets/textfield.h \
gui/widgets/textpreview.cpp \
gui/widgets/textpreview.h \
+ gui/widgets/vertcontainer.cpp \
+ gui/widgets/vertcontainer.h \
gui/widgets/whispertab.cpp \
gui/widgets/whispertab.h \
gui/widgets/window.cpp \
@@ -162,10 +164,14 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
gui/shortcutcontainer.h \
gui/shortcutwindow.cpp \
gui/shortcutwindow.h \
+ gui/skilldialog.cpp \
+ gui/skilldialog.h \
gui/skin.cpp \
gui/skin.h \
gui/speechbubble.cpp \
gui/speechbubble.h \
+ gui/statuswindow.cpp \
+ gui/statuswindow.h \
gui/storagewindow.cpp \
gui/storagewindow.h \
gui/table.cpp \
@@ -207,7 +213,7 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
net/partyhandler.h \
net/playerhandler.h \
net/serverinfo.h \
- net/skillhandler.h \
+ net/specialhandler.h \
net/tradehandler.h \
resources/action.cpp \
resources/action.h \
@@ -247,6 +253,8 @@ tmw_SOURCES = gui/widgets/avatar.cpp \
resources/resource.h \
resources/resourcemanager.cpp \
resources/resourcemanager.h \
+ resources/sdlrescalefacility.cpp \
+ resources/sdlrescalefacility.h \
resources/soundeffect.h \
resources/soundeffect.cpp \
resources/spritedef.h \
@@ -382,10 +390,6 @@ tmw_SOURCES += \
gui/quitdialog.h \
gui/serverdialog.cpp \
gui/serverdialog.h \
- gui/skilldialog.cpp \
- gui/skilldialog.h \
- gui/statuswindow.cpp \
- gui/statuswindow.h \
gui/unregisterdialog.cpp \
gui/unregisterdialog.h \
net/tmwserv/accountserver/account.cpp \
@@ -447,8 +451,8 @@ tmw_SOURCES += \
net/tmwserv/playerhandler.cpp \
net/tmwserv/playerhandler.h \
net/tmwserv/protocol.h \
- net/tmwserv/skillhandler.cpp \
- net/tmwserv/skillhandler.h \
+ net/tmwserv/specialhandler.cpp \
+ net/tmwserv/specialhandler.h \
net/tmwserv/tradehandler.cpp \
net/tmwserv/tradehandler.h \
guild.cpp \
@@ -458,10 +462,6 @@ endif
if SERVER_EATHENA
tmw_CXXFLAGS += -DEATHENA_SUPPORT
tmw_SOURCES += \
- gui/skill.cpp \
- gui/skill.h \
- gui/status.cpp \
- gui/status.h \
net/ea/gui/partytab.cpp \
net/ea/gui/partytab.h \
net/ea/adminhandler.cpp \
@@ -497,8 +497,8 @@ tmw_SOURCES += \
net/ea/playerhandler.cpp \
net/ea/playerhandler.h \
net/ea/protocol.h \
- net/ea/skillhandler.cpp \
- net/ea/skillhandler.h \
+ net/ea/specialhandler.cpp \
+ net/ea/specialhandler.h \
net/ea/tradehandler.cpp \
net/ea/tradehandler.h
endif
diff --git a/src/being.cpp b/src/being.cpp
index ea587afb..23b87e6c 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -49,7 +49,6 @@
#include "gui/speechbubble.h"
#include "utils/dtor.h"
-#include "utils/gettext.h"
#include "utils/stringutils.h"
#include "utils/xml.h"
@@ -66,7 +65,6 @@ static const int DEFAULT_HEIGHT = 32;
Being::Being(int id, int job, Map *map):
#ifdef EATHENA_SUPPORT
- mX(0), mY(0),
mWalkTime(0),
#endif
mEmotion(0), mEmotionTime(0),
@@ -100,6 +98,7 @@ Being::Being(int id, int job, Map *map):
mWalkSpeed(150),
#endif
mPx(0), mPy(0),
+ mX(0), mY(0),
mUsedTargetCursor(NULL)
{
setMap(map);
@@ -148,37 +147,21 @@ void Being::setDestination(Uint16 destX, Uint16 destY)
#endif
#ifdef TMWSERV_SUPPORT
-
-void Being::adjustCourse(int srcX, int srcY)
-{
- setDestination(srcX, srcY, mDest.x, mDest.y);
-}
-
void Being::setDestination(int dstX, int dstY)
{
- setDestination(mPos.x, mPos.y, dstX, dstY);
-}
+ mDest.x = dstX;
+ mDest.y = dstY;
+ int srcX = mPos.x;
+ int srcY = mPos.y;
-Path Being::findPath()
-{
- Path path;
+ Path thisPath;
if (mMap)
{
- path = mMap->findPath(mPos.x / 32, mPos.y / 32,
- mDest.x / 32, mDest.y / 32, getWalkMask());
+ thisPath = mMap->findPath(mPos.x / 32, mPos.y / 32,
+ mDest.x / 32, mDest.y / 32, getWalkMask());
}
- return path;
-}
-
-void Being::setDestination(int srcX, int srcY, int dstX, int dstY)
-{
- mDest.x = dstX;
- mDest.y = dstY;
-
- Path thisPath = findPath();
-
if (thisPath.empty())
{
setPath(Path());
@@ -188,16 +171,13 @@ void Being::setDestination(int srcX, int srcY, int dstX, int dstY)
// FIXME: Look into making this code neater.
// Interpolate the offsets. Also convert from tile based to pixel based
- // Note: I divided the offsets by 32 then muilpied it back to get the top left
- // Conner of where the tile is. (If you know a better way then please change it)
-
// Find the starting offset
- int startX = srcX - ((srcX / 32) * 32 + 16);
- int startY = srcY - ((srcY / 32) * 32 + 16);
+ int startX = (srcX % 32);
+ int startY = (srcY % 32);
// Find the ending offset
- int endX = dstX - ((dstX / 32) * 32 + 16);
- int endY = dstY - ((dstY / 32) * 32 + 16);
+ int endX = (dstX % 32);
+ int endY = (dstY % 32);
// Find the distance, and divide it by the number of steps
int changeX = (endX - startX) / thisPath.size();
@@ -209,8 +189,8 @@ void Being::setDestination(int srcX, int srcY, int dstX, int dstY)
int i = 0;
while(it != thisPath.end())
{
- it->x = (it->x * 32 + 16) + startX + (changeX * i);
- it->y = (it->y * 32 + 16) + startY + (changeY * i);
+ it->x = (it->x * 32) + startX + (changeX * i);
+ it->y = (it->y * 32) + startY + (changeY * i);
i++;
it++;
}
@@ -228,7 +208,7 @@ void Being::setPath(const Path &path)
{
mPath = path;
#ifdef TMWSERV_SUPPORT
-// std::cout << this << " New path: " << path << std::endl;
+ std::cout << this << " New path: " << path << std::endl;
#else
if (mAction != WALK && mAction != DEAD)
{
diff --git a/src/being.h b/src/being.h
index 9213a2dc..6e90b39d 100644
--- a/src/being.h
+++ b/src/being.h
@@ -149,7 +149,6 @@ class Being : public Sprite, public ConfigListener
enum { DOWN = 1, LEFT = 2, UP = 4, RIGHT = 8 };
#ifdef EATHENA_SUPPORT
- Uint16 mX, mY; /**< Tile coordinates */
int mFrame;
int mWalkTime;
#endif
@@ -184,30 +183,30 @@ class Being : public Sprite, public ConfigListener
virtual void setDestination(Uint16 destX, Uint16 destY);
#else
/**
- * Returns the path to the being's current destination
+ * Creates a path for the being from current position to ex and ey
*/
- virtual Path findPath();
+ void setDestination(int ex, int ey);
/**
- * Creates a path for the being from sx,sy to ex,ey
+ * Returns the destination for this being.
*/
- void setDestination(int sx, int sy, int ex, int ey);
+ const Vector &getDestination() const { return mDest; }
+#endif
/**
- * Creates a path for the being from current position to ex and ey
+ * Returns the tile x or y coord
*/
- void setDestination(int ex, int ey);
+ int getTileX() const
+ { return mX; }
- /**
- * Adjusts course to expected start point.
- */
- void adjustCourse(int srcX, int srcY);
+ int getTileY() const
+ { return mY; }
/**
- * Returns the destination for this being.
+ * Sets the tile x or y coord
*/
- const Vector &getDestination() const { return mDest; }
-#endif
+ void setTileCoords(int x, int y)
+ { mX = x; mY = y; }
/**
* Puts a "speech balloon" above this being for the specified amount
@@ -603,6 +602,7 @@ class Being : public Sprite, public ConfigListener
Vector mPos;
Vector mDest;
int mPx, mPy; /**< Position in pixels */
+ int mX, mY; /**< Position on tile */
/** Target cursor being used */
SimpleAnimation* mUsedTargetCursor;
diff --git a/src/beingmanager.cpp b/src/beingmanager.cpp
index 284f1343..0b8f71b5 100644
--- a/src/beingmanager.cpp
+++ b/src/beingmanager.cpp
@@ -40,14 +40,9 @@ class FindBeingFunctor
bool operator() (Being *being)
{
Uint16 other_y = y + ((being->getType() == Being::NPC) ? 1 : 0);
-#ifdef TMWSERV_SUPPORT
const Vector &pos = being->getPosition();
return ((int) pos.x / 32 == x &&
((int) pos.y / 32 == y || (int) pos.y / 32 == other_y) &&
-#else
- return (being->mX == x &&
- (being->mY == y || being->mY == other_y) &&
-#endif
being->mAction != Being::DEAD &&
(type == Being::UNKNOWN || being->getType() == type));
}
@@ -242,7 +237,7 @@ Being *BeingManager::findNearestLivingBeing(int x, int y, int maxdist,
const Vector &pos = being->getPosition();
int d = abs(((int) pos.x) - x) + abs(((int) pos.y) - y);
#else
- int d = abs(being->mX - x) + abs(being->mY - y);
+ int d = abs(being->getTileX() - x) + abs(being->getTileY() - y);
#endif
if ((being->getType() == type || type == Being::UNKNOWN)
@@ -268,8 +263,8 @@ Being *BeingManager::findNearestLivingBeing(Being *aroundBeing, int maxdist,
int y = apos.y;
maxdist = maxdist * 32;
#else
- int x = aroundBeing->mX;
- int y = aroundBeing->mY;
+ int x = aroundBeing->getTileX();
+ int y = aroundBeing->getTileY();
#endif
for (Beings::const_iterator i = mBeings.begin(), i_end = mBeings.end();
@@ -280,7 +275,7 @@ Being *BeingManager::findNearestLivingBeing(Being *aroundBeing, int maxdist,
const Vector &pos = being->getPosition();
int d = abs(((int) pos.x) - x) + abs(((int) pos.y) - y);
#else
- int d = abs(being->mX - x) + abs(being->mY - y);
+ int d = abs(being->getTileX() - x) + abs(being->getTileY() - y);
#endif
if ((being->getType() == type || type == Being::UNKNOWN)
diff --git a/src/commandhandler.cpp b/src/commandhandler.cpp
index d2a303e8..e64da120 100644
--- a/src/commandhandler.cpp
+++ b/src/commandhandler.cpp
@@ -207,7 +207,7 @@ void CommandHandler::handleHelp(const std::string &args, ChatTab *tab)
else if (args == "ignore")
{
tab->chatLog(_("Command: /ignore <player>"));
- tab->chatLog(_("This command ignores the given player reguardless of "
+ tab->chatLog(_("This command ignores the given player regardless of "
"current relations."));
}
else if (args == "join")
@@ -397,7 +397,7 @@ void CommandHandler::handleParty(const std::string &args, ChatTab *tab)
if (args != "")
Net::getPartyHandler()->invite(args);
else
- tab->chatLog("Please specify a name.", BY_SERVER);
+ tab->chatLog(_("Please specify a name."), BY_SERVER);
}
void CommandHandler::handleMe(const std::string &args, ChatTab *tab)
diff --git a/src/engine.cpp b/src/engine.cpp
index d33607ec..f56f8a49 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -85,7 +85,7 @@ bool Engine::changeMap(const std::string &mapPath)
if (!newMap)
{
logger->log("Error while loading %s", map_path.c_str());
- new OkDialog(_("Could not load map"),
+ new OkDialog(_("Could Not Load Map"),
strprintf(_("Error while loading %s"), map_path.c_str()));
}
diff --git a/src/equipment.cpp b/src/equipment.cpp
index f760067c..41722300 100644
--- a/src/equipment.cpp
+++ b/src/equipment.cpp
@@ -21,27 +21,14 @@
#include "equipment.h"
#include "item.h"
-#ifdef EATHENA_SUPPORT
-#include "inventory.h"
-#include "localplayer.h"
-#endif
#include <algorithm>
Equipment::Equipment()
-#ifdef EATHENA_SUPPORT
- : mArrows(-1)
-#endif
{
-#ifdef TMWSERV_SUPPORT
std::fill_n(mEquipment, EQUIPMENT_SIZE, (Item*) 0);
-#else
- std::fill_n(mEquipment, EQUIPMENT_SIZE, -1);
-#endif
}
-#ifdef TMWSERV_SUPPORT
-
Equipment::~Equipment()
{
clear();
@@ -55,29 +42,14 @@ void Equipment::clear()
std::fill_n(mEquipment, EQUIPMENT_SIZE, (Item*) 0);
}
-void Equipment::setEquipment(int index, int id)
+void Equipment::setEquipment(int index, int id, int quantity)
{
if (mEquipment[index] && mEquipment[index]->getId() == id)
return;
delete mEquipment[index];
- mEquipment[index] = (id > 0) ? new Item(id) : 0;
-}
-
-#else
-
-void Equipment::setEquipment(int index, int inventoryIndex)
-{
- mEquipment[index] = inventoryIndex;
- Item *item = player_node->getInventory()->getItem(inventoryIndex);
- if (item)
- item->setEquipped(true);
-}
+ mEquipment[index] = (id > 0) ? new Item(id, quantity) : 0;
-void Equipment::removeEquipment(int index)
-{
- if (index >= 0 && index < EQUIPMENT_SIZE)
- mEquipment[index] = -1;
+ if (mEquipment[index])
+ mEquipment[index]->setInvIndex(index);
}
-
-#endif
diff --git a/src/equipment.h b/src/equipment.h
index 5bebf78d..c7058269 100644
--- a/src/equipment.h
+++ b/src/equipment.h
@@ -22,11 +22,7 @@
#ifndef EQUIPMENT_H
#define EQUIPMENT_H
-#ifdef TMWSERV_SUPPORT
#define EQUIPMENT_SIZE 11
-#else
-#define EQUIPMENT_SIZE 10
-#endif
class Item;
@@ -38,63 +34,45 @@ class Equipment
*/
Equipment();
-#ifdef TMWSERV_SUPPORT
/**
* Destructor.
*/
~Equipment();
-#endif
+
+ enum EquipmentSlots
+ {
+ EQUIP_TORSO_SLOT = 0,
+ EQUIP_GLOVES_SLOT = 1,
+ EQUIP_HEAD_SLOT = 2,
+ EQUIP_LEGS_SLOT = 3,
+ EQUIP_FEET_SLOT = 4,
+ EQUIP_RING1_SLOT = 5,
+ EQUIP_RING2_SLOT = 6,
+ EQUIP_NECK_SLOT = 7,
+ EQUIP_FIGHT1_SLOT = 8,
+ EQUIP_FIGHT2_SLOT = 9,
+ EQUIP_PROJECTILE_SLOT = 10,
+ EQUIP_VECTOREND
+ };
/**
* Get equipment at the given slot.
*/
-#ifdef TMWSERV_SUPPORT
Item *getEquipment(int index)
-#else
- int getEquipment(int index) const
-#endif
{ return mEquipment[index]; }
-#ifdef TMWSERV_SUPPORT
/**
* Clears equipment.
*/
void clear();
-#endif
/**
* Set equipment at the given slot.
*/
-#ifdef TMWSERV_SUPPORT
- void setEquipment(int index, int id);
-#else
- void setEquipment(int index, int inventoryIndex);
-#endif
-
-#ifdef EATHENA_SUPPORT
- /**
- * Remove equipment from the given slot.
- */
- void removeEquipment(int index);
-
- /**
- * Returns the item used in the arrow slot.
- */
- int getArrows() const { return mArrows; }
-
- /**
- * Set the item used in the arrow slot.
- */
- void setArrows(int arrows) { mArrows = arrows; }
-#endif
+ void setEquipment(int index, int id, int quantity = 0);
private:
-#ifdef TMWSERV_SUPPORT
Item *mEquipment[EQUIPMENT_SIZE];
-#else
- int mEquipment[EQUIPMENT_SIZE];
- int mArrows;
-#endif
};
#endif
diff --git a/src/game.cpp b/src/game.cpp
index f1df57cc..ff0d84f7 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -62,8 +62,8 @@
#include "gui/sdlinput.h"
#include "gui/sell.h"
#include "gui/setup.h"
-#include "gui/skill.h"
-#include "gui/status.h"
+#include "gui/skilldialog.h"
+#include "gui/statuswindow.h"
#include "gui/trade.h"
#include "gui/viewport.h"
#include "gui/windowmenu.h"
@@ -206,6 +206,8 @@ int get_elapsed_time(int start_time)
*/
static void createGuiWindows()
{
+ setupWindow->clearWindowsForReset();
+
// Create dialogs
chatWindow = new ChatWindow;
buyDialog = new BuyDialog;
@@ -214,17 +216,16 @@ static void createGuiWindows()
partyWindow = new PartyWindow;
#ifdef TMWSERV_SUPPORT
magicDialog = new MagicDialog;
- equipmentWindow = new EquipmentWindow(player_node->mEquipment.get());
buddyWindow = new BuddyWindow;
guildWindow = new GuildWindow;
#else
buySellDialog = new BuySellDialog;
- equipmentWindow = new EquipmentWindow;
#endif
+ equipmentWindow = new EquipmentWindow(player_node->mEquipment.get());
npcDialog = new NpcDialog;
npcPostDialog = new NpcPostDialog;
storageWindow = new StorageWindow;
- statusWindow = new StatusWindow(player_node);
+ statusWindow = new StatusWindow;
miniStatusWindow = new MiniStatusWindow;
inventoryWindow = new InventoryWindow;
skillDialog = new SkillDialog;
@@ -405,6 +406,7 @@ static bool saveScreenshot()
if (success)
{
std::stringstream chatlogentry;
+ // TODO: Make it one complete gettext string below
chatlogentry << _("Screenshot saved to ~/") << filenameSuffix.str();
localChatTab->chatLog(chatlogentry.str(), BY_SERVER);
}
@@ -763,8 +765,8 @@ void Game::handleInput()
Uint16 x = (int) pos.x / 32;
Uint16 y = (int) pos.y / 32;
#else
- Uint16 x = player_node->mX;
- Uint16 y = player_node->mY;
+ Uint16 x = player_node->getTileX();
+ Uint16 y = player_node->getTileY();
#endif
FloorItem *item =
floorItemManager->findByCoordinates(x, y);
@@ -937,14 +939,9 @@ void Game::handleInput()
return;
}
-#ifdef TMWSERV_SUPPORT
const Vector &pos = player_node->getPosition();
const Uint16 x = (int) pos.x / 32;
const Uint16 y = (int) pos.y / 32;
-#else
- const Uint16 x = player_node->mX;
- const Uint16 y = player_node->mY;
-#endif
unsigned char direction = 0;
// Translate pressed keys to movement and direction
diff --git a/src/graphics.cpp b/src/graphics.cpp
index 58f643e9..75db11f4 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -120,11 +120,47 @@ bool Graphics::drawImage(Image *image, int x, int y)
return drawImage(image, 0, 0, x, y, image->mBounds.w, image->mBounds.h);
}
+bool Graphics::drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor)
+{
+ // Check that preconditions for blitting are met.
+ if (!mScreen || !image) return false;
+ if (!image->mImage) return false;
+
+ Image *tmpImage = image->SDLgetScaledImage(desiredWidth, desiredHeight);
+ bool returnValue = false;
+ if (!tmpImage) return false;
+ if (!tmpImage->mImage) return false;
+
+ dstX += mClipStack.top().xOffset;
+ dstY += mClipStack.top().yOffset;
+
+ srcX += image->mBounds.x;
+ srcY += image->mBounds.y;
+
+ SDL_Rect dstRect;
+ SDL_Rect srcRect;
+ dstRect.x = dstX; dstRect.y = dstY;
+ srcRect.x = srcX; srcRect.y = srcY;
+ srcRect.w = width;
+ srcRect.h = height;
+
+ returnValue = !(SDL_BlitSurface(tmpImage->mImage, &srcRect, mScreen, &dstRect) < 0);
+
+ delete tmpImage;
+
+ return returnValue;
+}
+
bool Graphics::drawImage(Image *image, int srcX, int srcY, int dstX, int dstY,
int width, int height, bool)
{
// Check that preconditions for blitting are met.
- if (!mScreen || !image || !image->mImage) return false;
+ if (!mScreen || !image) return false;
+ if (!image->mImage) return false;
dstX += mClipStack.top().xOffset;
dstY += mClipStack.top().yOffset;
@@ -154,7 +190,8 @@ void Graphics::drawImage(gcn::Image const *image, int srcX, int srcY,
void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h)
{
// Check that preconditions for blitting are met.
- if (!mScreen || !image || !image->mImage) return;
+ if (!mScreen || !image) return;
+ if (!image->mImage) return;
const int iw = image->getWidth();
const int ih = image->getHeight();
@@ -184,6 +221,48 @@ void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h)
}
}
+void Graphics::drawRescaledImagePattern(Image *image, int x, int y,
+ int w, int h, int scaledWidth, int scaledHeight)
+{
+ // Check that preconditions for blitting are met.
+ if (!mScreen || !image) return;
+ if (!image->mImage) return;
+
+ if (scaledHeight == 0 || scaledWidth == 0) return;
+
+ Image *tmpImage = image->SDLgetScaledImage(scaledWidth, scaledHeight);
+ if (!tmpImage) return;
+
+ const int iw = tmpImage->getWidth();
+ const int ih = tmpImage->getHeight();
+
+ if (iw == 0 || ih == 0) return;
+
+ for (int py = 0; py < h; py += ih) // Y position on pattern plane
+ {
+ int dh = (py + ih >= h) ? h - py : ih;
+ 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
+ {
+ int dw = (px + iw >= w) ? w - px : iw;
+ int srcX = tmpImage->mBounds.x;
+ int dstX = x + px + mClipStack.top().xOffset;
+
+ SDL_Rect dstRect;
+ SDL_Rect srcRect;
+ dstRect.x = dstX; dstRect.y = dstY;
+ srcRect.x = srcX; srcRect.y = srcY;
+ srcRect.w = dw; srcRect.h = dh;
+
+ SDL_BlitSurface(tmpImage->mImage, &srcRect, mScreen, &dstRect);
+ }
+ }
+
+ delete tmpImage;
+}
+
void Graphics::drawImageRect(int x, int y, int w, int h,
Image *topLeft, Image *topRight,
Image *bottomLeft, Image *bottomRight,
diff --git a/src/graphics.h b/src/graphics.h
index d0e70c24..b8e87af1 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -29,6 +29,9 @@ class ImageRect;
struct SDL_Surface;
+static const int defaultScreenWidth = 800;
+static const int defaultScreenHeight = 600;
+
/**
* 9 images defining a rectangle. 4 corners, 4 sides and a middle area. The
* topology is as follows:
@@ -105,6 +108,28 @@ class Graphics : public gcn::SDLGraphics
int dstX, int dstY, int width, int height);
/**
+ * Draws a resclaled version of the image
+ */
+ bool drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight)
+ { return drawRescaledImage(image, srcX, srcY,
+ dstX, dstY,
+ width, height,
+ desiredWidth, desiredHeight,
+ false); };
+
+ /**
+ * Draws a resclaled version of the image
+ */
+ virtual bool drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor = false);
+
+ /**
* Blits an image onto the screen.
*
* @return <code>true</code> if the image was blitted properly
@@ -121,6 +146,13 @@ class Graphics : public gcn::SDLGraphics
int w, int h);
/**
+ * Draw a pattern based on a rescaled version of the given image...
+ */
+ virtual void drawRescaledImagePattern(Image *image,
+ int x, int y, int w, int h,
+ int scaledWidth, int scaledHeight);
+
+ /**
* Draws a rectangle using images. 4 corner images, 4 side images and 1
* image for the inside.
*/
diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp
index 5b393a06..a2398472 100644
--- a/src/gui/buy.cpp
+++ b/src/gui/buy.cpp
@@ -27,6 +27,7 @@
#include "gui/widgets/scrollarea.h"
#include "gui/widgets/slider.h"
+#include "gui/setup.h"
#include "gui/shop.h"
#include "gui/shoplistbox.h"
@@ -47,6 +48,7 @@ BuyDialog::BuyDialog():
mMoney(0), mAmountItems(0), mMaxItems(0)
{
setWindowName("Buy");
+ setupWindow->registerWindowForReset(this);
setResizable(true);
setCloseButton(true);
setMinWidth(260);
@@ -65,8 +67,12 @@ BuyDialog::BuyDialog():
mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"),
"", ""));
- mIncreaseButton = new Button("+", "+", this);
- mDecreaseButton = new Button("-", "-", this);
+ // TRANSLATORS: This is a narrow symbol used to denote 'increasing'.
+ // You may change this symbol if your language uses another.
+ mIncreaseButton = new Button(_("+"), "inc", this);
+ // TRANSLATORS: This is a narrow symbol used to denote 'decreasing'.
+ // You may change this symbol if your language uses another.
+ mDecreaseButton = new Button(_("-"), "dec", this);
mBuyButton = new Button(_("Buy"), "buy", this);
mQuitButton = new Button(_("Quit"), "quit", this);
mAddMaxButton = new Button(_("Max"), "max", this);
@@ -160,13 +166,13 @@ void BuyDialog::action(const gcn::ActionEvent &event)
mAmountItems = (int) mSlider->getValue();
updateButtonsAndLabels();
}
- else if (event.getId() == "+" && mAmountItems < mMaxItems)
+ else if (event.getId() == "inc" && mAmountItems < mMaxItems)
{
mAmountItems++;
mSlider->setValue(mAmountItems);
updateButtonsAndLabels();
}
- else if (event.getId() == "-" && mAmountItems > 1)
+ else if (event.getId() == "dec" && mAmountItems > 1)
{
mAmountItems--;
mSlider->setValue(mAmountItems);
diff --git a/src/gui/buysell.cpp b/src/gui/buysell.cpp
index 53c2419a..c96c9f24 100644
--- a/src/gui/buysell.cpp
+++ b/src/gui/buysell.cpp
@@ -24,6 +24,7 @@
#include "npc.h"
#include "gui/widgets/button.h"
+#include "gui/setup.h"
#include "net/net.h"
#include "net/npchandler.h"
@@ -35,6 +36,7 @@ BuySellDialog::BuySellDialog():
mBuyButton(0)
{
setWindowName("BuySell");
+ setupWindow->registerWindowForReset(this);
static const char *buttonNames[] = {
N_("Buy"), N_("Sell"), N_("Cancel"), 0
diff --git a/src/gui/changeemaildialog.cpp b/src/gui/changeemaildialog.cpp
index d36ab487..eb05e25e 100644
--- a/src/gui/changeemaildialog.cpp
+++ b/src/gui/changeemaildialog.cpp
@@ -46,7 +46,7 @@ ChangeEmailDialog::ChangeEmailDialog(Window *parent, LoginData *loginData):
{
gcn::Label *accountLabel = new Label(strprintf(_("Account: %s"),
mLoginData->username.c_str()));
- gcn::Label *newEmailLabel = new Label(_("Type New Email Address twice:"));
+ gcn::Label *newEmailLabel = new Label(_("Type new email address twice:"));
mFirstEmailField = new TextField;
mSecondEmailField = new TextField;
mChangeEmailButton = new Button(_("Change Email Address"), "change_email", this);
@@ -114,29 +114,29 @@ ChangeEmailDialog::action(const gcn::ActionEvent &event)
logger->log("ChangeEmailDialog::Email change, Username is %s",
username.c_str());
- std::stringstream errorMsg;
+ std::stringstream errorMessage;
int error = 0;
if (newFirstEmail.length() < LEN_MIN_PASSWORD)
{
// First email address too short
- errorMsg << "The new email address needs to be at least "
- << LEN_MIN_PASSWORD
- << " characters long.";
+ errorMessage << strprintf(_("The new email address needs to be at "
+ "least %d characters long."),
+ LEN_MIN_PASSWORD);
error = 1;
}
else if (newFirstEmail.length() > LEN_MAX_PASSWORD - 1 )
{
// First email address too long
- errorMsg << "The new email address needs to be less than "
- << LEN_MAX_PASSWORD
- << " characters long.";
+ errorMessage << strprintf(_("The new email address needs to be "
+ "less than %d characters long."),
+ LEN_MAX_PASSWORD);
error = 1;
}
else if (newFirstEmail != newSecondEmail)
{
// Second Pass mismatch
- errorMsg << "The email address entries mismatch.";
+ errorMessage << _("The email address entries mismatch.");
error = 2;
}
@@ -151,7 +151,7 @@ ChangeEmailDialog::action(const gcn::ActionEvent &event)
mWrongDataNoticeListener->setTarget(this->mSecondEmailField);
}
- OkDialog *dlg = new OkDialog("Error", errorMsg.str());
+ OkDialog *dlg = new OkDialog(_("Error"), errorMessage.str());
dlg->addActionListener(mWrongDataNoticeListener);
}
else
diff --git a/src/gui/changepassworddialog.cpp b/src/gui/changepassworddialog.cpp
index 4be92b15..9d66d13a 100644
--- a/src/gui/changepassworddialog.cpp
+++ b/src/gui/changepassworddialog.cpp
@@ -96,36 +96,35 @@ void ChangePasswordDialog::action(const gcn::ActionEvent &event)
logger->log("ChangePasswordDialog::Password change, Username is %s",
username.c_str());
- std::stringstream errorMsg;
+ std::stringstream errorMessage;
int error = 0;
// Check old Password
if (oldPassword.empty())
{
// No old password
- errorMsg << "Enter the old Password first.";
+ errorMessage << _("Enter the old password first.");
error = 1;
}
else if (newFirstPass.length() < LEN_MIN_PASSWORD)
{
// First password too short
- errorMsg << "The new password needs to be at least "
- << LEN_MIN_PASSWORD
- << " characters long.";
+ errorMessage << strprintf(_("The new password needs to be at least "
+ "%d characters long."), LEN_MIN_PASSWORD);
error = 2;
}
else if (newFirstPass.length() > LEN_MAX_PASSWORD - 1 )
{
// First password too long
- errorMsg << "The new password needs to be less than "
- << LEN_MAX_PASSWORD
- << " characters long.";
+ errorMessage << strprintf(_("The new password needs to be less "
+ "than %d characters long."),
+ LEN_MAX_PASSWORD);
error = 2;
}
else if (newFirstPass != newSecondPass)
{
// Second Pass mismatch
- errorMsg << "The new password entries mismatch.";
+ errorMessage << _("The new password entries mismatch.");
error = 3;
}
@@ -144,7 +143,7 @@ void ChangePasswordDialog::action(const gcn::ActionEvent &event)
mWrongDataNoticeListener->setTarget(this->mSecondPassField);
}
- OkDialog *dlg = new OkDialog("Error", errorMsg.str());
+ OkDialog *dlg = new OkDialog(_("Error"), errorMessage.str());
dlg->addActionListener(mWrongDataNoticeListener);
}
else
diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp
index 79ec5c1a..e09eee55 100644
--- a/src/gui/charcreatedialog.cpp
+++ b/src/gui/charcreatedialog.cpp
@@ -64,12 +64,16 @@ CharCreateDialog::CharCreateDialog(Window *parent, int slot):
mNameField = new TextField("");
mNameLabel = new Label(_("Name:"));
- mNextHairColorButton = new Button(">", "nextcolor", this);
- mPrevHairColorButton = new Button("<", "prevcolor", this);
- mHairColorLabel = new Label(_("Hair Color:"));
- mNextHairStyleButton = new Button(">", "nextstyle", this);
- mPrevHairStyleButton = new Button("<", "prevstyle", this);
- mHairStyleLabel = new Label(_("Hair Style:"));
+ // TRANSLATORS: This is a narrow symbol used to denote 'next'.
+ // You may change this symbol if your language uses another.
+ mNextHairColorButton = new Button(_(">"), "nextcolor", this);
+ // TRANSLATORS: This is a narrow symbol used to denote 'previous'.
+ // You may change this symbol if your language uses another.
+ mPrevHairColorButton = new Button(_("<"), "prevcolor", this);
+ mHairColorLabel = new Label(_("Hair color:"));
+ mNextHairStyleButton = new Button(_(">"), "nextstyle", this);
+ mPrevHairStyleButton = new Button(_("<"), "prevstyle", this);
+ mHairStyleLabel = new Label(_("Hair style:"));
mCreateButton = new Button(_("Create"), "create", this);
mCancelButton = new Button(_("Cancel"), "cancel", this);
mMale = new RadioButton(_("Male"), "gender");
diff --git a/src/gui/charselectdialog.cpp b/src/gui/charselectdialog.cpp
index 63a25d45..69a627e1 100644
--- a/src/gui/charselectdialog.cpp
+++ b/src/gui/charselectdialog.cpp
@@ -36,6 +36,8 @@
#include "gui/changeemaildialog.h"
#include "net/tmwserv/accountserver/account.h"
+#else
+#include "net/ea/protocol.h"
#endif
#include "gui/widgets/button.h"
@@ -116,7 +118,7 @@ CharSelectDialog::CharSelectDialog(LockedArray<LocalPlayer*> *charInfo,
mNameLabel = new Label(strprintf(_("Name: %s"), ""));
mLevelLabel = new Label(strprintf(_("Level: %d"), 0));
- mMoneyLabel = new Label(strprintf(_("Money: %d"), 0));
+ mMoneyLabel = new Label(strprintf(_("Money: %s"), ""));
// Control that shows the Player
mPlayerBox = new PlayerBox;
@@ -296,9 +298,9 @@ void CharSelectDialog::updatePlayerInfo()
mNameLabel->setCaption(strprintf(_("Name: %s"),
pi->getName().c_str()));
mLevelLabel->setCaption(strprintf(_("Level: %d"), pi->getLevel()));
-#ifndef TMWSERV_SUPPORT
+#ifdef EATHENA_SUPPORT
mJobLevelLabel->setCaption(strprintf(_("Job Level: %d"),
- pi->mJobLevel));
+ pi->getAttributeBase(JOB)));
#endif
mMoneyLabel->setCaption(strprintf(_("Money: %s"), mMoney.c_str()));
if (!mCharSelected)
@@ -362,7 +364,10 @@ bool CharSelectDialog::selectByName(const std::string &name)
LocalPlayer *player = mCharInfo->getEntry();
if (player && player->getName() == name)
+ {
+ mMoney = Units::formatCurrency(player->getMoney());
return true;
+ }
mCharInfo->next();
} while (mCharInfo->getPos());
diff --git a/src/gui/chat.cpp b/src/gui/chat.cpp
index 1ce1b77c..c337d33b 100644
--- a/src/gui/chat.cpp
+++ b/src/gui/chat.cpp
@@ -23,6 +23,7 @@
#include "gui/itemlinkhandler.h"
#include "gui/recorder.h"
+#include "gui/setup.h"
#include "gui/sdlinput.h"
#include "gui/widgets/chattab.h"
@@ -39,6 +40,7 @@
#include "net/net.h"
#include "utils/dtor.h"
+#include "utils/gettext.h"
#include "utils/stringutils.h"
#include <guichan/focushandler.hpp>
@@ -76,6 +78,8 @@ ChatWindow::ChatWindow():
{
setWindowName("Chat");
+ setupWindow->registerWindowForReset(this);
+
// no title presented, title bar is padding so window can be moved.
gcn::Window::setTitleBarHeight(gcn::Window::getPadding() + 4);
setShowTitle(false);
@@ -138,9 +142,14 @@ void ChatWindow::adjustTabSize()
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());
}
}
@@ -323,8 +332,8 @@ void ChatWindow::doPresent()
}
}
- std::string cpc = strprintf(_("%d players are present."), playercount);
- std::string log = _("Present: ") + response + std::string("; ") + cpc;
+ std::string log = strprintf(_("Present: %s; %d players are present."),
+ response.c_str(), playercount);
if (mRecorder->isRecording())
{
@@ -360,6 +369,37 @@ void ChatWindow::scroll(int amount)
tab->scroll(amount);
}
+void ChatWindow::mousePressed(gcn::MouseEvent &event)
+{
+ Window::mousePressed(event);
+
+ if(event.isConsumed())
+ return;
+
+ mMoved = event.getY() <= mCurrentTab->getHeight();
+ mDragOffsetX = event.getX();
+ mDragOffsetY = event.getY();
+
+}
+
+void ChatWindow::mouseDragged(gcn::MouseEvent &event)
+{
+ Window::mouseDragged(event);
+
+ if(event.isConsumed())
+ return;
+
+ if(isMovable() && mMoved)
+ {
+ int newX = std::max(0, getX() + event.getX() - mDragOffsetX);
+ int newY = std::max(0, getY() + event.getY() - mDragOffsetY);
+ newX = std::min(graphics->getWidth() - getWidth(), newX);
+ newY = std::min(graphics->getHeight() - getHeight(), newY);
+ setPosition(newX, newY);
+ }
+}
+
+
void ChatWindow::keyPressed(gcn::KeyEvent &event)
{
if (event.getKey().getValue() == Key::DOWN)
diff --git a/src/gui/chat.h b/src/gui/chat.h
index 7080392e..2de3a634 100644
--- a/src/gui/chat.h
+++ b/src/gui/chat.h
@@ -150,6 +150,11 @@ class ChatWindow : public Window,
/** Override to reset mTmpVisible */
void setVisible(bool visible);
+
+ void mousePressed(gcn::MouseEvent &event);
+ void mouseDragged(gcn::MouseEvent &event);
+
+
/**
* Scrolls the chat window
*
diff --git a/src/gui/connectiondialog.cpp b/src/gui/connectiondialog.cpp
index 1c3b7ff5..9e361173 100644
--- a/src/gui/connectiondialog.cpp
+++ b/src/gui/connectiondialog.cpp
@@ -31,7 +31,7 @@
#include "utils/gettext.h"
ConnectionDialog::ConnectionDialog(State previousState):
- Window("Info"), mProgress(0), mPreviousState(previousState)
+ Window(_("Info")), mProgress(0), mPreviousState(previousState)
{
setContentSize(200, 100);
diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp
index f3dbe5e2..59c0f254 100644
--- a/src/gui/debugwindow.cpp
+++ b/src/gui/debugwindow.cpp
@@ -21,6 +21,7 @@
#include "gui/debugwindow.h"
+#include "gui/setup.h"
#include "gui/viewport.h"
#include "gui/widgets/label.h"
@@ -31,31 +32,33 @@
#include "particle.h"
#include "map.h"
+#include "utils/gettext.h"
#include "utils/stringutils.h"
DebugWindow::DebugWindow():
- Window("Debug")
+ Window(_("Debug"))
{
setWindowName("Debug");
+ setupWindow->registerWindowForReset(this);
setResizable(true);
setCloseButton(true);
setSaveVisible(true);
setDefaultSize(400, 100, ImageRect::CENTER);
- mFPSLabel = new Label("0 FPS");
- mMusicFileLabel = new Label("Music: ");
- mMapLabel = new Label("Map: ");
- mMiniMapLabel = new Label("Mini-Map: ");
- mTileMouseLabel = new Label("Mouse: 0, 0");
- mParticleCountLabel = new Label("Particle count: 0");
+ mFPSLabel = new Label(strprintf(_("%d FPS"), 0));
+ mMusicFileLabel = new Label(strprintf(_("Music: %s"), ""));
+ mMapLabel = new Label(strprintf(_("Map: %s"), ""));
+ mMinimapLabel = new Label(strprintf(_("Minimap: %s"), ""));
+ mTileMouseLabel = new Label(strprintf(_("Tile: (%d, %d)"), 0, 0));
+ mParticleCountLabel = new Label(strprintf(_("Particle count: %d"), 0));
place(0, 0, mFPSLabel, 3);
place(3, 0, mTileMouseLabel);
place(0, 1, mMusicFileLabel, 3);
place(3, 1, mParticleCountLabel);
place(0, 2, mMapLabel, 4);
- place(0, 3, mMiniMapLabel, 4);
+ place(0, 3, mMinimapLabel, 4);
loadWindowState();
}
@@ -69,27 +72,28 @@ void DebugWindow::logic()
int mouseTileX = (viewport->getMouseX() + viewport->getCameraX()) / 32;
int mouseTileY = (viewport->getMouseY() + viewport->getCameraY()) / 32;
- mFPSLabel->setCaption(toString(fps) + " FPS");
+ mFPSLabel->setCaption(strprintf(_("%d FPS"), fps));
- mTileMouseLabel->setCaption("Tile: (" + toString(mouseTileX) + ", " +
- toString(mouseTileY) + ")");
+ mTileMouseLabel->setCaption(strprintf(_("Tile: (%d, %d)"), mouseTileX,
+ mouseTileY));
Map *currentMap = engine->getCurrentMap();
if (currentMap)
{
+ // TODO: Add gettext support below
const std::string music =
"Music: " + currentMap->getProperty("music");
mMusicFileLabel->setCaption(music);
const std::string minimap =
- "MiniMap: " + currentMap->getProperty("minimap");
- mMiniMapLabel->setCaption(minimap);
+ "Minimap: " + currentMap->getProperty("minimap");
+ mMinimapLabel->setCaption(minimap);
const std::string map =
"Map: " + currentMap->getProperty("_filename");
mMapLabel->setCaption(map);
}
- mParticleCountLabel->setCaption("Particle count: " +
- toString(Particle::particleCount));
+ mParticleCountLabel->setCaption(strprintf(_("Particle count: %d"),
+ Particle::particleCount));
}
diff --git a/src/gui/debugwindow.h b/src/gui/debugwindow.h
index e30107f9..e4c45bde 100644
--- a/src/gui/debugwindow.h
+++ b/src/gui/debugwindow.h
@@ -43,7 +43,7 @@ class DebugWindow : public Window
void logic();
private:
- gcn::Label *mMusicFileLabel, *mMapLabel, *mMiniMapLabel;
+ gcn::Label *mMusicFileLabel, *mMapLabel, *mMinimapLabel;
gcn::Label *mTileMouseLabel, *mFPSLabel;
gcn::Label *mParticleCountLabel;
};
diff --git a/src/gui/emoteshortcutcontainer.cpp b/src/gui/emoteshortcutcontainer.cpp
index 8e37be72..c087fc7e 100644
--- a/src/gui/emoteshortcutcontainer.cpp
+++ b/src/gui/emoteshortcutcontainer.cpp
@@ -39,8 +39,6 @@
#include "resources/resourcemanager.h"
#include "utils/dtor.h"
-#include "utils/gettext.h"
-#include "utils/stringutils.h"
static const int MAX_ITEMS = 12;
diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp
index 44006971..25de201c 100644
--- a/src/gui/equipmentwindow.cpp
+++ b/src/gui/equipmentwindow.cpp
@@ -25,6 +25,7 @@
#include "gui/itempopup.h"
#include "gui/palette.h"
#include "gui/playerbox.h"
+#include "gui/setup.h"
#include "gui/viewport.h"
#include "equipment.h"
@@ -50,31 +51,26 @@ static const int BOX_HEIGHT = 36;
// Positions of the boxes, 2nd dimension is X and Y respectively.
static const int boxPosition[][2] = {
- { 50, 208 }, // EQUIP_LEGS_SLOT
- { 8, 123 }, // EQUIP_FIGHT1_SLOT
+ { 90, 40 }, // EQUIP_TORSO_SLOT
{ 8, 78 }, // EQUIP_GLOVES_SLOT
- { 129, 168 }, // EQUIP_RING2_SLOT
+ { 70, 0 }, // EQUIP_HEAD_SLOT
+ { 50, 208 }, // EQUIP_LEGS_SLOT
+ { 90, 208 }, // EQUIP_FEET_SLOT
{ 8, 168 }, // EQUIP_RING1_SLOT
+ { 129, 168 }, // EQUIP_RING2_SLOT
+ { 50, 40 }, // EQUIP_NECK_SLOT
+ { 8, 123 }, // EQUIP_FIGHT1_SLOT
{ 129, 123 }, // EQUIP_FIGHT2_SLOT
- { 90, 208 }, // EQUIP_FEET_SLOT
- { 50, 40 }, // EQUIP_CAPE_SLOT
- { 70, 0 }, // EQUIP_HEAD_SLOT
- { 90, 40 }, // EQUIP_TORSO_SLOT
- { 129, 78 } // EQUIP_AMMO_SLOT
+ { 129, 78 } // EQUIP_PROJECTILE_SLOT
};
-#ifdef TMWSERV_SUPPORT
EquipmentWindow::EquipmentWindow(Equipment *equipment):
-#else
-EquipmentWindow::EquipmentWindow():
-#endif
Window(_("Equipment")),
-#ifdef TMWSERV_SUPPORT
mEquipment(equipment),
-#endif
mSelected(-1)
{
mItemPopup = new ItemPopup;
+ setupWindow->registerWindowForReset(this);
// Control that shows the Player
PlayerBox *playerBox = new PlayerBox;
@@ -96,16 +92,11 @@ EquipmentWindow::EquipmentWindow():
add(playerBox);
add(mUnequip);
- for (int i = 0; i < EQUIP_VECTOREND; i++)
+ for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
{
mEquipBox[i].posX = boxPosition[i][0] + getPadding();
mEquipBox[i].posY = boxPosition[i][1] + getTitleBarHeight();
}
-
-#ifdef EATHENA_SUPPORT
- mEquipment = player_node->mEquipment.get();
- mInventory = player_node->getInventory();
-#endif
}
EquipmentWindow::~EquipmentWindow()
@@ -122,7 +113,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
Window::drawChildren(graphics);
- for (int i = 0; i < EQUIP_VECTOREND; i++)
+ for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
{
if (i == mSelected)
{
@@ -140,13 +131,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
g->drawRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY,
BOX_WIDTH, BOX_HEIGHT));
-#ifdef TMWSERV_SUPPORT
Item *item = mEquipment->getEquipment(i);
-#else
- Item *item = (i != EQUIP_AMMO_SLOT) ?
- mInventory->getItem(mEquipment->getEquipment(i)) :
- mInventory->getItem(mEquipment->getArrows());
-#endif
if (item)
{
// Draw Item.
@@ -154,8 +139,7 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
g->drawImage(image,
mEquipBox[i].posX + 2,
mEquipBox[i].posY + 2);
-#ifdef EATHENA_SUPPORT
- if (i == EQUIP_AMMO_SLOT)
+ if (i == EQUIP_PROJECTILE_SLOT)
{
g->setColor(guiPalette->getColor(Palette::TEXT));
graphics->drawText(toString(item->getQuantity()),
@@ -163,7 +147,6 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
mEquipBox[i].posY - getFont()->getHeight(),
gcn::Graphics::CENTER);
}
-#endif
}
}
}
@@ -172,13 +155,7 @@ void EquipmentWindow::action(const gcn::ActionEvent &event)
{
if (event.getId() == "unequip" && mSelected > -1)
{
-#ifdef TMWSERV_SUPPORT // TODO: merge these!
Item *item = mEquipment->getEquipment(mSelected);
-#else
- Item *item = (mSelected != EQUIP_AMMO_SLOT) ?
- mInventory->getItem(mEquipment->getEquipment(mSelected)) :
- mInventory->getItem(mEquipment->getArrows());
-#endif
Net::getInventoryHandler()->unequipItem(item);
setSelected(-1);
}
@@ -186,20 +163,14 @@ void EquipmentWindow::action(const gcn::ActionEvent &event)
Item *EquipmentWindow::getItem(int x, int y) const
{
- for (int i = 0; i < EQUIP_VECTOREND; i++)
+ for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
{
gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY,
BOX_WIDTH, BOX_HEIGHT);
if (tRect.isPointInRect(x, y))
{
-#ifdef TMWSERV_SUPPORT
return mEquipment->getEquipment(i);
-#else
- return (i != EQUIP_AMMO_SLOT) ?
- mInventory->getItem(mEquipment->getEquipment(i)) :
- mInventory->getItem(mEquipment->getArrows());
-#endif
}
}
return NULL;
@@ -215,15 +186,9 @@ void EquipmentWindow::mousePressed(gcn::MouseEvent& mouseEvent)
if (mouseEvent.getButton() == gcn::MouseEvent::LEFT)
{
// Checks if any of the presses were in the equip boxes.
- for (int i = 0; i < EQUIP_VECTOREND; i++)
+ for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
{
-#ifdef TMWSERV_SUPPORT
Item *item = mEquipment->getEquipment(i);
-#else
- Item *item = (i != EQUIP_AMMO_SLOT) ?
- mInventory->getItem(mEquipment->getEquipment(i)) :
- mInventory->getItem(mEquipment->getArrows());
-#endif
gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY,
BOX_WIDTH, BOX_HEIGHT);
diff --git a/src/gui/equipmentwindow.h b/src/gui/equipmentwindow.h
index 8bc350a4..a7b2c0d1 100644
--- a/src/gui/equipmentwindow.h
+++ b/src/gui/equipmentwindow.h
@@ -24,11 +24,11 @@
#include "gui/widgets/window.h"
+#include "equipment.h"
#include "guichanfwd.h"
#include <guichan/actionlistener.hpp>
-class Equipment;
class Inventory;
class Item;
class ItemPopup;
@@ -44,11 +44,7 @@ class EquipmentWindow : public Window, public gcn::ActionListener
/**
* Constructor.
*/
-#ifdef TMWSERV_SUPPORT
EquipmentWindow(Equipment *equipment);
-#else
- EquipmentWindow();
-#endif
/**
* Destructor.
@@ -64,40 +60,6 @@ class EquipmentWindow : public Window, public gcn::ActionListener
void mousePressed(gcn::MouseEvent& mouseEvent);
-#ifdef TMWSERV_SUPPORT
- enum EquipmentSlots
- {
- EQUIP_TORSO_SLOT = 0,
- EQUIP_ARMS_SLOT = 1,
- EQUIP_HEAD_SLOT = 2,
- EQUIP_LEGS_SLOT = 3,
- EQUIP_FEET_SLOT = 4,
- EQUIP_RING1_SLOT = 5,
- EQUIP_RING2_SLOT = 6,
- EQUIP_NECKLACE_SLOT = 7,
- EQUIP_FIGHT1_SLOT = 8,
- EQUIP_FIGHT2_SLOT = 9,
- EQUIP_PROJECTILE_SLOT = 10,
- EQUIP_VECTOREND
- };
-#else
- enum EquipmentSlots
- {
- EQUIP_LEGS_SLOT = 0,
- EQUIP_FIGHT1_SLOT,
- EQUIP_GLOVES_SLOT,
- EQUIP_RING2_SLOT,
- EQUIP_RING1_SLOT,
- EQUIP_FIGHT2_SLOT,
- EQUIP_FEET_SLOT,
- EQUIP_CAPE_SLOT,
- EQUIP_HEAD_SLOT,
- EQUIP_TORSO_SLOT,
- EQUIP_AMMO_SLOT,
- EQUIP_VECTOREND
- };
-#endif
-
private:
void mouseExited(gcn::MouseEvent &event);
void mouseMoved(gcn::MouseEvent &event);
@@ -107,9 +69,6 @@ class EquipmentWindow : public Window, public gcn::ActionListener
void setSelected(int index);
Equipment *mEquipment;
-#ifdef EATHENA_SUPPORT
- Inventory *mInventory;
-#endif
/**
* Equipment box.
@@ -120,12 +79,12 @@ class EquipmentWindow : public Window, public gcn::ActionListener
int posY;
};
- EquipBox mEquipBox[EQUIP_VECTOREND]; /**< Equipment Boxes. */
+ EquipBox mEquipBox[Equipment::EQUIP_VECTOREND]; /**< Equipment Boxes. */
ItemPopup *mItemPopup;
gcn::Button *mUnequip;
- int mSelected; /**< Index of selected item. */
+ int mSelected; /**< Index of selected item. */
};
extern EquipmentWindow *equipmentWindow;
diff --git a/src/gui/guildwindow.cpp b/src/gui/guildwindow.cpp
index 6dc86e13..05af7780 100644
--- a/src/gui/guildwindow.cpp
+++ b/src/gui/guildwindow.cpp
@@ -24,6 +24,7 @@
#include "gui/confirmdialog.h"
#include "gui/guildlistbox.h"
+#include "gui/setup.h"
#include "gui/textdialog.h"
#include "gui/widgets/button.h"
@@ -41,6 +42,7 @@
#include "utils/dtor.h"
#include "utils/gettext.h"
+#include "utils/stringutils.h"
#include <algorithm>
@@ -58,6 +60,7 @@ GuildWindow::GuildWindow():
setMinWidth(200);
setMinHeight(280);
setDefaultSize(124, 41, 288, 330);
+ setupWindow->registerWindowForReset(this);
// Set button events Id
mGuildButton[0] = new Button(_("Create Guild"), "CREATE_GUILD", this);
@@ -110,7 +113,8 @@ void GuildWindow::action(const gcn::ActionEvent &event)
{
// Set focus so that guild name to be created can be typed.
mFocus = true;
- guildDialog = new TextDialog("Guild Name", "Choose your guild's name", this);
+ guildDialog = new TextDialog(_("Guild Name"),
+ _("Choose your guild's name."), this);
guildDialog->setOKButtonActionId("CREATE_GUILD_OK");
guildDialog->addActionListener(this);
}
@@ -118,7 +122,8 @@ void GuildWindow::action(const gcn::ActionEvent &event)
{
// TODO - Give feedback on whether the invite succeeded
mFocus = true;
- inviteDialog = new TextDialog("Member Invite", "Who would you like to invite?", this);
+ inviteDialog = new TextDialog(_("Member Invite"),
+ _("Who would you like to invite?"), this);
inviteDialog->setOKButtonActionId("INVITE_USER_OK");
inviteDialog->addActionListener(this);
}
@@ -128,7 +133,8 @@ void GuildWindow::action(const gcn::ActionEvent &event)
if (guild)
{
Net::ChatServer::Guild::quitGuild(guild);
- localChatTab->chatLog("Guild " + mGuildTabs->getSelectedTab()->getCaption() + " quit", BY_SERVER);
+ localChatTab->chatLog(strprintf(_("Guild %s quit."),
+ mGuildTabs->getSelectedTab()->getCaption().c_str()), BY_SERVER);
}
}
else if (eventId == "CREATE_GUILD_OK")
@@ -144,7 +150,8 @@ void GuildWindow::action(const gcn::ActionEvent &event)
// Defocus dialog
mFocus = false;
- localChatTab->chatLog("Creating Guild called " + name, BY_SERVER);
+ localChatTab->chatLog(strprintf(_("Creating guild called %s."),
+ name.c_str()), BY_SERVER);
guildDialog->scheduleDelete();
}
else if (eventId == "INVITE_USER_OK")
@@ -157,7 +164,7 @@ void GuildWindow::action(const gcn::ActionEvent &event)
// Defocus dialog
mFocus = false;
- localChatTab->chatLog("Invited user " + name, BY_SERVER);
+ localChatTab->chatLog(strprintf(_("Invited user %s."), name.c_str()), BY_SERVER);
inviteDialog->scheduleDelete();
}
else if (eventId == "yes")
@@ -233,10 +240,11 @@ short GuildWindow::getSelectedGuild()
void GuildWindow::openAcceptDialog(const std::string &inviterName,
const std::string &guildName)
{
- std::string msg = inviterName + " has invited you to join the guild " + guildName;
+ std::string msg = strprintf(_("%s has invited you to join the guild %s."),
+ inviterName.c_str(), guildName.c_str());
localChatTab->chatLog(msg, BY_SERVER);
- acceptDialog = new ConfirmDialog("Accept Guild Invite", msg, this);
+ acceptDialog = new ConfirmDialog(_("Accept Guild Invite"), msg, this);
acceptDialog->addActionListener(this);
invitedGuild = guildName;
diff --git a/src/gui/help.cpp b/src/gui/help.cpp
index ddcf7b49..e28f64e3 100644
--- a/src/gui/help.cpp
+++ b/src/gui/help.cpp
@@ -25,6 +25,7 @@
#include "gui/widgets/browserbox.h"
#include "gui/widgets/layout.h"
#include "gui/widgets/scrollarea.h"
+#include "gui/setup.h"
#include "resources/resourcemanager.h"
@@ -38,6 +39,7 @@ HelpWindow::HelpWindow():
setContentSize(455, 350);
setWindowName("Help");
setResizable(true);
+ setupWindow->registerWindowForReset(this);
setDefaultSize(500, 400, ImageRect::CENTER);
diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp
index 06e43eac..50465a50 100644
--- a/src/gui/inventorywindow.cpp
+++ b/src/gui/inventorywindow.cpp
@@ -23,6 +23,7 @@
#include "gui/itemamount.h"
#include "gui/itemcontainer.h"
+#include "gui/setup.h"
#include "gui/sdlinput.h"
#include "gui/viewport.h"
@@ -57,6 +58,7 @@ InventoryWindow::InventoryWindow(int invSize):
mItemDesc(false)
{
setWindowName("Inventory");
+ setupWindow->registerWindowForReset(this);
setResizable(true);
setCloseButton(true);
setSaveVisible(true);
diff --git a/src/gui/itemamount.cpp b/src/gui/itemamount.cpp
index 87df46c1..20834c54 100644
--- a/src/gui/itemamount.cpp
+++ b/src/gui/itemamount.cpp
@@ -90,9 +90,9 @@ ItemAmountWindow::ItemAmountWindow(Usage usage, Window *parent, Item *item,
mItemIcon = new Icon(image);
// Buttons
- Button *minusButton = new Button("-", "minus", this);
- Button *plusButton = new Button("+", "plus", this);
- Button *okButton = new Button(_("Ok"), "ok", this);
+ Button *minusButton = new Button(_("-"), "dec", this);
+ Button *plusButton = new Button(_("+"), "inc", this);
+ Button *okButton = new Button(_("OK"), "ok", this);
Button *cancelButton = new Button(_("Cancel"), "cancel", this);
Button *addAllButton = new Button(_("All"), "all", this);
@@ -172,11 +172,11 @@ void ItemAmountWindow::action(const gcn::ActionEvent &event)
{
close();
}
- else if (event.getId() == "plus" && amount < mMax)
+ else if (event.getId() == "inc" && amount < mMax)
{
amount++;
}
- else if (event.getId() == "minus" && amount > 1)
+ else if (event.getId() == "dec" && amount > 1)
{
amount--;
}
diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp
index e1822e03..39dc603a 100644
--- a/src/gui/itempopup.cpp
+++ b/src/gui/itempopup.cpp
@@ -88,8 +88,9 @@ void ItemPopup::setItem(const ItemInfo &item)
mItemDesc->setTextWrapped(item.getDescription(), 196);
mItemEffect->setTextWrapped(item.getEffect(), 196);
- mItemWeight->setTextWrapped(_("Weight: ") +
- Units::formatWeight(item.getWeight()), 196);
+ mItemWeight->setTextWrapped(strprintf(_("Weight: %s"),
+ Units::formatWeight(item.getWeight()).c_str()),
+ 196);
int minWidth = mItemName->getWidth();
diff --git a/src/gui/login.cpp b/src/gui/login.cpp
index 77f2e137..3b63eff1 100644
--- a/src/gui/login.cpp
+++ b/src/gui/login.cpp
@@ -70,7 +70,7 @@ LoginDialog::LoginDialog(LoginData *loginData):
mServerDropDown = new DropDown(mServerList);
#endif
- mKeepCheck = new CheckBox(_("Remember Username"), mLoginData->remember);
+ mKeepCheck = new CheckBox(_("Remember username"), mLoginData->remember);
mOkButton = new Button(_("OK"), "ok", this);
mCancelButton = new Button(_("Cancel"), "cancel", this);
mRegisterButton = new Button(_("Register"), "register", this);
diff --git a/src/gui/magic.cpp b/src/gui/magic.cpp
index c47faa18..6e314656 100644
--- a/src/gui/magic.cpp
+++ b/src/gui/magic.cpp
@@ -22,6 +22,7 @@
#include "gui/magic.h"
#include "gui/widgets/button.h"
+#include "gui/setup.h"
#include "localplayer.h"
@@ -35,6 +36,7 @@ MagicDialog::MagicDialog():
setCloseButton(true);
setSaveVisible(true);
setDefaultSize(255, 30, 175, 225);
+ setupWindow->registerWindowForReset(this);
mSpellButtons.resize(4);
diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp
index d1c99b84..40526a22 100644
--- a/src/gui/minimap.cpp
+++ b/src/gui/minimap.cpp
@@ -31,6 +31,7 @@
#include "player.h"
#include "gui/palette.h"
+#include "gui/setup.h"
#include "resources/image.h"
#include "resources/resourcemanager.h"
@@ -47,12 +48,13 @@ Minimap::Minimap():
mWidthProportion(0.5),
mHeightProportion(0.5)
{
- setWindowName("MiniMap");
+ setWindowName("Minimap");
mShow = config.getValue(getWindowName() + "Show", true);
setDefaultSize(5, 25, 100, 100);
// set this to false as the minimap window size is changed
//depending on the map size
setResizable(false);
+ setupWindow->registerWindowForReset(this);
setDefaultVisible(true);
setSaveVisible(true);
diff --git a/src/gui/ministatus.cpp b/src/gui/ministatus.cpp
index 65d2391d..4cb0e1ac 100644
--- a/src/gui/ministatus.cpp
+++ b/src/gui/ministatus.cpp
@@ -22,7 +22,7 @@
#include "gui/ministatus.h"
#include "gui/gui.h"
-#include "gui/status.h"
+#include "gui/statuswindow.h"
#include "gui/widgets/progressbar.h"
@@ -33,34 +33,30 @@
#include "utils/stringutils.h"
+extern volatile int tick_time;
+
MiniStatusWindow::MiniStatusWindow():
Popup("MiniStatus")
{
- mHpBar = new ProgressBar(0.0f, 100, 20, gcn::Color(0, 171, 34));
-#ifdef EATHENA_SUPPORT
- mMpBar = new ProgressBar(0.0f, 100, 20, gcn::Color(26, 102, 230));
- mXpBar = new ProgressBar(0.0f, 100, 20, gcn::Color(143, 192, 211));
-#endif
-
+ mHpBar = new ProgressBar((float) player_node->getHp()
+ / (float) player_node->getMaxHp(),
+ 100, 20, gcn::Color(0, 171, 34));
+ mMpBar = new ProgressBar((float) player_node->getMaxMP()
+ / (float) player_node->getMaxMP(),
+ 100, 20, gcn::Color(26, 102, 230));
+ mXpBar = new ProgressBar((float) player_node->getExp()
+ / player_node->getExpNeeded(),
+ 100, 20, gcn::Color(143, 192, 211));
mHpBar->setPosition(0, 3);
-#ifdef EATHENA_SUPPORT
mMpBar->setPosition(mHpBar->getWidth() + 3, 3);
mXpBar->setPosition(mMpBar->getX() + mMpBar->getWidth() + 3, 3);
-#endif
add(mHpBar);
-#ifdef EATHENA_SUPPORT
add(mMpBar);
add(mXpBar);
-#endif
-#ifdef EATHENA_SUPPORT
setContentSize(mXpBar->getX() + mXpBar->getWidth(),
mXpBar->getY() + mXpBar->getHeight());
-#else
- setContentSize(mHpBar->getX() + mHpBar->getWidth(),
- mHpBar->getY() + mHpBar->getHeight());
-#endif
setVisible((bool) config.getValue(getPopupName() + "Visible", true));
}
@@ -81,14 +77,37 @@ void MiniStatusWindow::eraseIcon(int index)
mIcons.erase(mIcons.begin() + index);
}
-extern volatile int tick_time;
+void MiniStatusWindow::drawIcons(Graphics *graphics)
+{
+ // Draw icons
+ int icon_x = mXpBar->getX() + mXpBar->getWidth() + 4;
+ for (unsigned int i = 0; i < mIcons.size(); i++) {
+ if (mIcons[i]) {
+ mIcons[i]->draw(graphics, icon_x, 3);
+ icon_x += 2 + mIcons[i]->getWidth();
+ }
+ }
+}
-void MiniStatusWindow::update()
+void MiniStatusWindow::update(int id)
{
- StatusWindow::updateHPBar(mHpBar);
-#ifdef EATHENA_SUPPORT
- StatusWindow::updateMPBar(mMpBar);
- StatusWindow::updateXPBar(mXpBar);
+ if (id == StatusWindow::HP)
+ {
+ StatusWindow::updateHPBar(mHpBar);
+ }
+ else if (id == StatusWindow::MP)
+ {
+ StatusWindow::updateMPBar(mMpBar);
+ }
+ else if (id == StatusWindow::EXP)
+ {
+ StatusWindow::updateXPBar(mXpBar);
+ }
+}
+
+void MiniStatusWindow::logic()
+{
+ Popup::logic();
// Displays the number of monsters to next lvl
// (disabled for now but interesting idea)
@@ -102,31 +121,8 @@ void MiniStatusWindow::update()
<< config.getValue("xpBarMonsterCounterName", "Monsters") <<" left...";
}
*/
-#endif
for (unsigned int i = 0; i < mIcons.size(); i++)
if (mIcons[i])
mIcons[i]->update(tick_time * 10);
}
-
-void MiniStatusWindow::draw(gcn::Graphics *graphics)
-{
- update();
- drawChildren(graphics);
-}
-
-void MiniStatusWindow::drawIcons(Graphics *graphics)
-{
- // Draw icons
-#ifdef TMWSERV_SUPPORT
- int icon_x = mHpBar->getX() + mHpBar->getWidth() + 4;
-#else
- int icon_x = mXpBar->getX() + mXpBar->getWidth() + 4;
-#endif
- for (unsigned int i = 0; i < mIcons.size(); i++) {
- if (mIcons[i]) {
- mIcons[i]->draw(graphics, icon_x, 3);
- icon_x += 2 + mIcons[i]->getWidth();
- }
- }
-}
diff --git a/src/gui/ministatus.h b/src/gui/ministatus.h
index 56f53908..82ab0adc 100644
--- a/src/gui/ministatus.h
+++ b/src/gui/ministatus.h
@@ -40,8 +40,6 @@ class MiniStatusWindow : public Popup
public:
MiniStatusWindow();
- void draw(gcn::Graphics *graphics);
-
/**
* Sets one of the icons.
*/
@@ -51,22 +49,24 @@ class MiniStatusWindow : public Popup
void drawIcons(Graphics *graphics);
- private:
- /**
- * Updates this dialog with values from player_node.
- */
- void update();
+ void update(int id); // Same types as status window
+
+ void logic(); // Updates icons
+ void draw(gcn::Graphics *graphics)
+ { drawChildren(graphics); }
+
+ private:
/*
* Mini Status Bars
*/
ProgressBar *mHpBar;
-#ifdef EATHENA_SUPPORT
ProgressBar *mMpBar;
ProgressBar *mXpBar;
-#endif
std::vector<AnimatedSprite *> mIcons;
};
+extern MiniStatusWindow *miniStatusWindow;
+
#endif
diff --git a/src/gui/npcdialog.cpp b/src/gui/npcdialog.cpp
index afcc150d..1956ba85 100644
--- a/src/gui/npcdialog.cpp
+++ b/src/gui/npcdialog.cpp
@@ -28,6 +28,7 @@
#include "gui/widgets/scrollarea.h"
#include "gui/widgets/textbox.h"
#include "gui/widgets/textfield.h"
+#include "gui/setup.h"
#include "npc.h"
@@ -54,6 +55,7 @@ NpcDialog::NpcDialog()
// Basic Window Setup
setWindowName("NpcText");
setResizable(true);
+ setupWindow->registerWindowForReset(this);
setMinWidth(200);
setMinHeight(150);
@@ -91,8 +93,8 @@ NpcDialog::NpcDialog()
mButton = new Button("", "ok", this);
//Setup more and less buttons (int input)
- mPlusButton = new Button("+", "plus", this);
- mMinusButton = new Button("-", "minus", this);
+ mPlusButton = new Button(_("+"), "inc", this);
+ mMinusButton = new Button(_("-"), "dec", this);
int width = std::max(mButton->getFont()->getWidth(CAPTION_WAITING),
mButton->getFont()->getWidth(CAPTION_NEXT));
@@ -154,7 +156,8 @@ void NpcDialog::action(const gcn::ActionEvent &event)
if (mActionState == NPC_ACTION_NEXT)
{
nextDialog();
- addText("\n> Next\n");
+ // TRANSLATORS: Please leave the \n sequences intact.
+ addText(_("\n> Next\n"));
}
else if (mActionState == NPC_ACTION_CLOSE)
{
@@ -209,11 +212,11 @@ void NpcDialog::action(const gcn::ActionEvent &event)
mIntField->setValue(mDefaultInt);
}
}
- else if (event.getId() == "plus")
+ else if (event.getId() == "inc")
{
mIntField->setValue(mIntField->getValue() + 1);
}
- else if (event.getId() == "minus")
+ else if (event.getId() == "dec")
{
mIntField->setValue(mIntField->getValue() - 1);
}
diff --git a/src/gui/outfitwindow.cpp b/src/gui/outfitwindow.cpp
index f43e1440..d2e9468d 100644
--- a/src/gui/outfitwindow.cpp
+++ b/src/gui/outfitwindow.cpp
@@ -58,9 +58,9 @@ OutfitWindow::OutfitWindow():
setCloseButton(true);
setDefaultSize(250, 250, 118, 180); //160
- mPreviousButton = new Button("<", "previous", this);
- mNextButton = new Button(">", "next", this);
- mCurrentLabel = new Label("Outfit: 1");
+ mPreviousButton = new Button(_("<"), "previous", this);
+ mNextButton = new Button(_(">"), "next", this);
+ mCurrentLabel = new Label(strprintf(_("Outfit: %d"), 1));
mCurrentLabel->setAlignment(gcn::Graphics::CENTER);
mUnequipCheck = new CheckBox(_("Unequip first"),
config.getValue("OutfitUnequip", true));
@@ -140,7 +140,7 @@ void OutfitWindow::action(const gcn::ActionEvent &event)
mCurrentOutfit = 9;
}
}
- mCurrentLabel->setCaption("Outfit: " + toString(mCurrentOutfit + 1));
+ mCurrentLabel->setCaption(strprintf(_("Outfit: %d"), mCurrentOutfit + 1));
}
void OutfitWindow::wearOutfit(int outfit)
@@ -153,14 +153,8 @@ void OutfitWindow::wearOutfit(int outfit)
//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);
}
}
diff --git a/src/gui/palette.cpp b/src/gui/palette.cpp
index 4d1233e8..a807dcd6 100644
--- a/src/gui/palette.cpp
+++ b/src/gui/palette.cpp
@@ -82,18 +82,21 @@ Palette::Palette() :
addColor(SHADOW, 0x000000, STATIC, indent + _("Text Shadow"));
addColor(OUTLINE, 0x000000, STATIC, indent + _("Text Outline"));
addColor(PROGRESS_BAR, 0xffffff, STATIC, indent + _("Progress Bar Labels"));
+ addColor(BUTTON, 0xc8ad00, STATIC, indent + _("Buttons"));
+ addColor(BUTTON_DISABLED, 0x828282, STATIC, indent + _("Disabled Buttons"));
+ addColor(TAB, 0xc8ad00, STATIC, indent + _("Tabs"));
addColor(BACKGROUND, 0xffffff, STATIC, _("Background"));
addColor(HIGHLIGHT, 0xebc873, STATIC, _("Highlight"), 'H');
addColor(TAB_HIGHLIGHT, 0xff0000, PULSE, indent + _("Tab Highlight"));
- addColor(SHOP_WARNING, 0x910000, STATIC, indent + _("Item too expensive"));
- addColor(ITEM_EQUIPPED, 0x000091, STATIC, indent + _("Item is equipped"));
+ addColor(SHOP_WARNING, 0x910000, STATIC, indent + _("Item Too Expensive"));
+ addColor(ITEM_EQUIPPED, 0x000091, STATIC, indent + _("Item Is Equipped"));
addColor(CHAT, 0x000000, STATIC, _("Chat"), 'C');
addColor(GM, 0xff0000, STATIC, indent + _("GM"), 'G');
addColor(PLAYER, 0x1fa052, STATIC, indent + _("Player"), 'Y');
- addColor(WHISPER, 0x0000ff, STATIC, indent + _("Whisper"), 'W');
+ addColor(WHISPER, 0x00feaf, STATIC, indent + _("Whisper"), 'W');
addColor(IS, 0xa08527, STATIC, indent + _("Is"), 'I');
addColor(PARTY, 0xf48055, STATIC, indent + _("Party"), 'P');
addColor(SERVER, 0x8415e2, STATIC, indent + _("Server"), 'S');
@@ -112,10 +115,10 @@ Palette::Palette() :
addColor(HEAD, 0x527fa4, STATIC, indent + _("Hats"));
addColor(USABLE, 0x268d24, STATIC, indent + _("Usables"));
addColor(TORSO, 0xd12aa4, STATIC, indent + _("Shirts"));
- addColor(ONEHAND, 0xf42a2a, STATIC, indent + _("1 Handed Weapons"));
+ addColor(ONEHAND, 0xf42a2a, STATIC, indent + _("One Handed Weapons"));
addColor(LEGS, 0x699900, STATIC, indent + _("Pants"));
addColor(FEET, 0xaa1d48, STATIC, indent + _("Shoes"));
- addColor(TWOHAND, 0xf46d0e, STATIC, indent + _("2 Handed Weapons"));
+ addColor(TWOHAND, 0xf46d0e, STATIC, indent + _("Two Handed Weapons"));
addColor(SHIELD, 0x9c2424, STATIC, indent + _("Shields"));
addColor(RING, 0x0000ff, STATIC, indent + _("Rings"));
addColor(NECKLACE, 0xff00ff, STATIC, indent + _("Necklaces"));
@@ -126,9 +129,9 @@ Palette::Palette() :
addColor(PICKUP_INFO, 0x28dc28, STATIC, indent + _("Pickup Notification"));
addColor(EXP_INFO, 0xffff00, STATIC, indent + _("Exp Notification"));
addColor(HIT_PLAYER_MONSTER, 0x0064ff, STATIC,
- indent + _("Player hits Monster"));
+ indent + _("Player Hits Monster"));
addColor(HIT_MONSTER_PLAYER, 0xff3232, STATIC,
- indent + _("Monster hits Player"));
+ indent + _("Monster Hits Player"));
addColor(HIT_CRITICAL, 0xff0000, RAINBOW, indent + _("Critical Hit"));
addColor(MISS, 0xffff00, STATIC, indent + _("Misses"));
diff --git a/src/gui/palette.h b/src/gui/palette.h
index 1dec2a60..c68a4e1c 100644
--- a/src/gui/palette.h
+++ b/src/gui/palette.h
@@ -57,6 +57,9 @@ class Palette : public gcn::ListModel
ENTRY(SHADOW)\
ENTRY(OUTLINE)\
ENTRY(PROGRESS_BAR)\
+ ENTRY(BUTTON)\
+ ENTRY(BUTTON_DISABLED)\
+ ENTRY(TAB)\
ENTRY(BACKGROUND)\
ENTRY(HIGHLIGHT)\
ENTRY(TAB_HIGHLIGHT)\
diff --git a/src/gui/partywindow.cpp b/src/gui/partywindow.cpp
index f66ffaac..d4b084ce 100644
--- a/src/gui/partywindow.cpp
+++ b/src/gui/partywindow.cpp
@@ -22,6 +22,7 @@
#include "gui/partywindow.h"
#include "gui/widgets/chattab.h"
+#include "gui/setup.h"
#include "beingmanager.h"
#include "player.h"
@@ -56,6 +57,7 @@ PartyWindow::PartyWindow() :
setMinWidth(120);
setMinHeight(55);
setDefaultSize(590, 200, 150, 60);
+ setupWindow->registerWindowForReset(this);
loadWindowState();
}
diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp
index e12ca822..0f0df756 100644
--- a/src/gui/popupmenu.cpp
+++ b/src/gui/popupmenu.cpp
@@ -34,6 +34,7 @@
#include "graphics.h"
#include "item.h"
#include "localplayer.h"
+#include "log.h"
#include "npc.h"
#include "playerrelations.h"
@@ -72,10 +73,6 @@ void PopupMenu::showPopup(int x, int y, Being *being)
mBeingId = being->getId();
mBrowserBox->clearRows();
- // Any being's name can be added to chat
- if (being->getType() != Being::UNKNOWN)
- mBrowserBox->addRow(_("@@name|Add name to chat@@"));
-
const std::string &name = being->getType() == Being::NPC ?
being->getName().substr(0, being->getName().size()
- 6) : being->getName();
@@ -86,42 +83,68 @@ void PopupMenu::showPopup(int x, int y, Being *being)
{
// Players can be traded with. Later also follow and
// add as buddy will be options in this menu.
- mBrowserBox->addRow(strprintf(_("@@trade|Trade With %s@@"), name.c_str()));
- mBrowserBox->addRow(strprintf(_("@@attack|Attack %s@@"), name.c_str()));
+ mBrowserBox->addRow(strprintf("@@trade|%s@@",
+ strprintf(_("Trade with %s"),
+ name.c_str()).c_str()));
+ // TRANSLATORS: Attacking a player.
+ mBrowserBox->addRow(strprintf("@@attack|%s@@",
+ strprintf(_("Attack %s"),
+ name.c_str()).c_str()));
mBrowserBox->addRow("##3---");
switch (player_relations.getRelation(name)) {
case PlayerRelation::NEUTRAL:
- mBrowserBox->addRow(strprintf(_("@@friend|Befriend %s@@"), name.c_str()));
+ mBrowserBox->addRow(strprintf("@@friend|%s@@",
+ strprintf(_("Befriend %s"),
+ name.c_str()).c_str()));
case PlayerRelation::FRIEND:
- mBrowserBox->addRow(strprintf(_("@@disregard|Disregard %s@@"), name.c_str()));
- mBrowserBox->addRow(strprintf(_("@@ignore|Ignore %s@@"), name.c_str()));
+ mBrowserBox->addRow(strprintf("@@disregard|%s@@",
+ strprintf(_("Disregard %s"),
+ name.c_str()).c_str()));
+ mBrowserBox->addRow(strprintf("@@ignore|%s@@",
+ strprintf(_("Ignore %s"),
+ name.c_str()).c_str()));
break;
case PlayerRelation::DISREGARDED:
- mBrowserBox->addRow(strprintf(_("@@unignore|Un-Ignore %s@@"), name.c_str()));
- mBrowserBox->addRow(strprintf(_("@@ignore|Completely ignore %s@@"), name.c_str()));
+ mBrowserBox->addRow(strprintf("@@unignore|%s@@",
+ strprintf(_("Unignore %s"),
+ name.c_str()).c_str()));
+ mBrowserBox->addRow(strprintf("@@ignore|%s@@",
+ strprintf(_("Completely ignore %s"),
+ name.c_str()).c_str()));
break;
case PlayerRelation::IGNORED:
- mBrowserBox->addRow(strprintf(_("@@unignore|Un-Ignore %s@@"), name.c_str()));
+ mBrowserBox->addRow(strprintf("@@unignore|%s@@",
+ strprintf(_("Unignore %s"),
+ name.c_str()).c_str()));
break;
}
- //mBrowserBox->addRow(_(strprintf("@@follow|Follow %s@@"), name.c_str()));
- //mBrowserBox->addRow(_("@@buddy|Add ") + name + " to Buddy List@@");
+ /*mBrowserBox->addRow(strprintf("@@follow|%s@@",
+ strprintf(_("Follow %s"),
+ name.c_str()).c_str()));*/
+ /*mBrowserBox->addRow(strprintf("@@buddy|%s@@",
+ strprintf(_("Add %s to Buddy List"),
+ name.c_str()).c_str()));*/
#ifdef TMWSERV_SUPPORT
- mBrowserBox->addRow(strprintf(_("@@guild|Invite %s to join your guild@@"), name.c_str()));
+ mBrowserBox->addRow(strprintf("@@guild|%s@@",
+ strprintf(_("Invite %s to join your guild"),
+ name.c_str()).c_str()));
#endif
if (player_node->isInParty())
- mBrowserBox->addRow(strprintf(_("@@party|Invite %s to join your party@@"), name.c_str()));
+ mBrowserBox->addRow(strprintf("@@pickup|%s@@",
+ strprintf(_("Invite %s to join your party"),
+ name.c_str()).c_str()));
if (player_node->isGM())
{
mBrowserBox->addRow("##3---");
- mBrowserBox->addRow(_("@@admin-kick|Kick player@@"));
+ mBrowserBox->addRow(strprintf("@@admin-kick|%s@@",
+ _("Kick player")));
}
}
break;
@@ -129,16 +152,21 @@ void PopupMenu::showPopup(int x, int y, Being *being)
case Being::NPC:
// NPCs can be talked to (single option, candidate for removal
// unless more options would be added)
- mBrowserBox->addRow(strprintf(_("@@talk|Talk To %s@@"), name.c_str()));
+ mBrowserBox->addRow(strprintf("@@talk|%s@@",
+ strprintf(_("Talk to %s"),
+ name.c_str()).c_str()));
break;
case Being::MONSTER:
{
// Monsters can be attacked
- mBrowserBox->addRow(strprintf(_("@@attack|Attack %s@@"), name.c_str()));
+ mBrowserBox->addRow(strprintf("@@attack|%s@@",
+ strprintf(_("Attack %s"),
+ name.c_str()).c_str()));
if (player_node->isGM())
- mBrowserBox->addRow(_("@@admin-kick|Kick monster@@"));
+ mBrowserBox->addRow(strprintf("@@admin-kick|%s@@",
+ _("Kick monster")));
}
break;
@@ -146,10 +174,11 @@ void PopupMenu::showPopup(int x, int y, Being *being)
/* Other beings aren't interesting... */
return;
}
+ mBrowserBox->addRow(strprintf("@@name|%s@@", _("Add name to chat")));
- //browserBox->addRow("@@look|Look To@@");
+ //mBrowserBox->addRow(strprintf("@@look|%s@@", _("Look To")));
mBrowserBox->addRow("##3---");
- mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
showPopup(x, y);
}
@@ -162,12 +191,13 @@ void PopupMenu::showPopup(int x, int y, FloorItem *floorItem)
// Floor item can be picked up (single option, candidate for removal)
std::string name = ItemDB::get(mFloorItem->getItemId()).getName();
- mBrowserBox->addRow(strprintf(_("@@pickup|Pick up %s@@"), name.c_str()));
- mBrowserBox->addRow(_("@@chat|Add to chat@@"));
+ mBrowserBox->addRow(strprintf("@@pickup|%s@@", strprintf(_("Pick up %s"),
+ name.c_str()).c_str()));
+ mBrowserBox->addRow(strprintf("@@chat|%s@@", _("Add to chat")));
- //browserBox->addRow("@@look|Look To@@");
+ //mBrowserBox->addRow(strprintf("@@look|%s@@", _("Look To")));
mBrowserBox->addRow("##3---");
- mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
showPopup(x, y);
}
@@ -193,13 +223,11 @@ void PopupMenu::handleLink(const std::string &link)
Net::getTradeHandler()->request(being);
tradePartnerName = being->getName();
}
-#ifdef EATHENA_SUPPORT
// Attack action
else if (link == "attack" && being)
{
player_node->attack(being, true);
}
-#endif
else if (link == "unignore" &&
being &&
being->getType() == Being::PLAYER)
@@ -332,7 +360,7 @@ void PopupMenu::handleLink(const std::string &link)
// Unknown actions
else if (link != "cancel")
{
- std::cout << link << std::endl;
+ logger->log("PopupMenu: Warning, unknown action '%s'", link.c_str());
}
setVisible(false);
@@ -353,34 +381,34 @@ void PopupMenu::showPopup(int x, int y, Item *item, bool isInventory)
if (item->isEquipment())
{
if (item->isEquipped())
- mBrowserBox->addRow(_("@@use|Unequip@@"));
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Unequip")));
else
- mBrowserBox->addRow(_("@@use|Equip@@"));
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Equip")));
}
else
- mBrowserBox->addRow(_("@@use|Use@@"));
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Use")));
- mBrowserBox->addRow(_("@@drop|Drop@@"));
+ mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop")));
if (Net::getInventoryHandler()->canSplit(item))
{
- mBrowserBox->addRow(_("@@split|Split@@"));
+ mBrowserBox->addRow(strprintf("@@split|%s@@", _("Split")));
}
if (player_node->getInStorage())
{
- mBrowserBox->addRow(_("@@store|Store@@"));
+ mBrowserBox->addRow(strprintf("@@store|%s@@", _("Store")));
}
}
// Assume in storage for now
// TODO: make this whole system more flexible, if needed
else
{
- mBrowserBox->addRow(_("@@retrieve|Retrieve@@"));
+ mBrowserBox->addRow(strprintf("@@retrieve|%s@@", _("Retrieve")));
}
- mBrowserBox->addRow(_("@@chat|Add to chat@@"));
+ mBrowserBox->addRow(strprintf("@@chat|%s@@", _("Add to chat")));
mBrowserBox->addRow("##3---");
- mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
showPopup(x, y);
}
diff --git a/src/gui/recorder.cpp b/src/gui/recorder.cpp
index 3307d904..b2679553 100644
--- a/src/gui/recorder.cpp
+++ b/src/gui/recorder.cpp
@@ -28,6 +28,7 @@
#include "gui/widgets/layout.h"
#include "gui/widgets/windowcontainer.h"
+#include "utils/gettext.h"
#include "utils/stringutils.h"
#include <physfs.h>
diff --git a/src/gui/register.cpp b/src/gui/register.cpp
index 2b897641..f1313a5e 100644
--- a/src/gui/register.cpp
+++ b/src/gui/register.cpp
@@ -160,13 +160,13 @@ void RegisterDialog::action(const gcn::ActionEvent &event)
const std::string user = mUserField->getText();
logger->log("RegisterDialog::register Username is %s", user.c_str());
- std::string errorMsg;
+ std::string errorMessage;
int error = 0;
if (user.length() < LEN_MIN_USERNAME)
{
// Name too short
- errorMsg = strprintf
+ errorMessage = strprintf
(_("The username needs to be at least %d characters long."),
LEN_MIN_USERNAME);
error = 1;
@@ -174,7 +174,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event)
else if (user.length() > LEN_MAX_USERNAME - 1 )
{
// Name too long
- errorMsg = strprintf
+ errorMessage = strprintf
(_("The username needs to be less than %d characters long."),
LEN_MAX_USERNAME);
error = 1;
@@ -182,7 +182,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event)
else if (mPasswordField->getText().length() < LEN_MIN_PASSWORD)
{
// Pass too short
- errorMsg = strprintf
+ errorMessage = strprintf
(_("The password needs to be at least %d characters long."),
LEN_MIN_PASSWORD);
error = 2;
@@ -190,7 +190,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event)
else if (mPasswordField->getText().length() > LEN_MAX_PASSWORD - 1 )
{
// Pass too long
- errorMsg = strprintf
+ errorMessage = strprintf
(_("The password needs to be less than %d characters long."),
LEN_MAX_PASSWORD);
error = 2;
@@ -198,7 +198,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event)
else if (mPasswordField->getText() != mConfirmField->getText())
{
// Password does not match with the confirmation one
- errorMsg = _("Passwords do not match.");
+ errorMessage = _("Passwords do not match.");
error = 2;
}
@@ -219,7 +219,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event)
mWrongDataNoticeListener->setTarget(this->mPasswordField);
}
- OkDialog *dlg = new OkDialog(_("Error"), errorMsg);
+ OkDialog *dlg = new OkDialog(_("Error"), errorMessage);
dlg->addActionListener(mWrongDataNoticeListener);
}
else
diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp
index 28288ef4..4082b881 100644
--- a/src/gui/sell.cpp
+++ b/src/gui/sell.cpp
@@ -21,6 +21,7 @@
#include "gui/sell.h"
+#include "gui/setup.h"
#include "gui/shop.h"
#include "gui/shoplistbox.h"
@@ -47,6 +48,7 @@ SellDialog::SellDialog():
mMaxItems(0), mAmountItems(0)
{
setWindowName("Sell");
+ setupWindow->registerWindowForReset(this);
setResizable(true);
setCloseButton(true);
setMinWidth(260);
@@ -67,8 +69,8 @@ SellDialog::SellDialog():
mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"),
"", ""));
- mIncreaseButton = new Button("+", "+", this);
- mDecreaseButton = new Button("-", "-", this);
+ mIncreaseButton = new Button(_("+"), "inc", this);
+ mDecreaseButton = new Button(_("-"), "dec", this);
mSellButton = new Button(_("Sell"), "sell", this);
mQuitButton = new Button(_("Quit"), "quit", this);
mAddMaxButton = new Button(_("Max"), "max", this);
@@ -159,13 +161,13 @@ void SellDialog::action(const gcn::ActionEvent &event)
mAmountItems = (int) mSlider->getValue();
updateButtonsAndLabels();
}
- else if (event.getId() == "+" && mAmountItems < mMaxItems)
+ else if (event.getId() == "inc" && mAmountItems < mMaxItems)
{
mAmountItems++;
mSlider->setValue(mAmountItems);
updateButtonsAndLabels();
}
- else if (event.getId() == "-" && mAmountItems > 1)
+ else if (event.getId() == "dec" && mAmountItems > 1)
{
mAmountItems--;
mSlider->setValue(mAmountItems);
diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp
index 5d08a2ec..bd6b7d4b 100644
--- a/src/gui/serverdialog.cpp
+++ b/src/gui/serverdialog.cpp
@@ -71,7 +71,7 @@ void ServersListModel::addElement(Server server)
}
ServerDialog::ServerDialog(LoginData *loginData):
- Window(_("Choose your server")), mLoginData(loginData)
+ Window(_("Choose Your Server")), mLoginData(loginData)
{
gcn::Label *serverLabel = new Label(_("Server:"));
gcn::Label *portLabel = new Label(_("Port:"));
diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp
index aebcf61b..2f0d78ca 100644
--- a/src/gui/setup.cpp
+++ b/src/gui/setup.cpp
@@ -37,29 +37,7 @@
#include "utils/dtor.h"
#include "utils/gettext.h"
-extern Window *chatWindow;
extern Window *statusWindow;
-extern Window *buyDialog;
-extern Window *sellDialog;
-extern Window *buySellDialog;
-extern Window *inventoryWindow;
-extern Window *npcTextDialog;
-extern Window *npcStringDialog;
-extern Window *skillDialog;
-extern Window *partyWindow;
-extern Window *minimap;
-extern Window *equipmentWindow;
-extern Window *tradeWindow;
-extern Window *helpWindow;
-extern Window *debugWindow;
-extern Window *itemShortcutWindow;
-extern Window *emoteShortcutWindow;
-#ifdef TMWSERV_SUPPORT
-extern Window *magicDialog;
-extern Window *guildWindow;
-#else
-extern Window *storageWindow;
-#endif
Setup::Setup():
Window(_("Setup"))
@@ -137,29 +115,11 @@ void Setup::action(const gcn::ActionEvent &event)
if (!statusWindow)
return;
- chatWindow->resetToDefaultSize();
- statusWindow->resetToDefaultSize();
- buyDialog->resetToDefaultSize();
- sellDialog->resetToDefaultSize();
-#ifdef EATHENA_SUPPORT
- buySellDialog->resetToDefaultSize();
-#endif
- inventoryWindow->resetToDefaultSize();
- skillDialog->resetToDefaultSize();
- partyWindow->resetToDefaultSize();
- minimap->resetToDefaultSize();
- equipmentWindow->resetToDefaultSize();
- tradeWindow->resetToDefaultSize();
- helpWindow->resetToDefaultSize();
- debugWindow->resetToDefaultSize();
- itemShortcutWindow->resetToDefaultSize();
- emoteShortcutWindow->resetToDefaultSize();
-#ifdef TMWSERV_SUPPORT
- magicDialog->resetToDefaultSize();
- guildWindow->resetToDefaultSize();
-#else
- storageWindow->resetToDefaultSize();
-#endif
+ for (std::list<Window*>::iterator it = mWindowsToReset.begin();
+ it != mWindowsToReset.end(); it++)
+ {
+ (*it)->resetToDefaultSize();
+ }
}
}
@@ -168,4 +128,9 @@ void Setup::setInGame(bool inGame)
mResetWindows->setEnabled(inGame);
}
+void Setup::registerWindowForReset(Window *window)
+{
+ mWindowsToReset.push_back(window);
+}
+
Setup *setupWindow;
diff --git a/src/gui/setup.h b/src/gui/setup.h
index 630d5eaa..6000adfa 100644
--- a/src/gui/setup.h
+++ b/src/gui/setup.h
@@ -61,8 +61,14 @@ class Setup : public Window, public gcn::ActionListener
*/
void setInGame(bool inGame);
+ void registerWindowForReset(Window *window);
+
+ void clearWindowsForReset()
+ { mWindowsToReset.clear(); }
+
private:
std::list<SetupTab*> mTabs;
+ std::list<Window*> mWindowsToReset;
gcn::Button *mResetWindows;
};
diff --git a/src/gui/setup_audio.cpp b/src/gui/setup_audio.cpp
index 9da74c2e..990a3ce8 100644
--- a/src/gui/setup_audio.cpp
+++ b/src/gui/setup_audio.cpp
@@ -91,7 +91,7 @@ void Setup_Audio::apply()
}
catch (const char *err)
{
- new OkDialog("Sound Engine", err);
+ new OkDialog(_("Sound Engine"), err);
logger->log("Warning: %s", err);
}
}
diff --git a/src/gui/setup_colors.cpp b/src/gui/setup_colors.cpp
index efa03ba4..7e8b8946 100644
--- a/src/gui/setup_colors.cpp
+++ b/src/gui/setup_colors.cpp
@@ -68,7 +68,7 @@ Setup_Colors::Setup_Colors() :
mPreviewBox->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER,
gcn::ScrollArea::SHOW_NEVER);
- mGradTypeLabel = new Label(_("Type: "));
+ mGradTypeLabel = new Label(_("Type:"));
mGradTypeSlider = new Slider(0, 3);
mGradTypeSlider->setWidth(200);
@@ -90,7 +90,7 @@ Setup_Colors::Setup_Colors() :
mGradTypeText->setCaption(longText);
- mGradDelayLabel = new Label(_("Delay: "));
+ mGradDelayLabel = new Label(_("Delay:"));
mGradDelayText = new TextField();
mGradDelayText->setWidth(40);
@@ -105,7 +105,7 @@ Setup_Colors::Setup_Colors() :
mGradDelaySlider->addActionListener(this);
mGradDelaySlider->setEnabled(false);
- mRedLabel = new Label(_("Red: "));
+ mRedLabel = new Label(_("Red:"));
mRedText = new TextField;
mRedText->setWidth(40);
@@ -120,7 +120,7 @@ Setup_Colors::Setup_Colors() :
mRedSlider->addActionListener(this);
mRedSlider->setEnabled(false);
- mGreenLabel = new Label(_("Green: "));
+ mGreenLabel = new Label(_("Green:"));
mGreenText = new TextField;
mGreenText->setWidth(40);
@@ -135,7 +135,7 @@ Setup_Colors::Setup_Colors() :
mGreenSlider->addActionListener(this);
mGreenSlider->setEnabled(false);
- mBlueLabel = new Label(_("Blue: "));
+ mBlueLabel = new Label(_("Blue:"));
mBlueText = new TextField;
mBlueText->setWidth(40);
@@ -262,6 +262,9 @@ void Setup_Colors::valueChanged(const gcn::SelectionEvent &event)
mTextPreview->setOutline(true);
mTextPreview->setShadow(false);
break;
+ case Palette::BUTTON:
+ case Palette::BUTTON_DISABLED:
+ case Palette::TAB:
case Palette::TAB_HIGHLIGHT:
mTextPreview->setFont(gui->getFont());
mTextPreview->setTextColor(col);
diff --git a/src/gui/setup_keyboard.cpp b/src/gui/setup_keyboard.cpp
index 938c1c4e..d9117b8a 100644
--- a/src/gui/setup_keyboard.cpp
+++ b/src/gui/setup_keyboard.cpp
@@ -116,7 +116,7 @@ void Setup_Keyboard::apply()
if (keyboard.hasConflicts())
{
- new OkDialog(_("Key Conflict(s) Detected."),
+ new OkDialog(_("Key Conflict(s) Detected"),
_("Resolve them, or gameplay may result in strange "
"behaviour."));
}
diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp
index a9c892b2..f21f20e0 100644
--- a/src/gui/setup_video.cpp
+++ b/src/gui/setup_video.cpp
@@ -192,15 +192,17 @@ Setup_Video::Setup_Video():
mVisibleNamesEnabled)),
mParticleEffectsCheckBox(new CheckBox(_("Particle effects"),
mParticleEffectsEnabled)),
- mNameCheckBox(new CheckBox(_("Show name"), mNameEnabled)),
+ mNameCheckBox(new CheckBox(_("Show own name"), mNameEnabled)),
mPickupNotifyLabel(new Label(_("Show pickup notification"))),
+ // TRANSLATORS: Refers to "Show own name"
mPickupChatCheckBox(new CheckBox(_("in chat"), mPickupChatEnabled)),
+ // TRANSLATORS: Refers to "Show own name"
mPickupParticleCheckBox(new CheckBox(_("as particle"),
mPickupParticleEnabled)),
mSpeechSlider(new Slider(0, 3)),
mSpeechLabel(new Label("")),
mAlphaSlider(new Slider(0.2, 1.0)),
- mFpsCheckBox(new CheckBox(_("FPS Limit:"))),
+ mFpsCheckBox(new CheckBox(_("FPS limit:"))),
mFpsSlider(new Slider(10, 120)),
mFpsField(new TextField),
mOverlayDetail((int) config.getValue("OverlayDetail", 2)),
@@ -219,7 +221,7 @@ Setup_Video::Setup_Video():
speechLabel = new Label(_("Overhead text"));
alphaLabel = new Label(_("Gui opacity"));
overlayDetailLabel = new Label(_("Ambient FX"));
- particleDetailLabel = new Label(_("Particle Detail"));
+ particleDetailLabel = new Label(_("Particle detail"));
fontSizeLabel = new Label(_("Font size"));
mFontSizeDropDown = new DropDown(new FontSizeChoiceListModel);
@@ -352,19 +354,27 @@ void Setup_Video::apply()
fullscreen = !fullscreen;
if (!graphics->setFullscreen(fullscreen))
{
- std::stringstream error;
- error << _("Failed to switch to ") <<
- (fullscreen ? _("windowed") : _("fullscreen")) <<
- _("mode and restoration of old mode also failed!") <<
- std::endl;
- logger->error(error.str());
+ std::stringstream errorMessage;
+ if (fullscreen)
+ {
+ errorMessage << _("Failed to switch to windowed mode "
+ "and restoration of old mode also "
+ "failed!") << std::endl;
+ }
+ else
+ {
+ errorMessage << _("Failed to switch to fullscreen mode "
+ "and restoration of old mode also "
+ "failed!") << std::endl;
+ }
+ logger->error(errorMessage.str());
}
}
#if defined(WIN32) || defined(__APPLE__)
}
else
{
- new OkDialog(_("Switching to full screen"),
+ new OkDialog(_("Switching to Full Screen"),
_("Restart needed for changes to take effect."));
}
#endif
@@ -377,7 +387,7 @@ void Setup_Video::apply()
config.setValue("opengl", mOpenGLCheckBox->isSelected());
// OpenGL can currently only be changed by restarting, notify user.
- new OkDialog(_("Changing OpenGL"),
+ new OkDialog(_("Changing to OpenGL"),
_("Applying change to OpenGL requires restart."));
}
@@ -436,11 +446,17 @@ void Setup_Video::action(const gcn::ActionEvent &event)
const int width = atoi(mode.substr(0, mode.find("x")).c_str());
const int height = atoi(mode.substr(mode.find("x") + 1).c_str());
+ // TODO: Find out why the drawing area doesn't resize without a restart.
if (width != graphics->getWidth() || height != graphics->getHeight())
{
- // TODO: Find out why the drawing area doesn't resize without a restart.
- new OkDialog(_("Screen resolution changed"),
- _("Restart your client for the change to take effect."));
+ if (width < graphics->getWidth() || height < graphics->getHeight())
+ new OkDialog(_("Screen Resolution Changed"),
+ _("Restart your client for the change to take effect.")
+ + std::string("\n") +
+ _("Some windows may be moved to fit the lowered resolution."));
+ else
+ new OkDialog(_("Screen Resolution Changed"),
+ _("Restart your client for the change to take effect."));
}
config.setValue("screenwidth", width);
@@ -464,7 +480,7 @@ void Setup_Video::action(const gcn::ActionEvent &event)
mParticleEffectsCheckBox->isSelected());
if (engine)
{
- new OkDialog(_("Particle effect settings changed."),
+ new OkDialog(_("Particle Effect Settings Changed."),
_("Changes will take effect on map change."));
}
}
diff --git a/src/gui/shortcutwindow.cpp b/src/gui/shortcutwindow.cpp
index b9eda02c..8e7e0bee 100644
--- a/src/gui/shortcutwindow.cpp
+++ b/src/gui/shortcutwindow.cpp
@@ -25,6 +25,7 @@
#include "gui/widgets/layout.h"
#include "gui/widgets/scrollarea.h"
+#include "gui/setup.h"
#include "configuration.h"
@@ -42,6 +43,7 @@ ShortcutWindow::ShortcutWindow(const std::string &title,
setResizable(true);
setDefaultVisible(false);
setSaveVisible(true);
+ setupWindow->registerWindowForReset(this);
mItems = content;
diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp
deleted file mode 100644
index 7698098c..00000000
--- a/src/gui/skill.cpp
+++ /dev/null
@@ -1,300 +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/skill.h"
-
-#include "gui/table.h"
-
-#include "gui/widgets/button.h"
-#include "gui/widgets/label.h"
-#include "gui/widgets/layout.h"
-#include "gui/widgets/listbox.h"
-#include "gui/widgets/scrollarea.h"
-#include "gui/widgets/windowcontainer.h"
-
-#include "localplayer.h"
-#include "log.h"
-
-#include "net/net.h"
-#include "net/skillhandler.h"
-
-#include "utils/dtor.h"
-#include "utils/gettext.h"
-#include "utils/stringutils.h"
-#include "utils/xml.h"
-
-static const char *SKILLS_FILE = "skills.xml";
-
-struct SkillInfo
-{
- std::string name;
- bool modifiable;
-};
-
-static const SkillInfo fakeSkillInfo = {
- _("Mystery Skill"),
- false
-};
-
-std::vector<SkillInfo> skill_db;
-
-static void initSkillinfo();
-
-class SkillGuiTableModel : public StaticTableModel
-{
-public:
- SkillGuiTableModel(SkillDialog *dialog) :
- StaticTableModel(0, 3)
- {
- mEntriesNr = 0;
- mDialog = dialog;
- update();
- }
-
- virtual int getRows() const
- {
- return mEntriesNr;
- }
-
- virtual int getColumnWidth(int index) const
- {
- if (index == 0)
- return 160;
-
- return 35;
- }
-
- virtual int getRowHeight() const
- {
- return 12;
- }
-
- virtual void update()
- {
- mEntriesNr = mDialog->getSkills().size();
- resize();
-
- for (int i = 0; i < mEntriesNr; i++)
- {
- SKILL *skill = mDialog->getSkills()[i];
- SkillInfo const *info;
- char tmp[128];
-
- if (skill->id >= 0
- && (unsigned int) skill->id < skill_db.size())
- info = &skill_db[skill->id];
- else
- info = &fakeSkillInfo;
-
- sprintf(tmp, "%c%s", info->modifiable? ' ' : '*', info->name.c_str());
- gcn::Label *name_label = new Label(tmp);
-
- sprintf(tmp, "Lv:%i", skill->lv);
- gcn::Label *lv_label = new Label(tmp);
-
- sprintf(tmp, "Sp:%i", skill->sp);
- gcn::Label *sp_label = new Label(tmp);
-
- set(i, 0, name_label);
- set(i, 1, lv_label);
- set(i, 2, sp_label);
- }
- }
-
-private:
- SkillDialog *mDialog;
- int mEntriesNr;
-};
-
-
-SkillDialog::SkillDialog():
- Window(_("Skills"))
-{
- initSkillinfo();
- mTableModel = new SkillGuiTableModel(this);
- mTable = new GuiTable(mTableModel);
- mTable->setOpaque(false);
- mTable->setLinewiseSelection(true);
- mTable->setWrappingEnabled(true);
- mTable->setActionEventId("skill");
- mTable->addActionListener(this);
-
- setWindowName("Skills");
- setCloseButton(true);
- setDefaultSize(255, 260, ImageRect::CENTER);
-
- setMinHeight(50 + mTableModel->getHeight());
- setMinWidth(200);
-
- ScrollArea *skillScrollArea = new ScrollArea(mTable);
- mPointsLabel = new Label(strprintf(_("Skill points: %d"), 0));
- mIncButton = new Button(_("Up"), "inc", this);
- mUseButton = new Button(_("Use"), "use", this);
- mUseButton->setEnabled(false);
-
- skillScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
-
- place(0, 0, skillScrollArea, 5).setPadding(3);
- place(0, 1, mPointsLabel, 4);
- place(3, 2, mIncButton);
- place(4, 2, mUseButton);
-
- Layout &layout = getLayout();
- layout.setRowHeight(0, Layout::AUTO_SET);
-
- center();
- loadWindowState();
-}
-
-SkillDialog::~SkillDialog()
-{
- delete_all(mSkillList);
-}
-
-void SkillDialog::action(const gcn::ActionEvent &event)
-{
- if (event.getId() == "inc")
- {
- // Increment skill
- int selectedSkill = mTable->getSelectedRow();
- if (selectedSkill >= 0)
- Net::getSkillHandler()->up(mSkillList[selectedSkill]->id);
- }
- else if (event.getId() == "skill" && mTable->getSelectedRow() > -1)
- {
- SKILL *skill = mSkillList[mTable->getSelectedRow()];
- SkillInfo const *info;
-
- if (skill->id >= 0 && (unsigned int) skill->id < skill_db.size())
- info = &skill_db[skill->id];
- else
- info = &fakeSkillInfo;
-
- mIncButton->setEnabled(player_node->mSkillPoint > 0 &&
- info->modifiable);
- }
- else if (event.getId() == "close")
- setVisible(false);
-}
-
-void SkillDialog::update()
-{
- mPointsLabel->setCaption(strprintf(_("Skill points: %d"),
- player_node->mSkillPoint));
-
- int selectedSkill = mTable->getSelectedRow();
-
- if (selectedSkill >= 0)
- {
- int skillId = mSkillList[selectedSkill]->id;
- bool modifiable;
-
- if (skillId >= 0 && (unsigned int) skillId < skill_db.size())
- modifiable = skill_db[skillId].modifiable;
- else
- modifiable = false;
-
- mIncButton->setEnabled(modifiable
- && player_node->mSkillPoint > 0);
- }
- else
- mIncButton->setEnabled(false);
-
- mTableModel->update();
- setMinHeight(50 + mTableModel->getHeight());
-}
-
-int SkillDialog::getNumberOfElements()
-{
- return mSkillList.size();
-}
-
-bool SkillDialog::hasSkill(int id)
-{
- for (unsigned int i = 0; i < mSkillList.size(); i++)
- {
- if (mSkillList[i]->id == id)
- return true;
- }
- return false;
-}
-
-void SkillDialog::addSkill(int id, int lvl, int mp)
-{
- SKILL *tmp = new SKILL;
- tmp->id = id;
- tmp->lv = lvl;
- tmp->sp = mp;
- mSkillList.push_back(tmp);
-}
-
-void SkillDialog::setSkill(int id, int lvl, int mp)
-{
- for (unsigned int i = 0; i < mSkillList.size(); i++)
- {
- if (mSkillList[i]->id == id)
- {
- mSkillList[i]->lv = lvl;
- mSkillList[i]->sp = mp;
- }
- }
-}
-
-void SkillDialog::cleanList()
-{
- delete_all(mSkillList);
- mSkillList.clear();
-}
-
-static void initSkillinfo()
-{
- SkillInfo emptySkillInfo = { "", false };
-
- XML::Document doc(SKILLS_FILE);
- xmlNodePtr root = doc.rootNode();
-
- if (!root || !xmlStrEqual(root->name, BAD_CAST "skills"))
- {
- logger->log("Error loading skills file: %s", SKILLS_FILE);
- skill_db.resize(2, emptySkillInfo);
- skill_db[1].name = "Basic";
- skill_db[1].modifiable = true;
- return;
- }
-
- for_each_xml_child_node(node, root)
- {
- if (xmlStrEqual(node->name, BAD_CAST "skill"))
- {
- int index = atoi(XML::getProperty(node, "id", "-1").c_str());
- std::string name = XML::getProperty(node, "name", "");
- bool modifiable = !atoi(XML::getProperty(node, "fixed", "0").c_str());
-
- if (index >= 0)
- {
- skill_db.resize(index + 1, emptySkillInfo);
- skill_db[index].name = name;
- skill_db[index].modifiable = modifiable;
- }
- }
- }
-}
-
diff --git a/src/gui/skill.h b/src/gui/skill.h
deleted file mode 100644
index 0879f7e1..00000000
--- a/src/gui/skill.h
+++ /dev/null
@@ -1,85 +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 SKILL_H
-#define SKILL_H
-
-#include "gui/widgets/window.h"
-
-#include <guichan/actionlistener.hpp>
-
-#include <vector>
-
-struct SKILL
-{
- short id; /**< Index into "skill_db" array */
- short lv, sp;
-};
-
-class GuiTable;
-class ScrollArea;
-class SkillGuiTableModel;
-
-/**
- * The skill dialog.
- *
- * \ingroup Interface
- */
-class SkillDialog : public Window, public gcn::ActionListener
-{
- public:
- /**
- * Constructor.
- */
- SkillDialog();
-
- /**
- * Destructor.
- */
- ~SkillDialog();
-
- void action(const gcn::ActionEvent &event);
-
- void update();
-
- int getNumberOfElements();
-
- bool hasSkill(int id);
- void addSkill(int id, int lv, int sp);
- void setSkill(int id, int lv, int sp);
- void cleanList();
-
- const std::vector<SKILL*>& getSkills() const { return mSkillList; }
-
- private:
- GuiTable *mTable;
- ScrollArea *skillScrollArea;
- SkillGuiTableModel *mTableModel;
- gcn::Label *mPointsLabel;
- gcn::Button *mIncButton;
- gcn::Button *mUseButton;
-
- std::vector<SKILL*> mSkillList;
-};
-
-extern SkillDialog *skillDialog;
-
-#endif
diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp
index f0cd01ce..14e0e5a4 100644
--- a/src/gui/skilldialog.cpp
+++ b/src/gui/skilldialog.cpp
@@ -25,105 +25,78 @@
#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/vertcontainer.h"
#include "gui/widgets/windowcontainer.h"
+#include "gui/setup.h"
#include "localplayer.h"
+#include "log.h"
+
+#include "net/net.h"
+#include "net/playerhandler.h"
#include "utils/dtor.h"
#include "utils/gettext.h"
#include "utils/stringutils.h"
+#include "utils/xml.h"
#include <string>
#include <vector>
-class SkillTab : public Container, public gcn::ActionListener
+class SkillEntry;
+
+struct SkillInfo
+{
+ unsigned short id;
+ std::string name;
+ std::string icon;
+ bool modifiable;
+ SkillEntry *display;
+};
+
+class SkillEntry : public Container, gcn::WidgetListener
{
public:
- /**
- * The type of this skill tab
- */
- const std::string type;
-
- /**
- * Constructor
- */
- SkillTab(const std::string &type);
-
- /**
- * Update this tab
- */
+ SkillEntry(SkillInfo *info);
+
+ void widgetResized(const gcn::Event &event);
+
void update();
- /**
- * Called when receiving actions from widget.
- */
- void action(const gcn::ActionEvent &event) {}
+ protected:
+ friend class SkillDialog;
+ SkillInfo *mInfo;
private:
- /**
- * Update the information of a skill at
- * the given index
- */
- void updateSkill(int index);
-
- /**
- * Gets the number of skills in this particular
- * type of tab.
- */
- int getSkillNum();
-
- /**
- * Get the first enumeration of this skill tab's
- * skill type.
- */
- int getSkillBegin();
-
- /**
- * Get the icon associated with the given index
- */
- Icon *getIcon(int index);
-
- std::vector<Icon *> mSkillIcons;
- std::vector<gcn::Label *> mSkillNameLabels;
- std::vector<gcn::Label *> mSkillLevelLabels;
- std::vector<gcn::Label *> mSkillExpLabels;
- std::vector<ProgressBar *> mSkillProgress;
+ Icon *mIcon;
+ Label *mNameLabel;
+ Label *mLevelLabel;
+ Label *mExpLabel;
+ Button *mIncrease;
+ ProgressBar *mProgress;
};
-
SkillDialog::SkillDialog():
Window(_("Skills"))
{
setWindowName("Skills");
setCloseButton(true);
+ setResizable(true);
setSaveVisible(true);
setDefaultSize(windowContainer->getWidth() - 280, 30, 275, 425);
+ setupWindow->registerWindowForReset(this);
- TabbedArea *panel = new TabbedArea;
- panel->setDimension(gcn::Rectangle(5, 5, 270, 420));
-
- SkillTab *tab;
-
- // Add each type of skill tab to the panel
- tab = new SkillTab("Weapon");
- panel->addTab(_("Weapons"), tab);
- mTabs.push_back(tab);
+ mTabs = new TabbedArea();
+ mPointsLabel = new Label("0");
- tab = new SkillTab("Magic");
- panel->addTab(_("Magic"), tab);
- mTabs.push_back(tab);
-
- tab = new SkillTab("Craft");
- panel->addTab(_("Crafts"), tab);
- mTabs.push_back(tab);
-
- add(panel);
-
- update();
+ place(0, 0, mTabs, 5, 5);
+ place(0, 5, mPointsLabel);
setLocationRelativeTo(getParent());
loadWindowState();
@@ -131,13 +104,17 @@ SkillDialog::SkillDialog():
SkillDialog::~SkillDialog()
{
- delete_all(mTabs);
+ //delete_all(mTabs);
}
void SkillDialog::action(const gcn::ActionEvent &event)
{
- if (event.getId() == "skill")
+ if (event.getId() == "inc")
{
+ SkillEntry *disp = dynamic_cast<SkillEntry*>(event.getSource()->getParent());
+
+ if (disp)
+ Net::getPlayerHandler()->increaseSkill(disp->mInfo->id);
}
else if (event.getId() == "close")
{
@@ -145,174 +122,254 @@ void SkillDialog::action(const gcn::ActionEvent &event)
}
}
-void SkillDialog::draw(gcn::Graphics *g)
+void SkillDialog::adjustTabSize()
{
- update();
+ 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);
- Window::draw(g);
+ adjustTabSize();
}
-void SkillDialog::update()
+void SkillDialog::logic()
{
- for(std::list<SkillTab*>::const_iterator i = mTabs.begin();
- i != mTabs.end(); ++i)
- {
- (*i)->update();
+ Window::logic();
+
+ Tab *tab = dynamic_cast<Tab*>(mTabs->getSelectedTab());
+ if (tab != mCurrentTab) {
+ mCurrentTab = tab;
+ adjustTabSize();
}
}
-SkillTab::SkillTab(const std::string &type): type(type)
+std::string SkillDialog::update(int id)
{
- setOpaque(false);
- setDimension(gcn::Rectangle(0, 0, 270, 420));
- int skillNum = getSkillNum();
-
- mSkillIcons.resize(skillNum);
- mSkillNameLabels.resize(skillNum);
- mSkillLevelLabels.resize(skillNum);
- mSkillExpLabels.resize(skillNum);
- mSkillProgress.resize(skillNum);
+ SkillMap::iterator i = mSkills.find(id);
- // Set the initial positions of the skill information
- for (int a = 0; a < skillNum; a++)
+ if (i != mSkills.end())
{
- mSkillIcons.at(a) = getIcon(a);
- mSkillIcons.at(a)->setPosition(1, a*32);
- add(mSkillIcons.at(a));
-
- mSkillNameLabels.at(a) = new Label("");
- mSkillNameLabels.at(a)->setPosition(35, a*32 );
- add(mSkillNameLabels.at(a));
+ SkillInfo *info = i->second;
+ info->display->update();
+ return info->name;
+ }
- mSkillProgress.at(a) = new ProgressBar(0.0f, 200, 20, gcn::Color(150, 150, 150));
- mSkillProgress.at(a)->setPosition(35, a*32 + 13);
- add(mSkillProgress.at(a));
+ return std::string();
+}
- mSkillExpLabels.at(a) = new Label("");
- mSkillExpLabels.at(a)->setPosition(45, a*32 + 16);
- add(mSkillExpLabels.at(a));
+void SkillDialog::update()
+{
+ mPointsLabel->setCaption(strprintf(_("Skill points available: %d"),
+ player_node->getSkillPoints()));
+ mPointsLabel->adjustSize();
- mSkillLevelLabels.at(a) = new Label("");
- mSkillLevelLabels.at(a)->setPosition(165, a*32);
- add(mSkillLevelLabels.at(a));
+ for (SkillMap::iterator it = mSkills.begin(); it != mSkills.end(); it++)
+ {
+ if ((*it).second->modifiable)
+ (*it).second->display->update();
}
-
- update();
}
-int SkillTab::getSkillNum()
+void SkillDialog::loadSkills(const std::string &file)
{
- int skillNum = 0;
+ // TODO: mTabs->clear();
+ delete_all(mSkills);
+ mSkills.clear();
- if (type == "Weapon")
+ XML::Document doc(file);
+ xmlNodePtr root = doc.rootNode();
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "skills"))
{
- skillNum = CHAR_SKILL_WEAPON_NB;
- return skillNum;
+ logger->log("Error loading skills file: %s", file.c_str());
+ return;
}
- else if (type == "Magic")
+
+ int setCount = 0;
+ std::string setName;
+ ScrollArea *scroll;
+ VertContainer *container;
+
+ for_each_xml_child_node(set, root)
{
- skillNum = CHAR_SKILL_MAGIC_NB;
- return skillNum;
+ if (xmlStrEqual(set->name, BAD_CAST "set"))
+ {
+ setCount++;
+ setName = XML::getProperty(set, "name", strprintf(_("Skill Set %d"), setCount));
+
+ container = new VertContainer(32);
+ 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 "skill"))
+ {
+ int id = atoi(XML::getProperty(node, "id", "-1").c_str());
+ std::string name = XML::getProperty(node, "name", strprintf(_("Skill %d"), id));
+ std::string icon = XML::getProperty(node, "icon", "");
+
+ SkillInfo *skill = new SkillInfo;
+ skill->id = id;
+ skill->name = name;
+ skill->icon = icon;
+ skill->modifiable = 0;
+ skill->display = new SkillEntry(skill);
+
+ container->add(skill->display);
+
+ mSkills[id] = skill;
+ }
+ }
+ }
}
- else if (type == "Craft")
+
+ adjustTabSize();
+ update();
+}
+
+void SkillDialog::setModifiable(int id, bool modifiable)
+{
+ SkillMap::iterator i = mSkills.find(id);
+
+ if (i != mSkills.end())
{
- skillNum = CHAR_SKILL_CRAFT_NB;
- return skillNum;
+ SkillInfo *info = i->second;
+ info->modifiable = modifiable;
+ info->display->update();
}
- else return skillNum;
}
-int SkillTab::getSkillBegin()
+SkillEntry::SkillEntry(SkillInfo *info) :
+ mInfo(info),
+ mIcon(NULL),
+ mNameLabel(new Label(info->name)),
+ mLevelLabel(new Label("999")),
+ mIncrease(new Button(_("+"), "inc", skillDialog)),
+ mProgress(new ProgressBar(0.0f, 200, 20, gcn::Color(150, 150, 150)))
+{
+ setFrameSize(1);
+ setOpaque(false);
+
+ addWidgetListener(this);
+
+ 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(165, 0);
+ add(mLevelLabel);
+
+ mProgress->setPosition(35, 13);
+ add(mProgress);
+
+ mIncrease->setPosition(getWidth() - mIncrease->getWidth(), 13);
+ add(mIncrease);
+
+ update();
+}
+
+void SkillEntry::widgetResized(const gcn::Event &event)
{
- int skillBegin = 0;
+ gcn::Rectangle size = getChildrenArea();
- if (type == "Weapon")
+ if (mProgress->isVisible() && mIncrease->isVisible())
{
- skillBegin = CHAR_SKILL_WEAPON_BEGIN - CHAR_SKILL_BEGIN;
- return skillBegin;
+ mLevelLabel->setPosition(size.width - mLevelLabel->getWidth()
+ - mIncrease->getWidth() - 4, 0);
+ mProgress->setWidth(size.width - mIncrease->getWidth() - 39);
+ mIncrease->setPosition(getWidth() - mIncrease->getWidth() - 2, 6);
}
- else if (type == "Magic")
+ else if (mProgress->isVisible())
{
- skillBegin = CHAR_SKILL_MAGIC_BEGIN - CHAR_SKILL_BEGIN;
- return skillBegin;
+ mLevelLabel->setPosition(size.width - mLevelLabel->getWidth(), 0);
+ mProgress->setWidth(size.width - 39);
}
- else if (type == "Craft")
+ else if (mIncrease->isVisible())
{
- skillBegin = CHAR_SKILL_CRAFT_BEGIN - CHAR_SKILL_BEGIN;
- return skillBegin;
+ mLevelLabel->setPosition(size.width - mLevelLabel->getWidth()
+ - mIncrease->getWidth() - 4, 0);
+ mIncrease->setPosition(getWidth() - mIncrease->getWidth() - 2, 6);
}
- else return skillBegin;
+ else
+ mLevelLabel->setPosition(size.width - mLevelLabel->getWidth(), 0);
}
-Icon* SkillTab::getIcon(int index)
+void SkillEntry::update()
{
- int skillBegin = getSkillBegin();
- std::string icon = LocalPlayer::getSkillInfo(index + skillBegin).icon;
- return new Icon(icon);
-}
+ int baseLevel = player_node->getAttributeBase(mInfo->id);
+ int effLevel = player_node->getAttributeEffective(mInfo->id);
-void SkillTab::updateSkill(int index)
-{
- int skillBegin = getSkillBegin();
+ if (baseLevel <= 0 && !mInfo->modifiable)
+ {
+ setVisible(false);
+ return;
+ }
+
+ setVisible(true);
- int baseLevel = player_node->getAttributeBase(index +
- skillBegin +
- CHAR_SKILL_BEGIN);
+ std::string skillLevel;
- int effLevel = player_node->getAttributeEffective(index +
- skillBegin +
- CHAR_SKILL_BEGIN);
- if(baseLevel <= 0)
+ if (effLevel != baseLevel)
{
- mSkillProgress.at(index)->setVisible(false);
- mSkillExpLabels.at(index)->setVisible(false);
- mSkillLevelLabels.at(index)->setVisible(false);
- mSkillNameLabels.at(index)->setVisible(false);
- mSkillIcons.at(index)->setVisible(false);
+ skillLevel = strprintf(_("Lvl: %d (%+d)"),
+ baseLevel, baseLevel - effLevel);
}
else
{
- mSkillProgress.at(index)->setVisible(true);
- mSkillExpLabels.at(index)->setVisible(true);
- mSkillLevelLabels.at(index)->setVisible(true);
- mSkillNameLabels.at(index)->setVisible(true);
- mSkillIcons.at(index)->setVisible(true);
- std::string skillLevel("Lvl: " + toString(baseLevel));
- if (effLevel < baseLevel)
- {
- skillLevel.append(" - " + toString(baseLevel - effLevel));
- }
- else if (effLevel > baseLevel)
- {
- skillLevel.append(" + " + toString(effLevel - baseLevel));
- }
- mSkillLevelLabels.at(index)->setCaption(skillLevel);
+ skillLevel = strprintf(_("Lvl: %d"), baseLevel);
+ }
- std::pair<int, int> exp = player_node->getExperience(index + skillBegin);
- std::string sExp (toString(exp.first) + " / " + toString(exp.second));
+ mLevelLabel->setCaption(skillLevel);
+ std::pair<int, int> exp = player_node->getExperience(mInfo->id);
+ std::string sExp (toString(exp.first) + " / " + toString(exp.second));
- mSkillNameLabels.at(index)->setCaption(LocalPlayer::getSkillInfo(index + skillBegin).name);
- mSkillNameLabels.at(index)->adjustSize();
- mSkillLevelLabels.at(index)->adjustSize();
- mSkillExpLabels.at(index)->setCaption(sExp);
- mSkillExpLabels.at(index)->adjustSize();
- mSkillExpLabels.at(index)->setAlignment(gcn::Graphics::RIGHT);
+ mLevelLabel->adjustSize();
+
+ if (exp.second)
+ {
+ mProgress->setVisible(true);
+ mProgress->setText(sExp);
// More intense red as exp grows
int color = 150 - (int)(150 * ((float) exp.first / exp.second));
- mSkillProgress.at(index)->setColor(244, color, color);
- mSkillProgress.at(index)->setProgress((float) exp.first / exp.second);
+ mProgress->setColor(244, color, color);
+ mProgress->setProgress((float) exp.first / exp.second);
}
-}
-
-void SkillTab::update()
-{
- int skillNum = getSkillNum();
+ else
+ mProgress->setVisible(false);
- // Update the skill information for reach skill
- for (int a = 0; a < skillNum; a++)
+ if (mInfo->modifiable)
{
- updateSkill(a);
+ mIncrease->setVisible(true);
+ mIncrease->setEnabled(player_node->getSkillPoints());
}
+ else
+ {
+ mIncrease->setVisible(false);
+ mIncrease->setEnabled(false);
+ }
+
+ widgetResized(NULL);
}
diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h
index 56192273..ce8f091a 100644
--- a/src/gui/skilldialog.h
+++ b/src/gui/skilldialog.h
@@ -29,10 +29,14 @@
#include <guichan/actionlistener.hpp>
#include <list>
+#include <map>
-class ProgressBar;
-class Icon;
-class SkillTab;
+class Label;
+class ScrollArea;
+class Tab;
+class TabbedArea;
+
+struct SkillInfo;
/**
* The skill dialog.
@@ -52,17 +56,35 @@ class SkillDialog : public Window, public gcn::ActionListener
void action(const gcn::ActionEvent &event);
/**
- * Update the tabs in this dialog
+ * Called when the widget changes size. Used for adapting the size of
+ * the tabbed area.
*/
- void update();
+ void widgetResized(const gcn::Event &event);
+
+ void logic();
/**
- * Draw this window.
- */
- void draw(gcn::Graphics *g);
+ * Update the given skill's display
+ */
+ std::string update(int id);
+
+ /**
+ * Update other parts of the display
+ */
+ void update();
+
+ void loadSkills(const std::string &file);
+
+ void setModifiable(int id, bool modifiable);
private:
- std::list<SkillTab*> mTabs;
+ void adjustTabSize();
+
+ typedef std::map<int, SkillInfo*> SkillMap;
+ SkillMap mSkills;
+ Tab *mCurrentTab;
+ TabbedArea *mTabs;
+ Label *mPointsLabel;
};
extern SkillDialog *skillDialog;
diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp
index 959e47ee..c2703327 100644
--- a/src/gui/speechbubble.cpp
+++ b/src/gui/speechbubble.cpp
@@ -28,8 +28,6 @@
#include "graphics.h"
-#include "utils/gettext.h"
-
#include <guichan/font.hpp>
#include <guichan/widgets/label.hpp>
diff --git a/src/gui/status.cpp b/src/gui/status.cpp
deleted file mode 100644
index eca01725..00000000
--- a/src/gui/status.cpp
+++ /dev/null
@@ -1,414 +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/status.h"
-#include "gui/palette.h"
-
-#include "localplayer.h"
-#include "units.h"
-
-#include "gui/widgets/button.h"
-#include "gui/widgets/label.h"
-#include "gui/widgets/layout.h"
-#include "gui/widgets/progressbar.h"
-#include "gui/widgets/windowcontainer.h"
-
-#include "net/net.h"
-#include "net/ea/playerhandler.h"
-
-#include "utils/gettext.h"
-#include "utils/mathutils.h"
-#include "utils/stringutils.h"
-
-StatusWindow::StatusWindow(LocalPlayer *player):
- Window(player->getName()),
- mPlayer(player),
- mCurrency(0)
-{
- setWindowName("Status");
- setCloseButton(true);
- setSaveVisible(true);
- setDefaultSize(400, 345, ImageRect::CENTER);
-
- // ----------------------
- // Status Part
- // ----------------------
-
- mLvlLabel = new Label(strprintf(_("Level: %d"), 0));
- mJobLvlLabel = new Label(strprintf(_("Job: %d"), 0));
- mGpLabel = new Label(strprintf(_("Money: %s"),
- Units::formatCurrency(mCurrency).c_str()));
-
- mHpLabel = new Label(_("HP:"));
- mHpBar = new ProgressBar(0.0f, 80, 15, gcn::Color(0, 171, 34));
-
- mXpLabel = new Label(_("Exp:"));
- mXpBar = new ProgressBar(0.0f, 80, 15, gcn::Color(143, 192, 211));
-
- mMpLabel = new Label(_("MP:"));
- mMpBar = new ProgressBar(0.0f, 80, 15, gcn::Color(26, 102, 230));
-
- mJobLabel = new Label(_("Job:"));
- mJobBar = new ProgressBar(0.0f, 80, 15, gcn::Color(220, 135, 203));
-
- // ----------------------
- // Stats Part
- // ----------------------
-
- // Static Labels
- gcn::Label *mStatsTitleLabel = new Label(_("Stats"));
- gcn::Label *mStatsTotalLabel = new Label(_("Total"));
- gcn::Label *mStatsCostLabel = new Label(_("Cost"));
- mStatsTotalLabel->setAlignment(gcn::Graphics::CENTER);
-
- // Derived Stats
- mStatsAttackLabel = new Label(_("Attack:"));
- mStatsDefenseLabel= new Label(_("Defense:"));
- mStatsMagicAttackLabel = new Label(_("M.Attack:"));
- mStatsMagicDefenseLabel = new Label(_("M.Defense:"));
- // Gettext flag for next line: xgettext:no-c-format
- mStatsAccuracyLabel = new Label(_("% Accuracy:"));
- // Gettext flag for next line: xgettext:no-c-format
- mStatsEvadeLabel = new Label(_("% Evade:"));
- // Gettext flag for next line: xgettext:no-c-format
- mStatsReflexLabel = new Label(_("% Reflex:"));
-
- mStatsAttackPoints = new Label;
- mStatsDefensePoints = new Label;
- mStatsMagicAttackPoints = new Label;
- mStatsMagicDefensePoints = new Label;
- mStatsAccuracyPoints = new Label;
- mStatsEvadePoints = new Label;
- mStatsReflexPoints = new Label;
-
- // New labels
- for (int i = 0; i < 6; i++)
- {
- mStatsLabel[i] = new Label("0");
- mStatsLabel[i]->setAlignment(gcn::Graphics::CENTER);
- mStatsDisplayLabel[i] = new Label;
- mPointsLabel[i] = new Label("0");
- mPointsLabel[i]->setAlignment(gcn::Graphics::CENTER);
- }
- mRemainingStatsPointsLabel = new Label;
-
- // Set button events Id
- mStatsButton[0] = new Button("+", "STR", this);
- mStatsButton[1] = new Button("+", "AGI", this);
- mStatsButton[2] = new Button("+", "VIT", this);
- mStatsButton[3] = new Button("+", "INT", this);
- mStatsButton[4] = new Button("+", "DEX", this);
- mStatsButton[5] = new Button("+", "LUK", this);
-
- // Assemble
- ContainerPlacer place;
- place = getPlacer(0, 0);
-
- place(0, 0, mLvlLabel, 3);
- place(5, 0, mJobLvlLabel, 3);
- place(8, 0, mGpLabel, 3);
- place(0, 1, mHpLabel).setPadding(3);
- place(1, 1, mHpBar, 4);
- place(5, 1, mXpLabel).setPadding(3);
- place(6, 1, mXpBar, 5);
- place(0, 2, mMpLabel).setPadding(3);
- place(1, 2, mMpBar, 4);
- place(5, 2, mJobLabel).setPadding(3);
- place(6, 2, mJobBar, 5);
- place.getCell().matchColWidth(0, 1);
- place = getPlacer(0, 3);
- place(0, 1, mStatsTitleLabel, 5);
- place(5, 1, mStatsTotalLabel, 5);
- place(12, 1, mStatsCostLabel, 5);
- for (int i = 0; i < 6; i++)
- {
- place(0, 2 + i, mStatsLabel[i], 7).setPadding(5);
- place(7, 2 + i, mStatsDisplayLabel[i]).setPadding(5);
- place(10, 2 + i, mStatsButton[i]);
- place(12, 2 + i, mPointsLabel[i]).setPadding(5);
- }
- place(14, 2, mStatsAttackLabel, 7).setPadding(5);
- place(14, 3, mStatsDefenseLabel, 7).setPadding(5);
- place(14, 4, mStatsMagicAttackLabel, 7).setPadding(5);
- place(14, 5, mStatsMagicDefenseLabel, 7).setPadding(5);
- place(14, 6, mStatsAccuracyLabel, 7).setPadding(5);
- place(14, 7, mStatsEvadeLabel, 7).setPadding(5);
- place(14, 8, mStatsReflexLabel, 7).setPadding(5);
- place(21, 2, mStatsAttackPoints, 3).setPadding(5);
- place(21, 3, mStatsDefensePoints, 3).setPadding(5);
- place(21, 4, mStatsMagicAttackPoints, 3).setPadding(5);
- place(21, 5, mStatsMagicDefensePoints, 3).setPadding(5);
- place(21, 6, mStatsAccuracyPoints, 3).setPadding(5);
- place(21, 7, mStatsEvadePoints, 3).setPadding(5);
- place(21, 8, mStatsReflexPoints, 3).setPadding(5);
- place(0, 8, mRemainingStatsPointsLabel, 3).setPadding(5);
-
- Layout &layout = getLayout();
- layout.setRowHeight(0, Layout::AUTO_SET);
-
- loadWindowState();
-}
-
-void StatusWindow::update()
-{
- // Status Part
- // -----------
- mLvlLabel->setCaption(strprintf(_("Level: %d"), mPlayer->getLevel()));
- mLvlLabel->adjustSize();
-
- mJobLvlLabel->setCaption(strprintf(_("Job: %d"), mPlayer->mJobLevel));
- mJobLvlLabel->adjustSize();
-
- if (mCurrency != mPlayer->getMoney()) {
- mCurrency = mPlayer->getMoney();
- mGpLabel->setCaption(strprintf(_("Money: %s"),
- Units::formatCurrency(mCurrency).c_str()));
- mGpLabel->adjustSize();
- }
-
- updateHPBar(mHpBar, true);
-
- updateMPBar(mMpBar, true);
-
- updateXPBar(mXpBar, false);
-
- updateJobBar(mJobBar, false);
-
- // Stats Part
- // ----------
- static const char *attrNames[6] = {
- N_("Strength"),
- N_("Agility"),
- N_("Vitality"),
- N_("Intelligence"),
- N_("Dexterity"),
- N_("Luck")
- };
- int statusPoints = mPlayer->mStatsPointsToAttribute;
-
- // Update labels
- for (int i = 0; i < 6; i++)
- {
- mStatsLabel[i]->setCaption(gettext(attrNames[i]));
- mStatsDisplayLabel[i]->setCaption(toString((int) mPlayer->mAttr[i]));
- mPointsLabel[i]->setCaption(toString((int) mPlayer->mAttrUp[i]));
-
- mStatsLabel[i]->adjustSize();
- mStatsDisplayLabel[i]->adjustSize();
- mPointsLabel[i]->adjustSize();
-
- mStatsButton[i]->setEnabled(mPlayer->mAttrUp[i] <= statusPoints);
- }
- mRemainingStatsPointsLabel->setCaption(
- strprintf(_("Remaining Status Points: %d"), statusPoints));
- mRemainingStatsPointsLabel->adjustSize();
-
- // Derived Stats Points
-
- // Attack TODO: Count equipped Weapons and items attack bonuses
- mStatsAttackPoints->setCaption(
- toString(mPlayer->ATK + mPlayer->ATK_BONUS));
- mStatsAttackPoints->adjustSize();
-
- // Defense TODO: Count equipped Armors and items defense bonuses
- mStatsDefensePoints->setCaption(
- toString(mPlayer->DEF + mPlayer->DEF_BONUS));
- mStatsDefensePoints->adjustSize();
-
- // Magic Attack TODO: Count equipped items M.Attack bonuses
- mStatsMagicAttackPoints->setCaption(
- toString(mPlayer->MATK + mPlayer->MATK_BONUS));
- mStatsMagicAttackPoints->adjustSize();
-
- // Magic Defense TODO: Count equipped items M.Defense bonuses
- mStatsMagicDefensePoints->setCaption(
- toString(mPlayer->MDEF + mPlayer->MDEF_BONUS));
- mStatsMagicDefensePoints->adjustSize();
-
- // Accuracy %
- mStatsAccuracyPoints->setCaption(toString(mPlayer->HIT));
- mStatsAccuracyPoints->adjustSize();
-
- // Evasion %
- mStatsEvadePoints->setCaption(toString(mPlayer->FLEE));
- mStatsEvadePoints->adjustSize();
-
- // Reflex %
- mStatsReflexPoints->setCaption(toString(mPlayer->DEX / 4)); // + counter
- mStatsReflexPoints->adjustSize();
-}
-
-void StatusWindow::draw(gcn::Graphics *g)
-{
- update();
-
- Window::draw(g);
-}
-
-void StatusWindow::action(const gcn::ActionEvent &event)
-{
- // Stats Part
- // Net::getPlayerHandler()->increaseStat(?);
- if (event.getId().length() == 3)
- {
- if (event.getId() == "STR")
- Net::getPlayerHandler()->increaseStat(LocalPlayer::STR);
- if (event.getId() == "AGI")
- Net::getPlayerHandler()->increaseStat(LocalPlayer::AGI);
- if (event.getId() == "VIT")
- Net::getPlayerHandler()->increaseStat(LocalPlayer::VIT);
- if (event.getId() == "INT")
- Net::getPlayerHandler()->increaseStat(LocalPlayer::INT);
- if (event.getId() == "DEX")
- Net::getPlayerHandler()->increaseStat(LocalPlayer::DEX);
- if (event.getId() == "LUK")
- Net::getPlayerHandler()->increaseStat(LocalPlayer::LUK);
- }
-}
-
-void StatusWindow::updateHPBar(ProgressBar *bar, bool showMax)
-{
- if (showMax)
- bar->setText(toString(player_node->getHp()) +
- "/" + toString(player_node->getMaxHp()));
- else
- bar->setText(toString(player_node->getHp()));
-
- // HP Bar coloration
- float r1 = 255;
- float g1 = 255;
- float b1 = 255;
-
- float r2 = 255;
- float g2 = 255;
- float b2 = 255;
-
- float weight = 1.0f;
-
- int curHP = player_node->getHp();
- int thresholdLevel = player_node->getMaxHp() / 4;
- int thresholdProgress = curHP % thresholdLevel;
- weight = 1-((float)thresholdProgress) / ((float)thresholdLevel);
-
- if (curHP < (thresholdLevel))
- {
- gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_ONE_HALF);
- gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_ONE_QUARTER);
- r1 = color1.r; r2 = color2.r;
- g1 = color1.g; g2 = color2.g;
- b1 = color1.b; b2 = color2.b;
- }
- else if (curHP < (thresholdLevel*2))
- {
- gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_THREE_QUARTERS);
- gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_ONE_HALF);
- r1 = color1.r; r2 = color2.r;
- g1 = color1.g; g2 = color2.g;
- b1 = color1.b; b2 = color2.b;
- }
- else if (curHP < thresholdLevel*3)
- {
- gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_FULL);
- gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_THREE_QUARTERS);
- r1 = color1.r; r2 = color2.r;
- g1 = color1.g; g2 = color2.g;
- b1 = color1.b; b2 = color2.b;
- }
- else
- {
- gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_FULL);
- gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_FULL);
- r1 = color1.r; r2 = color2.r;
- g1 = color1.g; g2 = color2.g;
- b1 = color1.b; b2 = color2.b;
- }
-
- // Safety checks
- if (weight > 1.0f) weight = 1.0f;
- if (weight < 0.0f) weight = 0.0f;
-
- // Do the color blend
- r1 = (int) weightedAverage(r1, r2,weight);
- g1 = (int) weightedAverage(g1, g2, weight);
- b1 = (int) weightedAverage(b1, b2, weight);
-
- // More safety checks
- if (r1 > 255) r1 = 255;
- if (g1 > 255) g1 = 255;
- if (b1 > 255) b1 = 255;
-
- bar->setColor(r1, g1, b1);
-
- bar->setProgress((float) player_node->getHp() / (float) player_node->getMaxHp());
-}
-
-void StatusWindow::updateMPBar(ProgressBar *bar, bool showMax)
-{
- if (showMax)
- bar->setText(toString(player_node->mMp) +
- "/" + toString(player_node->mMaxMp));
- else
- bar->setText(toString(player_node->mMp));
-
- if (player_node->MATK <= 0)
- bar->setColor(100, 100, 100); // grey, to indicate that we lack magic
- else
- bar->setColor(26, 102, 230); // blue, to indicate that we have magic
-
- bar->setProgress((float) player_node->mMp / (float) player_node->mMaxMp);
-}
-
-static void updateProgressBar(ProgressBar *bar, int value, int max,
- bool percent)
-{
- if (max == 0)
- {
- bar->setText(_("Max level"));
- bar->setProgress(1.0);
- }
- else
- {
- float progress = (float) value / max;
-
- if (percent)
- bar->setText(strprintf("%2.2f", 100 * progress) + "%");
- else
- bar->setText(toString(value) + "/" + toString(max));
-
- bar->setProgress(progress);
- }
-}
-
-void StatusWindow::updateXPBar(ProgressBar *bar, bool percent)
-{
- updateProgressBar(bar,
- player_node->getXp(),
- player_node->mXpForNextLevel,
- percent);
-}
-
-void StatusWindow::updateJobBar(ProgressBar *bar, bool percent)
-{
- updateProgressBar(bar,
- player_node->mJobXp,
- player_node->mJobXpForNextLevel,
- percent);
-}
diff --git a/src/gui/status.h b/src/gui/status.h
deleted file mode 100644
index 403a7d59..00000000
--- a/src/gui/status.h
+++ /dev/null
@@ -1,107 +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 STATUS_H
-#define STATUS_H
-
-#include "gui/widgets/window.h"
-
-#include <guichan/actionlistener.hpp>
-
-class LocalPlayer;
-class ProgressBar;
-
-/**
- * The player status dialog.
- *
- * \ingroup Interface
- */
-class StatusWindow : public Window, public gcn::ActionListener
-{
- public:
- /**
- * Constructor.
- */
- StatusWindow(LocalPlayer *player);
-
- /**
- * Called when receiving actions from widget.
- */
- void action(const gcn::ActionEvent &event);
-
- /**
- * Draw this window
- */
- void draw(gcn::Graphics *graphics);
-
- /**
- * Updates this dialog with values from PLAYER_INFO *char_info
- */
- void update();
-
- static void updateHPBar(ProgressBar *bar, bool showMax = false);
- static void updateMPBar(ProgressBar *bar, bool showMax = false);
- static void updateXPBar(ProgressBar *bar, bool percent = true);
- static void updateJobBar(ProgressBar *bar, bool percent = true);
-
- private:
- LocalPlayer *mPlayer;
-
- /**
- * Status Part
- */
- gcn::Label *mLvlLabel, *mJobLvlLabel;
- gcn::Label *mGpLabel;
- int mCurrency;
- gcn::Label *mHpLabel, *mMpLabel, *mXpLabel, *mJobLabel;
- ProgressBar *mHpBar, *mMpBar;
- ProgressBar *mXpBar, *mJobBar;
-
- /**
- * Derived Statistics captions
- */
- gcn::Label *mStatsAttackLabel, *mStatsDefenseLabel;
- gcn::Label *mStatsMagicAttackLabel, *mStatsMagicDefenseLabel;
- gcn::Label *mStatsAccuracyLabel, *mStatsEvadeLabel;
- gcn::Label *mStatsReflexLabel;
-
- gcn::Label *mStatsAttackPoints, *mStatsDefensePoints;
- gcn::Label *mStatsMagicAttackPoints, *mStatsMagicDefensePoints;
- gcn::Label *mStatsAccuracyPoints, *mStatsEvadePoints;
- gcn::Label *mStatsReflexPoints;
-
- /**
- * Stats captions.
- */
- gcn::Label *mStatsLabel[6];
- gcn::Label *mPointsLabel[6];
- gcn::Label *mStatsDisplayLabel[6];
- gcn::Label *mRemainingStatsPointsLabel;
-
- /**
- * Stats buttons.
- */
- gcn::Button *mStatsButton[6];
-};
-
-extern StatusWindow *statusWindow;
-
-#endif
diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp
index edbf387b..6f5f72fa 100644
--- a/src/gui/statuswindow.cpp
+++ b/src/gui/statuswindow.cpp
@@ -23,353 +23,494 @@
#include "gui/widgets/button.h"
#include "gui/widgets/label.h"
+#include "gui/widgets/layouthelper.h"
#include "gui/widgets/progressbar.h"
+#include "gui/widgets/scrollarea.h"
+#include "gui/widgets/vertcontainer.h"
#include "gui/widgets/windowcontainer.h"
+#include "gui/ministatus.h"
+#include "gui/setup.h"
+
#include "localplayer.h"
+#include "units.h"
+
+#include "net/net.h"
+#include "net/playerhandler.h"
+
+#ifdef EATHENA_SUPPORT
+#include "net/ea/protocol.h"
+#endif
+#include "utils/gettext.h"
+#include "utils/mathutils.h"
#include "utils/stringutils.h"
-StatusWindow::StatusWindow(LocalPlayer *player):
- Window(player->getName()),
- mPlayer(player)
+class AttrDisplay : public Container
+{
+ public:
+ virtual std::string update();
+
+ protected:
+ AttrDisplay(int id, const std::string &name);
+
+ const int mId;
+ const std::string mName;
+
+ LayoutHelper *mLayout;
+ Label *mLabel;
+ Label *mValue;
+};
+
+class DerDisplay : public AttrDisplay
+{
+ public:
+ DerDisplay(int id, const std::string &name);
+};
+
+class ChangeDisplay : public AttrDisplay, gcn::ActionListener
+{
+ public:
+ ChangeDisplay(int id, const std::string &name);
+ std::string update();
+ void setPointsNeeded(int needed);
+
+ private:
+ void action(const gcn::ActionEvent &event);
+
+ int mNeeded;
+
+ Label *mPoints;
+ Button *mDec;
+ Button *mInc;
+};
+
+StatusWindow::StatusWindow():
+ Window(player_node->getName())
{
setWindowName("Status");
+ setupWindow->registerWindowForReset(this);
setResizable(true);
setCloseButton(true);
setSaveVisible(true);
setDefaultSize((windowContainer->getWidth() - 365) / 2,
(windowContainer->getHeight() - 255) / 2, 365, 275);
- loadWindowState();
// ----------------------
// Status Part
// ----------------------
- mLvlLabel = new Label("Level:");
- mMoneyLabel = new Label("Money:");
-
- mHpLabel = new Label("HP:");
- mHpBar = new ProgressBar(0.0f, 80, 15, gcn::Color(0, 171, 34));
- mHpValueLabel = new Label;
-
- int y = 3;
- int x = 5;
-
- mLvlLabel->setPosition(x, y);
- x += mLvlLabel->getWidth() + 40;
- mMoneyLabel->setPosition(x, y);
-
- y += mLvlLabel->getHeight() + 5; // Next Row
- x = 5;
-
- mHpLabel->setPosition(x, y);
- x += mHpLabel->getWidth() + 5;
- mHpBar->setPosition(x, y);
- x += mHpBar->getWidth() + 5;
- mHpValueLabel->setPosition(x, y);
-
- y += mHpLabel->getHeight() + 5; // Next Row
- x = 5;
-
- add(mLvlLabel);
- add(mMoneyLabel);
- add(mHpLabel);
- add(mHpValueLabel);
- add(mHpBar);
+ mLvlLabel = new Label(strprintf(_("Level: %d"), 0));
+ mMoneyLabel = new Label(strprintf(_("Money: %s"), ""));
+
+ mHpLabel = new Label(_("HP:"));
+ mHpBar = new ProgressBar((float) player_node->getHp()
+ / (float) player_node->getMaxHp(),
+ 80, 15, gcn::Color(0, 171, 34));
+
+ mXpLabel = new Label(_("Exp:"));
+ mXpBar = new ProgressBar((float) player_node->getExp()
+ / player_node->getExpNeeded(),
+ 80, 15, gcn::Color(143, 192, 211));
+
+ mMpLabel = new Label(_("MP:"));
+ mMpBar = new ProgressBar((float) player_node->getMaxMP()
+ / (float) player_node->getMaxMP(),
+ 80, 15, gcn::Color(26, 102, 230));
+
+ place(0, 0, mLvlLabel, 3);
+ // 5, 0 Job Level
+ place(8, 0, mMoneyLabel, 3);
+ place(0, 1, mHpLabel).setPadding(3);
+ place(1, 1, mHpBar, 4);
+ place(5, 1, mXpLabel).setPadding(3);
+ place(6, 1, mXpBar, 5);
+ place(0, 2, mMpLabel).setPadding(3);
+ // 5, 2 and 6, 2 Job Progress Bar
+ place(1, 2, mMpBar, 4);
+
+#ifdef EATHENA_SUPPORT
+ mJobLvlLabel = new Label(strprintf(_("Job: %d"), 0));
+ mJobLabel = new Label(_("Job:"));
+ mJobBar = new ProgressBar(0.0f, 80, 15, gcn::Color(220, 135, 203));
+
+ place(5, 0, mJobLvlLabel, 3);
+ place(5, 2, mJobLabel).setPadding(3);
+ place(6, 2, mJobBar, 5);
+#endif
// ----------------------
// Stats Part
// ----------------------
- // Static Labels
- gcn::Label *mStatsTitleLabel = new Label("Stats");
- gcn::Label *mStatsTotalLabel = new Label("Total");
-
- // Derived Stats
-/*
- mStatsAttackLabel = new Label("Attack:");
- mStatsDefenseLabel= new Label("Defense:");
- mStatsMagicAttackLabel = new Label("M.Attack:");
- mStatsMagicDefenseLabel = new Label("M.Defense:");
- mStatsAccuracyLabel = new Label("% Accuracy:");
- mStatsEvadeLabel = new Label("% Evade:");
- mStatsReflexLabel = new Label("% Reflex:");
-
- mStatsAttackPoints = new Label;
- mStatsDefensePoints = new Label;
- mStatsMagicAttackPoints = new Label;
- mStatsMagicDefensePoints = new Label;
- mStatsAccuracyPoints = new Label("% Accuracy:");
- mStatsEvadePoints = new Label("% Evade:");
- mStatsReflexPoints = new Label("% Reflex:");
-*/
- // New labels
- for (int i = 0; i < 6; i++) {
- mStatsLabel[i] = new Label;
- mStatsDisplayLabel[i] = new Label;
- }
- mCharacterPointsLabel = new Label;
- mCorrectionPointsLabel = new Label;
-
- // Set button events Id
- mStatsPlus[0] = new Button("+", "STR+", this);
- mStatsPlus[1] = new Button("+", "AGI+", this);
- mStatsPlus[2] = new Button("+", "DEX+", this);
- mStatsPlus[3] = new Button("+", "VIT+", this);
- mStatsPlus[4] = new Button("+", "INT+", this);
- mStatsPlus[5] = new Button("+", "WIL+", this);
+ mAttrCont = new VertContainer(32);
+ mAttrScroll = new ScrollArea(mAttrCont);
+ mAttrScroll->setOpaque(false);
+ mAttrScroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
+ mAttrScroll->setVerticalScrollPolicy(ScrollArea::SHOW_AUTO);
+ place(0, 3, mAttrScroll, 5, 3);
- mStatsMinus[0] = new Button("-", "STR-", this);
- mStatsMinus[1] = new Button("-", "AGI-", this);
- mStatsMinus[2] = new Button("-", "DEX-", this);
- mStatsMinus[3] = new Button("-", "VIT-", this);
- mStatsMinus[4] = new Button("-", "INT-", this);
- mStatsMinus[5] = new Button("-", "WIL-", this);
+ mDAttrCont = new VertContainer(32);
+ mDAttrScroll = new ScrollArea(mDAttrCont);
+ mDAttrScroll->setOpaque(false);
+ mDAttrScroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
+ mDAttrScroll->setVerticalScrollPolicy(ScrollArea::SHOW_AUTO);
+ place(6, 3, mDAttrScroll, 5, 3);
+ getLayout().setRowHeight(3, Layout::AUTO_SET);
+ mCharacterPointsLabel = new Label("C");
+ mCorrectionPointsLabel = new Label("C");
+ place(0, 6, mCharacterPointsLabel, 5);
+ place(0, 7, mCorrectionPointsLabel, 5);
- // Set position
- mStatsTitleLabel->setPosition(mHpLabel->getX(), mHpLabel->getY() + 23 );
- mStatsTotalLabel->setPosition(110, mStatsTitleLabel->getY() + 15);
- int totalLabelY = mStatsTotalLabel->getY();
-
- for (int i = 0; i < 6; i++)
- {
- mStatsLabel[i]->setPosition(5,
- mStatsTotalLabel->getY() + (i * 23) + 15);
- mStatsMinus[i]->setPosition(85, totalLabelY + (i * 23) + 15);
- mStatsDisplayLabel[i]->setPosition(125,
- totalLabelY + (i * 23) + 15);
- mStatsPlus[i]->setPosition(185, totalLabelY + (i * 23) + 15);
- }
+ loadWindowState();
- mCharacterPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 25);
- mCorrectionPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 35);
-/*
- mStatsAttackLabel->setPosition(220, mStatsLabel[0]->getY());
- mStatsDefenseLabel->setPosition(220, mStatsLabel[1]->getY());
- mStatsMagicAttackLabel->setPosition(220, mStatsLabel[2]->getY());
- mStatsMagicDefenseLabel->setPosition(220, mStatsLabel[3]->getY());
- mStatsAccuracyLabel->setPosition(220, mStatsLabel[4]->getY());
- mStatsEvadeLabel->setPosition(220, mStatsLabel[5]->getY());
- mStatsReflexLabel->setPosition(220, mStatsLabel[6]->getY());
-
- mStatsAttackPoints->setPosition(310, mStatsLabel[0]->getY());
- mStatsDefensePoints->setPosition(310, mStatsLabel[1]->getY());
- mStatsMagicAttackPoints->setPosition(310, mStatsLabel[2]->getY());
- mStatsMagicDefensePoints->setPosition(310, mStatsLabel[3]->getY());
- mStatsAccuracyPoints->setPosition(310, mStatsLabel[4]->getY());
- mStatsEvadePoints->setPosition(310, mStatsLabel[5]->getY());
- mStatsReflexPoints->setPosition(310, mStatsLabel[6]->getY());
-*/
- // Assemble
- add(mStatsTitleLabel);
- add(mStatsTotalLabel);
- for(int i = 0; i < 6; i++)
- {
- add(mStatsLabel[i]);
- add(mStatsDisplayLabel[i]);
- add(mStatsPlus[i]);
- add(mStatsMinus[i]);
- }/*
- add(mStatsAttackLabel);
- add(mStatsDefenseLabel);
- add(mStatsMagicAttackLabel);
- add(mStatsMagicDefenseLabel);
- add(mStatsAccuracyLabel);
- add(mStatsEvadeLabel);
- add(mStatsReflexLabel);
-
- add(mStatsAttackPoints);
- add(mStatsDefensePoints);
- add(mStatsMagicAttackPoints);
- add(mStatsMagicDefensePoints);
- add(mStatsAccuracyPoints);
- add(mStatsEvadePoints);
- add(mStatsReflexPoints);*/
-
- add(mCharacterPointsLabel);
- add(mCorrectionPointsLabel);
+ update(HP);
+ update(MP);
+ update(EXP);
+ update(MONEY);
+ update(CHAR_POINTS); // This also updates all attributes (none atm)
+ update(LEVEL);
+#ifdef EATHENA_SUPPORT
+ update(JOB);
+#endif
}
-void StatusWindow::update()
+std::string StatusWindow::update(int id)
{
- // Status Part
- // -----------
- mLvlLabel->setCaption( "Level: " +
- toString(mPlayer->getLevel()) +
- " (" +
- toString(mPlayer->getLevelProgress()) +
- "%)");
- mLvlLabel->adjustSize();
-
- mMoneyLabel->setCaption("Money: " + toString(mPlayer->getMoney()) + " GP");
- mMoneyLabel->adjustSize();
+ if (miniStatusWindow)
+ miniStatusWindow->update(id);
- updateHPBar(mHpBar, true);
-
- // Stats Part
- // ----------
- const std::string attrNames[6] = {
- "Strength",
- "Agility",
- "Dexterity",
- "Vitality",
- "Intelligence",
- "Willpower"
- };
- int characterPoints = mPlayer->getCharacterPoints();
- int correctionPoints = mPlayer->getCorrectionPoints();
- // Update labels
- for (int i = 0; i < 6; i++)
+ if (id == HP)
{
- mStatsLabel[i]->setCaption(attrNames[i]);
- mStatsDisplayLabel[i]->setCaption(
- strprintf("%d / %d",
- mPlayer->getAttributeEffective(CHAR_ATTR_BEGIN + i),
- mPlayer->getAttributeBase(CHAR_ATTR_BEGIN + i)));
-
- mStatsLabel[i]->adjustSize();
- mStatsDisplayLabel[i]->adjustSize();
+ updateHPBar(mHpBar, true);
- mStatsPlus[i]->setEnabled(characterPoints);
- mStatsMinus[i]->setEnabled(correctionPoints);
+ return _("HP");
}
- mCharacterPointsLabel->setCaption("Character Points: " +
- toString(characterPoints));
- mCharacterPointsLabel->adjustSize();
-
- mCorrectionPointsLabel->setCaption("Correction Points: " +
- toString(correctionPoints));
- mCorrectionPointsLabel->adjustSize();
-/*
- // Derived Stats Points
-
- // Attack TODO: Count equipped Weapons and items attack bonuses
- mStatsAttackPoints->setCaption(
- toString(mPlayer->ATK + mPlayer->ATK_BONUS));
- mStatsAttackPoints->adjustSize();
-
- // Defense TODO: Count equipped Armors and items defense bonuses
- mStatsDefensePoints->setCaption(
- toString(mPlayer->DEF + mPlayer->DEF_BONUS));
- mStatsDefensePoints->adjustSize();
-
- // Magic Attack TODO: Count equipped items M.Attack bonuses
- mStatsMagicAttackPoints->setCaption(
- toString(mPlayer->MATK + mPlayer->MATK_BONUS));
- mStatsMagicAttackPoints->adjustSize();
-
- // Magic Defense TODO: Count equipped items M.Defense bonuses
- mStatsMagicDefensePoints->setCaption(
- toString(mPlayer->MDEF + mPlayer->MDEF_BONUS));
- mStatsMagicDefensePoints->adjustSize();
-
- // Accuracy %
- mStatsAccuracyPoints->setCaption(toString(mPlayer->HIT));
- mStatsAccuracyPoints->adjustSize();
-
- // Evasion %
- mStatsEvadePoints->setCaption(toString(mPlayer->FLEE));
- mStatsEvadePoints->adjustSize();
-
- // Reflex %
- mStatsReflexPoints->setCaption(toString(mPlayer->DEX / 4)); // + counter
- mStatsReflexPoints->adjustSize();
-*/
- // Update Second column widgets position
- mMoneyLabel->setPosition(mLvlLabel->getX() + mLvlLabel->getWidth() + 20,
- mLvlLabel->getY());
-
-}
-
-void StatusWindow::draw(gcn::Graphics *g)
-{
- update();
-
- Window::draw(g);
-}
-
-void StatusWindow::action(const gcn::ActionEvent &event)
-{
- const std::string &eventId = event.getId();
-
- // Stats Part
- if (eventId == "STR+")
+ else if (id == MP)
{
- mPlayer->raiseAttribute(LocalPlayer::STR);
+ updateMPBar(mMpBar, true);
+
+ return _("MP");
}
- else if (eventId == "AGI+")
+ else if (id == EXP)
{
- mPlayer->raiseAttribute(LocalPlayer::AGI);
+ updateXPBar(mXpBar, false);
+
+ return _("Exp");
}
- else if (eventId == "DEX+")
+ else if (id == MONEY)
{
- mPlayer->raiseAttribute(LocalPlayer::DEX);
+ int money = player_node->getMoney();
+ mMoneyLabel->setCaption(strprintf(_("Money: %s"),
+ Units::formatCurrency(money).c_str()));
+ mMoneyLabel->adjustSize();
+
+ return _("Money");
}
- else if (eventId == "VIT+")
+#ifdef EATHENA_SUPPORT
+ else if (id == JOB)
{
- mPlayer->raiseAttribute(LocalPlayer::VIT);
+ mJobLvlLabel->setCaption(strprintf(_("Job: %d"),
+ player_node->getAttributeBase(JOB)));
+ mJobLvlLabel->adjustSize();
+
+ updateProgressBar(mJobBar, JOB, false);
+
+ return _("Job");
}
- else if (eventId == "INT+")
+#endif
+ else if (id == CHAR_POINTS)
{
- mPlayer->raiseAttribute(LocalPlayer::INT);
+ mCharacterPointsLabel->setCaption(strprintf(_("Character points: %d"),
+ player_node->getCharacterPoints()));
+ mCharacterPointsLabel->adjustSize();
+
+ mCorrectionPointsLabel->setCaption(strprintf(_("Correction points: %d"),
+ player_node->getCorrectionPoints()));
+ mCorrectionPointsLabel->adjustSize();
+
+ for (Attrs::iterator it = mAttrs.begin(); it != mAttrs.end(); it++)
+ {
+ it->second->update();
+ }
}
- else if (eventId == "WIL+")
+ else if (id == LEVEL)
{
- mPlayer->raiseAttribute(LocalPlayer::WIL);
- }
+ mLvlLabel->setCaption(strprintf(_("Level: %d"),
+ player_node->getLevel()));
+ mLvlLabel->adjustSize();
- else if (eventId == "STR-")
- {
- mPlayer->lowerAttribute(LocalPlayer::STR);
- }
- else if (eventId == "AGI-")
- {
- mPlayer->lowerAttribute(LocalPlayer::AGI);
+ return _("Level");
}
- else if (eventId == "DEX-")
+ else
{
- mPlayer->lowerAttribute(LocalPlayer::DEX);
+ Attrs::iterator it = mAttrs.find(id);
+
+ if (it != mAttrs.end())
+ {
+ return it->second->update();
+ }
}
- else if (eventId == "VIT-")
+
+ return "";
+}
+
+void StatusWindow::setPointsNeeded(int id, int needed)
+{
+ Attrs::iterator it = mAttrs.find(id);
+
+ if (it != mAttrs.end())
{
- mPlayer->lowerAttribute(LocalPlayer::VIT);
+ ChangeDisplay *disp = dynamic_cast<ChangeDisplay*>(it->second);
+ if (disp)
+ disp->setPointsNeeded(needed);
}
- else if (eventId == "INT-")
+}
+
+void StatusWindow::addAttribute(int id, const std::string &name,
+ bool modifiable)
+{
+ AttrDisplay *disp;
+
+ if (modifiable)
{
- mPlayer->lowerAttribute(LocalPlayer::INT);
+ disp = new ChangeDisplay(id, name);
+ mAttrCont->add(disp);
}
- else if (eventId == "WIL-")
+ else
{
- mPlayer->lowerAttribute(LocalPlayer::WIL);
+ disp = new DerDisplay(id, name);
+ mDAttrCont->add(disp);
}
-}
-// WARNING: Duplicated method!
+ mAttrs[id] = disp;
+}
void StatusWindow::updateHPBar(ProgressBar *bar, bool showMax)
{
+
if (showMax)
bar->setText(toString(player_node->getHp()) +
"/" + toString(player_node->getMaxHp()));
else
bar->setText(toString(player_node->getHp()));
- // HP Bar coloration
- if (player_node->getHp() < player_node->getMaxHp() / 3)
+ if (player_node->getMaxHp() < 4)
{
- bar->setColor(223, 32, 32); // Red
+ bar->setColor(guiPalette->getColor(Palette::HPBAR_ONE_QUARTER));
}
- else if (player_node->getHp() < (player_node->getMaxHp() / 3) * 2)
+ else
{
- bar->setColor(230, 171, 34); // Orange
+ // HP Bar coloration
+ float r1 = 255;
+ float g1 = 255;
+ float b1 = 255;
+
+ float r2 = 255;
+ float g2 = 255;
+ float b2 = 255;
+
+ float weight = 1.0f;
+
+ int curHP = player_node->getHp();
+ int thresholdLevel = player_node->getMaxHp() / 4;
+ int thresholdProgress = curHP % thresholdLevel;
+
+ if (thresholdLevel)
+ weight = 1 - ((float)thresholdProgress) / ((float)thresholdLevel);
+ else
+ weight = 0;
+
+ if (curHP < (thresholdLevel))
+ {
+ gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_ONE_HALF);
+ gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_ONE_QUARTER);
+ r1 = color1.r; r2 = color2.r;
+ g1 = color1.g; g2 = color2.g;
+ b1 = color1.b; b2 = color2.b;
+ }
+ else if (curHP < (thresholdLevel*2))
+ {
+ gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_THREE_QUARTERS);
+ gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_ONE_HALF);
+ r1 = color1.r; r2 = color2.r;
+ g1 = color1.g; g2 = color2.g;
+ b1 = color1.b; b2 = color2.b;
+ }
+ else if (curHP < thresholdLevel*3)
+ {
+ gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_FULL);
+ gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_THREE_QUARTERS);
+ r1 = color1.r; r2 = color2.r;
+ g1 = color1.g; g2 = color2.g;
+ b1 = color1.b; b2 = color2.b;
+ }
+ else
+ {
+ gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_FULL);
+ gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_FULL);
+ r1 = color1.r; r2 = color2.r;
+ g1 = color1.g; g2 = color2.g;
+ b1 = color1.b; b2 = color2.b;
+ }
+
+ // Safety checks
+ if (weight > 1.0f) weight = 1.0f;
+ if (weight < 0.0f) weight = 0.0f;
+
+ // Do the color blend
+ r1 = (int) weightedAverage(r1, r2,weight);
+ g1 = (int) weightedAverage(g1, g2, weight);
+ b1 = (int) weightedAverage(b1, b2, weight);
+
+ // More safety checks
+ if (r1 > 255) r1 = 255;
+ if (g1 > 255) g1 = 255;
+ if (b1 > 255) b1 = 255;
+
+ bar->setColor(r1, g1, b1);
}
+
+ bar->setProgress((float) player_node->getHp() / (float) player_node->getMaxHp());
+
+}
+
+void StatusWindow::updateMPBar(ProgressBar *bar, bool showMax)
+{
+ if (showMax)
+ bar->setText(toString(player_node->getMP()) +
+ "/" + toString(player_node->getMaxMP()));
else
+ bar->setText(toString(player_node->getMP()));
+
+ if (Net::getPlayerHandler()->canUseMagic())
+ bar->setColor(26, 102, 230); // blue, to indicate that we have magic
+ else
+ bar->setColor(100, 100, 100); // grey, to indicate that we lack magic
+
+ bar->setProgress((float) player_node->getMP() /
+ (float) player_node->getMaxMP());
+}
+
+void StatusWindow::updateProgressBar(ProgressBar *bar, int value, int max,
+ bool percent)
+{
+ if (max == 0)
{
- bar->setColor(0, 171, 34); // Green
+ bar->setText(_("Max"));
+ bar->setProgress(1.0);
}
+ else
+ {
+ float progress = (float) value / max;
- bar->setProgress((float) player_node->getHp() / (float) player_node->getMaxHp());
+ if (percent)
+ bar->setText(strprintf("%2.2f", 100 * progress) + "%");
+ else
+ bar->setText(toString(value) + "/" + toString(max));
+
+ bar->setProgress(progress);
+ }
+}
+
+void StatusWindow::updateXPBar(ProgressBar *bar, bool percent)
+{
+ updateProgressBar(bar, player_node->getExp(), player_node->getExpNeeded(),
+ percent);
+}
+
+void StatusWindow::updateProgressBar(ProgressBar *bar, int id, bool percent)
+{
+ std::pair<int, int> exp = player_node->getExperience(id);
+ updateProgressBar(bar, exp.first, exp.second, percent);
+}
+
+AttrDisplay::AttrDisplay(int id, const std::string &name):
+ mId(id),
+ mName(name)
+{
+ setSize(100, 32);
+ mLabel = new Label(name);
+ mValue = new Label("1");
+
+ mLabel->setAlignment(Graphics::CENTER);
+ mValue->setAlignment(Graphics::CENTER);
+
+ mLayout = new LayoutHelper(this);
+}
+
+std::string AttrDisplay::update()
+{
+ int base = player_node->getAttributeBase(mId);
+ int bonus = player_node->getAttributeEffective(mId) - base;
+ std::string value = toString(base);
+ if (bonus)
+ value += strprintf(" (%+d)", bonus);
+ mValue->setCaption(value);
+
+ return mName;
+}
+
+DerDisplay::DerDisplay(int id, const std::string &name):
+ AttrDisplay(id, name)
+{
+ // Do the layout
+ LayoutHelper h(this);
+ ContainerPlacer place = mLayout->getPlacer(0, 0);
+
+ place(0, 0, mLabel, 3);
+ place(3, 0, mValue, 2);
+
+ update();
+}
+
+ChangeDisplay::ChangeDisplay(int id, const std::string &name):
+ AttrDisplay(id, name), mNeeded(1)
+{
+ mPoints = new Label("1");
+ mDec = new Button(_("-"), "dec", this);
+ mInc = new Button(_("+"), "inc", this);
+ mDec->setWidth(mInc->getWidth());
+
+ // Do the layout
+ ContainerPlacer place = mLayout->getPlacer(0, 0);
+
+ place(0, 0, mLabel, 3);
+ place(3, 0, mDec);
+ place(4, 0, mValue, 2);
+ place(6, 0, mInc);
+ place(7, 0, mPoints);
+
+ update();
+}
+
+std::string ChangeDisplay::update()
+{
+ mPoints->setCaption(toString(mNeeded));
+
+ mDec->setEnabled(player_node->getCorrectionPoints());
+ mInc->setEnabled(player_node->getCharacterPoints() >= mNeeded);
+
+ return AttrDisplay::update();
+}
+
+void ChangeDisplay::setPointsNeeded(int needed)
+{
+ mNeeded = needed;
+
+ update();
+}
+
+void ChangeDisplay::action(const gcn::ActionEvent &event)
+{
+ if (event.getSource() == mDec)
+ {
+ Net::getPlayerHandler()->decreaseAttribute(mId);
+ }
+ else if (event.getSource() == mInc)
+ {
+ Net::getPlayerHandler()->increaseAttribute(mId);
+ }
}
diff --git a/src/gui/statuswindow.h b/src/gui/statuswindow.h
index 1e2a5097..f6d4f73e 100644
--- a/src/gui/statuswindow.h
+++ b/src/gui/statuswindow.h
@@ -28,75 +28,71 @@
#include <guichan/actionlistener.hpp>
-class LocalPlayer;
+#include <map>
+
+class AttrDisplay;
class ProgressBar;
+class ScrollArea;
+class VertContainer;
/**
* The player status dialog.
*
* \ingroup Interface
*/
-class StatusWindow : public Window, public gcn::ActionListener
+class StatusWindow : public Window
{
public:
+ enum { // Some update constants
+ HP = -1,
+ MP = -2,
+ EXP = -3,
+ MONEY = -4,
+ CHAR_POINTS = -5,
+ LEVEL = -6
+ };
+
/**
* Constructor.
*/
- StatusWindow(LocalPlayer *player);
+ StatusWindow();
- /**
- * Called when receiving actions from widget.
- */
- void action(const gcn::ActionEvent &event);
+ std::string update(int id);
- /**
- * Draw this window
- */
- void draw(gcn::Graphics *graphics);
+ void setPointsNeeded(int id, int needed);
- /**
- * Updates this dialog with values from PLAYER_INFO *char_info
- */
- void update();
+ void addAttribute(int id, const std::string &name, bool modifiable);
static void updateHPBar(ProgressBar *bar, bool showMax = false);
+ static void updateMPBar(ProgressBar *bar, bool showMax = false);
+ static void updateXPBar(ProgressBar *bar, bool percent = true);
+ static void updateProgressBar(ProgressBar *bar, int value, int max,
+ bool percent);
+ void updateProgressBar(ProgressBar *bar, int id,
+ bool percent = true);
private:
- LocalPlayer *mPlayer;
-
/**
* Status Part
*/
- gcn::Label *mLvlLabel, *mMoneyLabel, *mHpLabel, *mHpValueLabel;
- ProgressBar *mHpBar;
+ gcn::Label *mLvlLabel, *mMoneyLabel;
+ gcn::Label *mHpLabel, *mMpLabel, *mXpLabel;
+ ProgressBar *mHpBar, *mMpBar, *mXpBar;
- /**
- * Derived Statistics captions
- */
-/*
- gcn::Label *mStatsAttackLabel, *mStatsDefenseLabel;
- gcn::Label *mStatsMagicAttackLabel, *mStatsMagicDefenseLabel;
- gcn::Label *mStatsAccuracyLabel, *mStatsEvadeLabel;
- gcn::Label *mStatsReflexLabel;
-
- gcn::Label *mStatsAttackPoints, *mStatsDefensePoints;
- gcn::Label *mStatsMagicAttackPoints, *mStatsMagicDefensePoints;
- gcn::Label *mStatsAccuracyPoints, *mStatsEvadePoints;
- gcn::Label *mStatsReflexPoints;
-*/
- /**
- * Stats captions.
- */
- gcn::Label *mStatsLabel[6];
- gcn::Label *mStatsDisplayLabel[6];
- gcn::Label *mCharacterPointsLabel;
- gcn::Label *mCorrectionPointsLabel;
+#ifdef EATHENA_SUPPORT
+ gcn::Label *mJobLvlLabel, *mJobLabel;
+ ProgressBar *mJobBar;
+#endif
- /**
- * Stats buttons.
- */
- gcn::Button *mStatsPlus[6];
- gcn::Button *mStatsMinus[6];
+ VertContainer *mAttrCont;
+ ScrollArea *mAttrScroll;
+ VertContainer *mDAttrCont;
+ ScrollArea *mDAttrScroll;
+
+ gcn::Label *mCharacterPointsLabel, *mCorrectionPointsLabel;
+
+ typedef std::map<int, AttrDisplay*> Attrs;
+ Attrs mAttrs;
};
extern StatusWindow *statusWindow;
diff --git a/src/gui/storagewindow.cpp b/src/gui/storagewindow.cpp
index 91224359..f0d00ee7 100644
--- a/src/gui/storagewindow.cpp
+++ b/src/gui/storagewindow.cpp
@@ -24,6 +24,7 @@
#include "gui/inventorywindow.h"
#include "gui/itemamount.h"
#include "gui/itemcontainer.h"
+#include "gui/setup.h"
#include "gui/viewport.h"
#include "gui/widgets/button.h"
@@ -58,6 +59,7 @@ StorageWindow::StorageWindow(int invSize):
setWindowName("Storage");
setResizable(true);
setCloseButton(true);
+ setupWindow->registerWindowForReset(this);
// If you adjust these defaults, don't forget to adjust the trade window's.
setDefaultSize(375, 300, ImageRect::CENTER);
diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp
index 3abb985e..22eefc14 100644
--- a/src/gui/trade.cpp
+++ b/src/gui/trade.cpp
@@ -29,6 +29,7 @@
#include "gui/inventorywindow.h"
#include "gui/itemamount.h"
#include "gui/itemcontainer.h"
+#include "gui/setup.h"
#include "gui/widgets/button.h"
#include "gui/widgets/chattab.h"
@@ -65,6 +66,7 @@ TradeWindow::TradeWindow():
setDefaultSize(386, 180, ImageRect::CENTER);
setMinWidth(386);
setMinHeight(180);
+ setupWindow->registerWindowForReset(this);
std::string longestName = getFont()->getWidth(_("OK")) >
getFont()->getWidth(_("Trade")) ?
@@ -92,7 +94,7 @@ TradeWindow::TradeWindow():
ScrollArea *partnerScroll = new ScrollArea(mPartnerItemContainer);
partnerScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
- mMoneyLabel = new Label(strprintf(_("You get %s."), ""));
+ mMoneyLabel = new Label(strprintf(_("You get %s"), ""));
gcn::Label *mMoneyLabel2 = new Label(_("You give:"));
mMoneyField = new TextField;
@@ -128,7 +130,7 @@ TradeWindow::~TradeWindow()
void TradeWindow::setMoney(int amount)
{
- mMoneyLabel->setCaption(strprintf(_("You get %s."),
+ mMoneyLabel->setCaption(strprintf(_("You get %s"),
Units::formatCurrency(amount).c_str()));
mMoneyLabel->adjustSize();
}
@@ -255,7 +257,10 @@ void TradeWindow::action(const gcn::ActionEvent &event)
return;
if (!inventoryWindow->isVisible())
+ {
+ inventoryWindow->setVisible(true);
return;
+ }
if (!item)
return;
diff --git a/src/gui/unregisterdialog.cpp b/src/gui/unregisterdialog.cpp
index 048239c5..be54453d 100644
--- a/src/gui/unregisterdialog.cpp
+++ b/src/gui/unregisterdialog.cpp
@@ -42,7 +42,7 @@
#include <sstream>
UnRegisterDialog::UnRegisterDialog(Window *parent, LoginData *loginData):
- Window("Unregister", true, parent),
+ Window(_("Unregister"), true, parent),
mWrongDataNoticeListener(new WrongDataNoticeListener),
mLoginData(loginData)
{
@@ -102,24 +102,23 @@ UnRegisterDialog::action(const gcn::ActionEvent &event)
logger->log("UnregisterDialog::unregistered, Username is %s",
username.c_str());
- std::stringstream errorMsg;
+ std::stringstream errorMessage;
bool error = false;
// Check password
if (password.length() < LEN_MIN_PASSWORD)
{
// Pass too short
- errorMsg << "The password needs to be at least "
- << LEN_MIN_PASSWORD
- << " characters long.";
+ errorMessage << strprintf(_("The password needs to be at least %d "
+ "characters long."), LEN_MIN_PASSWORD);
error = true;
}
- else if (password.length() > LEN_MAX_PASSWORD - 1 )
+ else if (password.length() > LEN_MAX_PASSWORD - 1)
{
// Pass too long
- errorMsg << "The password needs to be less than "
- << LEN_MAX_PASSWORD
- << " characters long.";
+ errorMessage << strprintf(_("The password needs to be less than "
+ "%d characters long."),
+ LEN_MAX_PASSWORD);
error = true;
}
@@ -127,7 +126,7 @@ UnRegisterDialog::action(const gcn::ActionEvent &event)
{
mWrongDataNoticeListener->setTarget(this->mPasswordField);
- OkDialog *dlg = new OkDialog("Error", errorMsg.str());
+ OkDialog *dlg = new OkDialog(_("Error"), errorMessage.str());
dlg->addActionListener(mWrongDataNoticeListener);
}
else
diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp
index 21362630..bb2128b4 100644
--- a/src/gui/updatewindow.cpp
+++ b/src/gui/updatewindow.cpp
@@ -322,9 +322,8 @@ int UpdaterWindow::downloadThread(void *ptr)
{
case CURLE_COULDNT_CONNECT:
default:
- std::cerr << _("curl error ") << res << ": "
- << uw->mCurlError << _(" host: ") << url.c_str()
- << std::endl;
+ logger->log("curl error %d: %s host: %s",
+ res, uw->mCurlError, url.c_str());
break;
}
@@ -445,10 +444,13 @@ void UpdaterWindow::logic()
}
mThread = NULL;
}
+ // TODO: Only send complete sentences to gettext
mBrowserBox->addRow("");
mBrowserBox->addRow(_("##1 The update process is incomplete."));
+ // TRANSLATORS: Continues "you try again later.".
mBrowserBox->addRow(_("##1 It is strongly recommended that"));
- mBrowserBox->addRow(_("##1 you try again later"));
+ // TRANSLATORS: Begins "It is strongly recommended that".
+ mBrowserBox->addRow(_("##1 you try again later."));
mBrowserBox->addRow(mCurlError);
mScrollArea->setVerticalScrollAmount(
mScrollArea->getVerticalMaxScroll());
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index 68b5fed3..9a631581 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -116,22 +116,12 @@ void Viewport::draw(gcn::Graphics *gcnGraphics)
}
// Calculate viewpoint
-#ifdef TMWSERV_SUPPORT
int midTileX = (graphics->getWidth() + mScrollCenterOffsetX) / 2;
int midTileY = (graphics->getHeight() + mScrollCenterOffsetX) / 2;
const Vector &playerPos = player_node->getPosition();
const int player_x = (int) playerPos.x - midTileX;
const int player_y = (int) playerPos.y - midTileY;
-#else
- int midTileX = (graphics->getWidth() + mScrollCenterOffsetX) / 32 / 2;
- int midTileY = (graphics->getHeight() + mScrollCenterOffsetY) / 32 / 2;
-
- int player_x = (player_node->mX - midTileX) * 32 +
- player_node->getXOffset();
- int player_y = (player_node->mY - midTileY) * 32 +
- player_node->getYOffset();
-#endif
if (mScrollLaziness < 1)
mScrollLaziness = 1; // Avoids division by zero
diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp
index 71579bd4..2357b263 100644
--- a/src/gui/widgets/button.cpp
+++ b/src/gui/widgets/button.cpp
@@ -152,7 +152,10 @@ void Button::draw(gcn::Graphics *graphics)
static_cast<Graphics*>(graphics)->
drawImageRect(0, 0, getWidth(), getHeight(), button[mode]);
- graphics->setColor(guiPalette->getColor(Palette::TEXT));
+ if (mode == BUTTON_DISABLED)
+ graphics->setColor(guiPalette->getColor(Palette::BUTTON_DISABLED));
+ else
+ graphics->setColor(guiPalette->getColor(Palette::BUTTON));
int textX;
int textY = getHeight() / 2 - getFont()->getHeight() / 2;
diff --git a/src/gui/widgets/channeltab.cpp b/src/gui/widgets/channeltab.cpp
index e3edbba0..8b055a22 100644
--- a/src/gui/widgets/channeltab.cpp
+++ b/src/gui/widgets/channeltab.cpp
@@ -72,23 +72,24 @@ bool ChannelTab::handleCommand(const std::string &type,
{
chatLog(_("Command: /quit"));
chatLog(_("This command leaves the current channel."));
- chatLog(_("If you're the last person in the channel, it will be deleted."));
+ chatLog(_("If you're the last person in the channel, "
+ "it will be deleted."));
}
else if (args == "op")
{
chatLog(_("Command: /op <nick>"));
chatLog(_("This command makes <nick> a channel operator."));
chatLog(_("If the <nick> has spaces in it, enclose it in "
- "double quotes (\")."));
+ "double quotes (\")."));
chatLog(_("Channel operators can kick and op other users "
- "from the channel."));
+ "from the channel."));
}
else if (args == "kick")
{
chatLog(_("Command: /kick <nick>"));
chatLog(_("This command makes <nick> leave the channel."));
chatLog(_("If the <nick> has spaces in it, enclose it in "
- "double quotes (\")."));
+ "double quotes (\")."));
}
else
return false;
diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp
index d2fa33b8..e3ba4874 100644
--- a/src/gui/widgets/chattab.cpp
+++ b/src/gui/widgets/chattab.cpp
@@ -143,7 +143,7 @@ void ChatTab::chatLog(std::string line, int own, bool ignoreRecord)
lineColor = "##2"; // Equiv. to BrowserBox::GREEN
break;
case ACT_WHISPER:
- tmp.nick = strprintf(_("%s whispers: "), tmp.nick.c_str());
+ tmp.nick = strprintf(_("%s whispers: %s"), tmp.nick.c_str(), "");
lineColor = "##W";
break;
case ACT_IS:
diff --git a/src/gui/widgets/checkbox.cpp b/src/gui/widgets/checkbox.cpp
index 2e9a234b..dd57f674 100644
--- a/src/gui/widgets/checkbox.cpp
+++ b/src/gui/widgets/checkbox.cpp
@@ -35,9 +35,12 @@ Image *CheckBox::checkBoxNormal;
Image *CheckBox::checkBoxChecked;
Image *CheckBox::checkBoxDisabled;
Image *CheckBox::checkBoxDisabledChecked;
+Image *CheckBox::checkBoxNormalHi;
+Image *CheckBox::checkBoxCheckedHi;
CheckBox::CheckBox(const std::string &caption, bool selected):
- gcn::CheckBox(caption, selected)
+ gcn::CheckBox(caption, selected),
+ mHasMouse(false)
{
if (instances == 0)
{
@@ -47,10 +50,14 @@ CheckBox::CheckBox(const std::string &caption, bool selected):
checkBoxChecked = checkBox->getSubImage(9, 0, 9, 10);
checkBoxDisabled = checkBox->getSubImage(18, 0, 9, 10);
checkBoxDisabledChecked = checkBox->getSubImage(27, 0, 9, 10);
+ checkBoxNormalHi = checkBox->getSubImage(36, 0, 9, 10);
+ checkBoxCheckedHi = checkBox->getSubImage(45, 0, 9, 10);
checkBoxNormal->setAlpha(mAlpha);
checkBoxChecked->setAlpha(mAlpha);
checkBoxDisabled->setAlpha(mAlpha);
checkBoxDisabledChecked->setAlpha(mAlpha);
+ checkBoxNormalHi->setAlpha(mAlpha);
+ checkBoxCheckedHi->setAlpha(mAlpha);
checkBox->decRef();
}
@@ -67,6 +74,8 @@ CheckBox::~CheckBox()
delete checkBoxChecked;
delete checkBoxDisabled;
delete checkBoxDisabledChecked;
+ delete checkBoxNormalHi;
+ delete checkBoxCheckedHi;
}
}
@@ -86,17 +95,22 @@ void CheckBox::drawBox(gcn::Graphics* graphics)
{
Image *box;
- if (isSelected())
- {
- if (isEnabled())
- box = checkBoxChecked;
+ if (isEnabled())
+ if (isSelected())
+ if (mHasMouse)
+ box = checkBoxCheckedHi;
+ else
+ box = checkBoxChecked;
else
- box = checkBoxDisabledChecked;
- }
- else if (isEnabled())
- box = checkBoxNormal;
+ if (mHasMouse)
+ box = checkBoxNormalHi;
+ else
+ box = checkBoxNormal;
else
- box = checkBoxDisabled;
+ if (isSelected())
+ box = checkBoxDisabledChecked;
+ else
+ box = checkBoxDisabled;
if (config.getValue("guialpha", 0.8) != mAlpha)
{
@@ -105,7 +119,19 @@ void CheckBox::drawBox(gcn::Graphics* graphics)
checkBoxChecked->setAlpha(mAlpha);
checkBoxDisabled->setAlpha(mAlpha);
checkBoxDisabledChecked->setAlpha(mAlpha);
+ checkBoxNormal->setAlpha(mAlpha);
+ checkBoxCheckedHi->setAlpha(mAlpha);
}
static_cast<Graphics*>(graphics)->drawImage(box, 2, 2);
}
+
+void CheckBox::mouseEntered(gcn::MouseEvent& event)
+{
+ mHasMouse = true;
+}
+
+void CheckBox::mouseExited(gcn::MouseEvent& event)
+{
+ mHasMouse = false;
+}
diff --git a/src/gui/widgets/checkbox.h b/src/gui/widgets/checkbox.h
index 303782b0..7a7c8674 100644
--- a/src/gui/widgets/checkbox.h
+++ b/src/gui/widgets/checkbox.h
@@ -24,6 +24,7 @@
#include <guichan/widgets/checkbox.hpp>
+
class Image;
/**
@@ -54,13 +55,26 @@ class CheckBox : public gcn::CheckBox
*/
void drawBox(gcn::Graphics* graphics);
+ /**
+ * Called when the mouse enteres the widget area.
+ */
+ void mouseEntered(gcn::MouseEvent& event);
+
+ /**
+ * Called when the mouse leaves the widget area.
+ */
+ void mouseExited(gcn::MouseEvent& event);
+
private:
static int instances;
static float mAlpha;
+ bool mHasMouse;
static Image *checkBoxNormal;
static Image *checkBoxChecked;
static Image *checkBoxDisabled;
static Image *checkBoxDisabledChecked;
+ static Image *checkBoxNormalHi;
+ static Image *checkBoxCheckedHi;
};
#endif
diff --git a/src/gui/widgets/desktop.cpp b/src/gui/widgets/desktop.cpp
index a4164bcc..13ac866a 100644
--- a/src/gui/widgets/desktop.cpp
+++ b/src/gui/widgets/desktop.cpp
@@ -39,8 +39,9 @@ Desktop::Desktop()
Wallpaper::loadWallpapers();
- gcn::Label *versionLabel = new Label(FULL_VERSION);
- add(versionLabel, 25, 2);
+ mVersionLabel = new Label(FULL_VERSION);
+ mVersionLabel->setBackgroundColor(gcn::Color(255, 255, 255, 128));
+ add(mVersionLabel, 25, 2);
}
Desktop::~Desktop()
@@ -74,11 +75,20 @@ void Desktop::draw(gcn::Graphics *graphics)
if (mWallpaper)
{
- g->drawImage(mWallpaper,
+ if (!mWallpaper->isAnOpenGLOne())
+ g->drawImage(mWallpaper,
(getWidth() - mWallpaper->getWidth()) / 2,
(getHeight() - mWallpaper->getHeight()) / 2);
+ else
+ g->drawRescaledImage(mWallpaper, 0, 0, 0, 0,
+ mWallpaper->getWidth(), mWallpaper->getHeight(),
+ getWidth(), getHeight(), false);
}
+ // Draw a thin border under the application version...
+ g->setColor(gcn::Color(255, 255, 255, 128));
+ g->fillRectangle(gcn::Rectangle(mVersionLabel->getDimension()));
+
Container::draw(graphics);
}
@@ -87,13 +97,27 @@ void Desktop::setBestFittingWallpaper()
const std::string wallpaperName =
Wallpaper::getWallpaper(getWidth(), getHeight());
- Image *temp = ResourceManager::getInstance()->getImage(wallpaperName);
+ Image *nWallPaper = ResourceManager::getInstance()->getImage(wallpaperName);
- if (temp)
+ if (nWallPaper)
{
if (mWallpaper)
mWallpaper->decRef();
- mWallpaper = temp;
+
+ if (!nWallPaper->isAnOpenGLOne() && (nWallPaper->getWidth() != getWidth()
+ || nWallPaper->getHeight() != getHeight()))
+ {
+ // We rescale to obtain a fullscreen wallpaper...
+ Image *newRsclWlPpr = nWallPaper->SDLgetScaledImage(getWidth(), getHeight());
+ std::string idPath = nWallPaper->getIdPath();
+
+ // We replace the resource in the resource manager
+ nWallPaper->decRef();
+ ResourceManager::getInstance()->addResource(idPath, newRsclWlPpr);
+ mWallpaper = newRsclWlPpr;
+ }
+ else
+ mWallpaper = nWallPaper;
}
else
{
diff --git a/src/gui/widgets/desktop.h b/src/gui/widgets/desktop.h
index ad04ee96..da623bbd 100644
--- a/src/gui/widgets/desktop.h
+++ b/src/gui/widgets/desktop.h
@@ -24,6 +24,8 @@
#include "gui/widgets/container.h"
+#include "guichanfwd.h"
+
#include <guichan/widgetlistener.hpp>
class Image;
@@ -60,6 +62,7 @@ class Desktop : public Container, gcn::WidgetListener
void setBestFittingWallpaper();
Image *mWallpaper;
+ gcn::Label *mVersionLabel;
};
#endif // DESKTOP_H
diff --git a/src/gui/widgets/progressbar.cpp b/src/gui/widgets/progressbar.cpp
index 134d071f..7cc020ef 100644
--- a/src/gui/widgets/progressbar.cpp
+++ b/src/gui/widgets/progressbar.cpp
@@ -43,14 +43,17 @@ ProgressBar::ProgressBar(float progress,
int width, int height,
const gcn::Color &color):
gcn::Widget(),
- mProgress(0.0f),
- mProgressToGo(0.0f),
mSmoothProgress(true),
mColor(color),
mColorToGo(color),
mSmoothColorChange(true)
{
- setProgress(progress);
+ // The progress value is directly set at load time:
+ if (progress > 1.0f || progress < 0.0f)
+ progress = 1.0f;
+
+ mProgress = mProgressToGo = progress;
+
setSize(width, height);
if (mInstances == 0)
diff --git a/src/gui/widgets/radiobutton.cpp b/src/gui/widgets/radiobutton.cpp
index 6f0ccdbd..9cf49672 100644
--- a/src/gui/widgets/radiobutton.cpp
+++ b/src/gui/widgets/radiobutton.cpp
@@ -33,10 +33,13 @@ Image *RadioButton::radioNormal;
Image *RadioButton::radioChecked;
Image *RadioButton::radioDisabled;
Image *RadioButton::radioDisabledChecked;
+Image *RadioButton::radioNormalHi;
+Image *RadioButton::radioCheckedHi;
RadioButton::RadioButton(const std::string &caption, const std::string &group,
bool marked):
- gcn::RadioButton(caption, group, marked)
+ gcn::RadioButton(caption, group, marked),
+ mHasMouse(false)
{
if (instances == 0)
{
@@ -45,10 +48,14 @@ RadioButton::RadioButton(const std::string &caption, const std::string &group,
radioChecked = resman->getImage("graphics/gui/radioin.png");
radioDisabled = resman->getImage("graphics/gui/radioout.png");
radioDisabledChecked = resman->getImage("graphics/gui/radioin.png");
+ radioNormalHi = resman->getImage("graphics/gui/radioout_highlight.png");
+ radioCheckedHi = resman->getImage("graphics/gui/radioin_highlight.png");
radioNormal->setAlpha(mAlpha);
radioChecked->setAlpha(mAlpha);
radioDisabled->setAlpha(mAlpha);
radioDisabledChecked->setAlpha(mAlpha);
+ radioNormalHi->setAlpha(mAlpha);
+ radioCheckedHi->setAlpha(mAlpha);
}
instances++;
@@ -64,6 +71,8 @@ RadioButton::~RadioButton()
radioChecked->decRef();
radioDisabled->decRef();
radioDisabledChecked->decRef();
+ radioNormalHi->decRef();
+ radioCheckedHi->decRef();
}
}
@@ -76,21 +85,28 @@ void RadioButton::drawBox(gcn::Graphics* graphics)
radioChecked->setAlpha(mAlpha);
radioDisabled->setAlpha(mAlpha);
radioDisabledChecked->setAlpha(mAlpha);
+ radioNormalHi->setAlpha(mAlpha);
+ radioCheckedHi->setAlpha(mAlpha);
}
Image *box = NULL;
- if (isSelected())
- {
- if (isEnabled())
- box = radioChecked;
+ if (isEnabled())
+ if (isSelected())
+ if (mHasMouse)
+ box = radioCheckedHi;
+ else
+ box = radioChecked;
else
- box = radioDisabledChecked;
- }
- else if (isEnabled())
- box = radioNormal;
+ if (mHasMouse)
+ box = radioNormalHi;
+ else
+ box = radioNormal;
else
- box = radioDisabled;
+ if (isSelected())
+ box = radioDisabledChecked;
+ else
+ box = radioDisabled;
if (box)
static_cast<Graphics*>(graphics)->drawImage(box, 2, 2);
@@ -111,3 +127,14 @@ void RadioButton::draw(gcn::Graphics* graphics)
int h = getHeight() + getHeight() / 2;
graphics->drawText(getCaption(), h - 2, 0);
}
+
+void RadioButton::mouseEntered(gcn::MouseEvent& event)
+{
+ mHasMouse = true;
+}
+
+void RadioButton::mouseExited(gcn::MouseEvent& event)
+{
+ mHasMouse = false;
+}
+
diff --git a/src/gui/widgets/radiobutton.h b/src/gui/widgets/radiobutton.h
index 9aec3add..57eb3623 100644
--- a/src/gui/widgets/radiobutton.h
+++ b/src/gui/widgets/radiobutton.h
@@ -26,13 +26,13 @@
class Image;
-/*
+/**
* Guichan based RadioButton with custom look
*/
class RadioButton : public gcn::RadioButton
{
public:
- /*
+ /**
* Constructor.
*/
RadioButton(const std::string &caption,const std::string &group,
@@ -54,13 +54,26 @@ class RadioButton : public gcn::RadioButton
*/
void draw(gcn::Graphics* graphics);
+ /**
+ * Called when the mouse enteres the widget area.
+ */
+ void mouseEntered(gcn::MouseEvent& event);
+
+ /**
+ * Called when the mouse leaves the widget area.
+ */
+ void mouseExited(gcn::MouseEvent& event);
+
private:
static int instances;
static float mAlpha;
+ bool mHasMouse;
static Image *radioNormal;
static Image *radioChecked;
static Image *radioDisabled;
static Image *radioDisabledChecked;
+ static Image *radioNormalHi;
+ static Image *radioCheckedHi;
};
#endif /* RADIOBUTTON_H */
diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp
index ff3a23d1..52322b05 100644
--- a/src/gui/widgets/scrollarea.cpp
+++ b/src/gui/widgets/scrollarea.cpp
@@ -33,10 +33,13 @@ int ScrollArea::instances = 0;
float ScrollArea::mAlpha = 1.0;
ImageRect ScrollArea::background;
ImageRect ScrollArea::vMarker;
+ImageRect ScrollArea::vMarkerHi;
Image *ScrollArea::buttons[4][2];
ScrollArea::ScrollArea():
gcn::ScrollArea(),
+ mX(0),
+ mY(0),
mOpaque(true)
{
init();
@@ -44,6 +47,7 @@ ScrollArea::ScrollArea():
ScrollArea::ScrollArea(gcn::Widget *widget):
gcn::ScrollArea(widget),
+ mHasMouse(false),
mOpaque(true)
{
init();
@@ -60,6 +64,7 @@ ScrollArea::~ScrollArea()
{
for_each(background.grid, background.grid + 9, dtor<Image*>());
for_each(vMarker.grid, vMarker.grid + 9, dtor<Image*>());
+ for_each(vMarkerHi.grid, vMarkerHi.grid + 9, dtor<Image*>());
buttons[UP][0]->decRef();
buttons[UP][1]->decRef();
@@ -103,6 +108,8 @@ void ScrollArea::init()
// Load vertical scrollbar skin
Image *vscroll = resman->getImage("graphics/gui/vscroll_grey.png");
+ Image *vscrollHi = resman->getImage("graphics/gui/vscroll_highlight.png");
+
int vsgridx[4] = {0, 4, 7, 11};
int vsgridy[4] = {0, 4, 15, 19};
a = 0;
@@ -115,12 +122,18 @@ void ScrollArea::init()
vsgridx[x], vsgridy[y],
vsgridx[x + 1] - vsgridx[x],
vsgridy[y + 1] - vsgridy[y]);
+ vMarkerHi.grid[a] = vscrollHi->getSubImage(
+ vsgridx[x], vsgridy[y],
+ vsgridx[x + 1] - vsgridx[x],
+ vsgridy[y + 1] - vsgridy[y]);
vMarker.grid[a]->setAlpha(config.getValue("guialpha", 0.8));
+ vMarkerHi.grid[a]->setAlpha(config.getValue("guialpha", 0.8));
a++;
}
}
vscroll->decRef();
+ vscrollHi->decRef();
buttons[UP][0] =
resman->getImage("graphics/gui/vscroll_up_default.png");
@@ -202,6 +215,7 @@ void ScrollArea::draw(gcn::Graphics *graphics)
{
background.grid[a]->setAlpha(mAlpha);
vMarker.grid[a]->setAlpha(mAlpha);
+ vMarkerHi.grid[a]->setAlpha(mAlpha);
}
}
@@ -296,14 +310,39 @@ void ScrollArea::drawVMarker(gcn::Graphics *graphics)
{
gcn::Rectangle dim = getVerticalMarkerDimension();
- static_cast<Graphics*>(graphics)->
- drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarker);
+ if ((mHasMouse) && (mX > (getWidth() - getScrollbarWidth())))
+ static_cast<Graphics*>(graphics)->
+ drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarkerHi);
+ else
+ static_cast<Graphics*>(graphics)->
+ drawImageRect(dim.x, dim.y, dim.width, dim.height,vMarker);
}
void ScrollArea::drawHMarker(gcn::Graphics *graphics)
{
gcn::Rectangle dim = getHorizontalMarkerDimension();
- static_cast<Graphics*>(graphics)->
- drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarker);
+ if ((mHasMouse) && (mY > (getHeight() - getScrollbarWidth())))
+ static_cast<Graphics*>(graphics)->
+ drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarkerHi);
+ else
+ static_cast<Graphics*>(graphics)->
+ drawImageRect(dim.x, dim.y, dim.width, dim.height, vMarker);
}
+
+void ScrollArea::mouseMoved(gcn::MouseEvent& event)
+{
+mX = event.getX();
+mY = event.getY();
+}
+
+void ScrollArea::mouseEntered(gcn::MouseEvent& event)
+{
+ mHasMouse = true;
+}
+
+void ScrollArea::mouseExited(gcn::MouseEvent& event)
+{
+ mHasMouse = false;
+}
+
diff --git a/src/gui/widgets/scrollarea.h b/src/gui/widgets/scrollarea.h
index 700de32b..8fd92b5f 100644
--- a/src/gui/widgets/scrollarea.h
+++ b/src/gui/widgets/scrollarea.h
@@ -83,6 +83,21 @@ class ScrollArea : public gcn::ScrollArea
*/
bool isOpaque() const { return mOpaque; }
+ /**
+ * Called when the mouse moves in the widget area.
+ */
+ void mouseMoved(gcn::MouseEvent& event);
+
+ /**
+ * Called when the mouse enteres the widget area.
+ */
+ void mouseEntered(gcn::MouseEvent& event);
+
+ /**
+ * Called when the mouse leaves the widget area.
+ */
+ void mouseExited(gcn::MouseEvent& event);
+
protected:
enum BUTTON_DIR {
UP,
@@ -110,8 +125,11 @@ class ScrollArea : public gcn::ScrollArea
static float mAlpha;
static ImageRect background;
static ImageRect vMarker;
+ static ImageRect vMarkerHi;
static Image *buttons[4][2];
+ int mX,mY;
+ bool mHasMouse;
bool mOpaque;
};
diff --git a/src/gui/widgets/slider.cpp b/src/gui/widgets/slider.cpp
index 7cd0e54a..6ce5f849 100644
--- a/src/gui/widgets/slider.cpp
+++ b/src/gui/widgets/slider.cpp
@@ -29,17 +29,21 @@
Image *Slider::hStart, *Slider::hMid, *Slider::hEnd, *Slider::hGrip;
Image *Slider::vStart, *Slider::vMid, *Slider::vEnd, *Slider::vGrip;
+Image *Slider::hStartHi, *Slider::hMidHi, *Slider::hEndHi, *Slider::hGripHi;
+Image *Slider::vStartHi, *Slider::vMidHi, *Slider::vEndHi, *Slider::vGripHi;
float Slider::mAlpha = 1.0;
int Slider::mInstances = 0;
Slider::Slider(double scaleEnd):
- gcn::Slider(scaleEnd)
+ gcn::Slider(scaleEnd),
+ mHasMouse(false)
{
init();
}
Slider::Slider(double scaleStart, double scaleEnd):
- gcn::Slider(scaleStart, scaleEnd)
+ gcn::Slider(scaleStart, scaleEnd),
+ mHasMouse(false)
{
init();
}
@@ -58,6 +62,14 @@ Slider::~Slider()
delete vMid;
delete vEnd;
delete vGrip;
+ delete hStartHi;
+ delete hMidHi;
+ delete hEndHi;
+ delete hGripHi;
+ delete vStartHi;
+ delete vMidHi;
+ delete vEndHi;
+ delete vGripHi;
}
}
@@ -71,6 +83,7 @@ void Slider::init()
{
ResourceManager *resman = ResourceManager::getInstance();
Image *slider = resman->getImage("graphics/gui/slider.png");
+ Image *sliderHi = resman->getImage("graphics/gui/slider_hilight.png");
x = 0; y = 0;
w = 15; h = 6;
@@ -78,10 +91,14 @@ void Slider::init()
hStart = slider->getSubImage(x, y, o1 - x, h);
hMid = slider->getSubImage(o1, y, o2 - o1, h);
hEnd = slider->getSubImage(o2, y, w - o2 + x, h);
+ hStartHi = sliderHi->getSubImage(x, y, o1 - x, h);
+ hMidHi = sliderHi->getSubImage(o1, y, o2 - o1, h);
+ hEndHi = sliderHi->getSubImage(o2, y, w - o2 + x, h);
x = 6; y = 8;
w = 9; h = 10;
hGrip = slider->getSubImage(x, y, w, h);
+ hGripHi = sliderHi->getSubImage(x, y, w, h);
x = 0; y = 6;
w = 6; h = 21;
@@ -89,22 +106,35 @@ void Slider::init()
vStart = slider->getSubImage(x, y, w, o1 - y);
vMid = slider->getSubImage(x, o1, w, o2 - o1);
vEnd = slider->getSubImage(x, o2, w, h - o2 + y);
+ vStartHi = sliderHi->getSubImage(x, y, w, o1 - y);
+ vMidHi = sliderHi->getSubImage(x, o1, w, o2 - o1);
+ vEndHi = sliderHi->getSubImage(x, o2, w, h - o2 + y);
x = 6; y = 8;
w = 9; h = 10;
vGrip = slider->getSubImage(x, y, w, h);
+ vGripHi = sliderHi->getSubImage(x, y, w, h);
slider->decRef();
+ sliderHi->decRef();
hStart->setAlpha(mAlpha);
hMid->setAlpha(mAlpha);
hEnd->setAlpha(mAlpha);
hGrip->setAlpha(mAlpha);
+ hStartHi->setAlpha(mAlpha);
+ hMidHi->setAlpha(mAlpha);
+ hEndHi->setAlpha(mAlpha);
+ hGripHi->setAlpha(mAlpha);
vStart->setAlpha(mAlpha);
vMid->setAlpha(mAlpha);
vEnd->setAlpha(mAlpha);
vGrip->setAlpha(mAlpha);
+ vStartHi->setAlpha(mAlpha);
+ vMidHi->setAlpha(mAlpha);
+ vEndHi->setAlpha(mAlpha);
+ vGripHi->setAlpha(mAlpha);
}
mInstances++;
@@ -117,7 +147,7 @@ void Slider::draw(gcn::Graphics *graphics)
int w = getWidth();
int h = getHeight();
int x = 0;
- int y = (h - hStart->getHeight()) / 2;
+ int y = mHasMouse?(h - hStartHi->getHeight()) / 2:(h - hStart->getHeight()) / 2;
if (config.getValue("guialpha", 0.8) != mAlpha)
{
@@ -126,23 +156,45 @@ void Slider::draw(gcn::Graphics *graphics)
hMid->setAlpha(mAlpha);
hEnd->setAlpha(mAlpha);
hGrip->setAlpha(mAlpha);
+ hStartHi->setAlpha(mAlpha);
+ hMidHi->setAlpha(mAlpha);
+ hEndHi->setAlpha(mAlpha);
+ hGripHi->setAlpha(mAlpha);
vStart->setAlpha(mAlpha);
vMid->setAlpha(mAlpha);
vEnd->setAlpha(mAlpha);
vGrip->setAlpha(mAlpha);
+ vStartHi->setAlpha(mAlpha);
+ vMidHi->setAlpha(mAlpha);
+ vEndHi->setAlpha(mAlpha);
+ vGripHi->setAlpha(mAlpha);
}
+ if (!mHasMouse)
+ {
+ static_cast<Graphics*>(graphics)->drawImage(hStart, x, y);
- static_cast<Graphics*>(graphics)->drawImage(hStart, x, y);
+ w -= hStart->getWidth() + hEnd->getWidth();
+ x += hStart->getWidth();
- w -= hStart->getWidth() + hEnd->getWidth();
- x += hStart->getWidth();
+ static_cast<Graphics*>(graphics)->
+ drawImagePattern(hMid, x, y, w, hMid->getHeight());
- static_cast<Graphics*>(graphics)->
- drawImagePattern(hMid, x, y, w, hMid->getHeight());
+ x += w;
+ static_cast<Graphics*>(graphics)->drawImage(hEnd, x, y);
+ } else
+ {
+ static_cast<Graphics*>(graphics)->drawImage(hStartHi, x, y);
- x += w;
- static_cast<Graphics*>(graphics)->drawImage(hEnd, x, y);
+ w -= hStartHi->getWidth() + hEndHi->getWidth();
+ x += hStartHi->getWidth();
+
+ static_cast<Graphics*>(graphics)->
+ drawImagePattern(hMidHi, x, y, w, hMidHi->getHeight());
+
+ x += w;
+ static_cast<Graphics*>(graphics)->drawImage(hEndHi, x, y);
+ }
drawMarker(graphics);
}
@@ -150,5 +202,16 @@ void Slider::draw(gcn::Graphics *graphics)
void Slider::drawMarker(gcn::Graphics *graphics)
{
static_cast<Graphics*>(graphics)->
- drawImage(hGrip, getMarkerPosition(), (getHeight() - hGrip->getHeight()) / 2);
+ drawImage(mHasMouse?hGripHi:hGrip, getMarkerPosition(),
+ (getHeight() - (mHasMouse?hGripHi:hGrip)->getHeight()) / 2);
}
+
+void Slider::mouseEntered(gcn::MouseEvent& event)
+{
+ mHasMouse = true;
+}
+
+void Slider::mouseExited(gcn::MouseEvent& event)
+{
+ mHasMouse = false;
+} \ No newline at end of file
diff --git a/src/gui/widgets/slider.h b/src/gui/widgets/slider.h
index 56ea334a..85fb2633 100644
--- a/src/gui/widgets/slider.h
+++ b/src/gui/widgets/slider.h
@@ -58,6 +58,16 @@ class Slider : public gcn::Slider {
*/
void drawMarker(gcn::Graphics *graphics);
+ /**
+ * Called when the mouse enteres the widget area.
+ */
+ void mouseEntered(gcn::MouseEvent& event);
+
+ /**
+ * Called when the mouse leaves the widget area.
+ */
+ void mouseExited(gcn::MouseEvent& event);
+
private:
/**
* Used to initialize instances.
@@ -66,6 +76,9 @@ class Slider : public gcn::Slider {
static Image *hStart, *hMid, *hEnd, *hGrip;
static Image *vStart, *vMid, *vEnd, *vGrip;
+ static Image *hStartHi, *hMidHi, *hEndHi, *hGripHi;
+ static Image *vStartHi, *vMidHi, *vEndHi, *vGripHi;
+ bool mHasMouse;
static float mAlpha;
static int mInstances;
};
diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp
index f2231fca..3e49263e 100644
--- a/src/gui/widgets/tab.cpp
+++ b/src/gui/widgets/tab.cpp
@@ -55,7 +55,7 @@ struct TabData
static TabData const data[TAB_COUNT] = {
{ "graphics/gui/tab.png", 0, 0 },
- { "graphics/gui/tab.png", 9, 4 },
+ { "graphics/gui/tab_hilight.png", 9, 4 },
{ "graphics/gui/tabselected.png", 16, 19 },
{ "graphics/gui/tab.png", 25, 23 }
};
@@ -63,7 +63,7 @@ static TabData const data[TAB_COUNT] = {
ImageRect Tab::tabImg[TAB_COUNT];
Tab::Tab() : gcn::Tab(),
- mTabColor(&guiPalette->getColor(Palette::TEXT))
+ mTabColor(&guiPalette->getColor(Palette::TAB))
{
init();
}
@@ -123,21 +123,19 @@ void Tab::draw(gcn::Graphics *graphics)
// check which type of tab to draw
if (mTabbedArea)
{
+ mLabel->setForegroundColor(*mTabColor);
if (mTabbedArea->isTabSelected(this))
{
mode = TAB_SELECTED;
// if tab is selected, it doesnt need to highlight activity
- mLabel->setForegroundColor(*mTabColor);
mHighlighted = false;
- }
- else if (mHighlighted)
+ } else if (mHasMouse)
{
mode = TAB_HIGHLIGHTED;
- mLabel->setForegroundColor(guiPalette->getColor(Palette::TAB_HIGHLIGHT));
}
- else
+ if (mHighlighted)
{
- mLabel->setForegroundColor(*mTabColor);
+ mLabel->setForegroundColor(guiPalette->getColor(Palette::TAB_HIGHLIGHT));
}
}
diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp
index 07f46a94..bb5ae9a4 100644
--- a/src/gui/widgets/tabbedarea.cpp
+++ b/src/gui/widgets/tabbedarea.cpp
@@ -69,6 +69,16 @@ gcn::Widget *TabbedArea::getWidget(const std::string &name) const
return NULL;
}
+gcn::Widget *TabbedArea::getCurrentWidget()
+{
+ gcn::Tab *tab = getSelectedTab();
+
+ if (tab)
+ return getWidget(tab->getCaption());
+ else
+ return NULL;
+}
+
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 6aaafe16..29ba2f76 100644
--- a/src/gui/widgets/tabbedarea.h
+++ b/src/gui/widgets/tabbedarea.h
@@ -63,6 +63,11 @@ class TabbedArea : public gcn::TabbedArea
*/
gcn::Widget *getWidget(const std::string &name) const;
+ /**
+ * Returns the widget for the current tab
+ */
+ gcn::Widget *getCurrentWidget();
+
using gcn::TabbedArea::addTab;
/**
diff --git a/src/gui/widgets/vertcontainer.cpp b/src/gui/widgets/vertcontainer.cpp
new file mode 100644
index 00000000..9dd02cdc
--- /dev/null
+++ b/src/gui/widgets/vertcontainer.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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/widgets/vertcontainer.h"
+
+VertContainer::VertContainer(int spacing):
+ mSpacing(spacing),
+ mCount(0)
+{
+ addWidgetListener(this);
+}
+
+void VertContainer::add(gcn::Widget *widget)
+{
+ Container::add(widget);
+ widget->setPosition(0, mCount * mSpacing);
+ widget->setSize(getWidth(), mSpacing);
+ mCount++;
+ setHeight(mCount * mSpacing);
+}
+
+void VertContainer::clear()
+{
+ Container::clear();
+
+ mCount = 0;
+}
+
+void VertContainer::widgetResized(const gcn::Event &event)
+{
+ for (WidgetListIterator it = mWidgets.begin(); it != mWidgets.end(); it++)
+ {
+ (*it)->setWidth(getWidth());
+ }
+}
diff --git a/src/gui/widgets/vertcontainer.h b/src/gui/widgets/vertcontainer.h
new file mode 100644
index 00000000..9e15e66a
--- /dev/null
+++ b/src/gui/widgets/vertcontainer.h
@@ -0,0 +1,47 @@
+/*
+ * 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 GUI_VERTCONTAINER_H
+#define GUI_VERTCONTAINER_H
+
+#include "gui/widgets/container.h"
+
+#include <guichan/widgetlistener.hpp>
+
+/**
+ * A widget container.
+ *
+ * This container places it's contents veritcally.
+ */
+class VertContainer : public Container, public gcn::WidgetListener
+{
+ public:
+ VertContainer(int spacing);
+ virtual void add(gcn::Widget *widget);
+ virtual void clear();
+ void widgetResized(const gcn::Event &event);
+
+ private:
+ int mSpacing;
+ int mCount;
+};
+
+#endif
diff --git a/src/gui/widgets/whispertab.cpp b/src/gui/widgets/whispertab.cpp
index 43c63cc0..5509a589 100644
--- a/src/gui/widgets/whispertab.cpp
+++ b/src/gui/widgets/whispertab.cpp
@@ -84,14 +84,14 @@ bool WhisperTab::handleCommand(const std::string &type,
else if (args == "ignore")
{
chatLog(_("Command: /ignore"));
- chatLog(_("This command ignores the other player reguardless of "
+ chatLog(_("This command ignores the other player regardless of "
"current relations."));
}
else if (args == "unignore")
{
chatLog(_("Command: /unignore <player>"));
chatLog(_("This command stops ignoring the other player if they "
- "are being ignored"));
+ "are being ignored."));
}
else
return false;
diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp
index 19d80671..1ee84a6f 100644
--- a/src/gui/widgets/window.cpp
+++ b/src/gui/widgets/window.cpp
@@ -306,6 +306,10 @@ void Window::setVisible(bool visible)
void Window::setVisible(bool visible, bool forceSticky)
{
+ // Check if the window is off screen...
+ if (visible)
+ checkIfIsOffScreen();
+
gcn::Window::setVisible((!forceSticky && isSticky()) || visible);
}
@@ -526,6 +530,9 @@ void Window::loadWindowState()
{
setSize(mDefaultWidth, mDefaultHeight);
}
+
+ // Check if the window is off screen...
+ checkIfIsOffScreen();
}
void Window::saveWindowState()
@@ -739,3 +746,63 @@ void Window::center()
{
setLocationRelativeTo(getParent());
}
+
+void Window::checkIfIsOffScreen(bool partially, bool entirely)
+{
+ // Move the window onto screen if it has become off screen
+ // For instance, because of resolution change...
+
+ // First of all, don't deal when a window hasn't got
+ // any size initialized yet...
+ if (getWidth() == 0 && getHeight() == 0)
+ return;
+
+ // Made partially the default behaviour
+ if (!partially && !entirely)
+ partially = true;
+
+ // Keep guichan window inside screen (supports resizing any side)
+
+ gcn::Rectangle winDimension = getDimension();
+
+ if (winDimension.x < 0)
+ {
+ winDimension.width += winDimension.x;
+ winDimension.x = 0;
+ }
+ if (winDimension.y < 0)
+ {
+ winDimension.height += winDimension.y;
+ winDimension.y = 0;
+ }
+
+ // Look if the window is partially off-screen limits...
+ if (partially)
+ {
+ if (winDimension.x + winDimension.width > graphics->getWidth())
+ {
+ winDimension.x = graphics->getWidth() - winDimension.width;
+ }
+
+ if (winDimension.y + winDimension.height > graphics->getHeight())
+ {
+ winDimension.y = graphics->getHeight() - winDimension.height;
+ }
+ setDimension(winDimension);
+ return;
+ }
+
+ if (entirely)
+ {
+ if (winDimension.x > graphics->getWidth())
+ {
+ winDimension.x = graphics->getWidth() - winDimension.width;
+ }
+
+ if (winDimension.y > graphics->getHeight())
+ {
+ winDimension.y = graphics->getHeight() - winDimension.height;
+ }
+ }
+ setDimension(winDimension);
+}
diff --git a/src/gui/widgets/window.h b/src/gui/widgets/window.h
index 153602ba..b3ef3fdc 100644
--- a/src/gui/widgets/window.h
+++ b/src/gui/widgets/window.h
@@ -269,7 +269,7 @@ class Window : public gcn::Window, gcn::WidgetListener
int defaultWidth, int defaultHeight);
/**
- * Set the default win pos and size tot he current ones.
+ * Set the default win pos and size to the current ones.
*/
void setDefaultSize();
@@ -347,6 +347,13 @@ class Window : public gcn::Window, gcn::WidgetListener
};
/**
+ * Check if the window is off-screen and then move it to be visible
+ * again. This is internally used by loadWindowState
+ * and setVisible(true) members.
+ */
+ void checkIfIsOffScreen(bool partially = true, bool entirely = true);
+
+ /**
* Determines if the mouse is in a resize area and returns appropriate
* resize handles. Also initializes drag offset in case the resize
* grip is used.
diff --git a/src/gui/windowmenu.cpp b/src/gui/windowmenu.cpp
index 8964f072..96776617 100644
--- a/src/gui/windowmenu.cpp
+++ b/src/gui/windowmenu.cpp
@@ -62,7 +62,7 @@ WindowMenu::WindowMenu():
#ifdef TMWSERV_SUPPORT
N_("Magic"),
N_("Guilds"),
- N_("Buddys"),
+ N_("Buddies"),
#endif
N_("Shortcut"),
N_("Setup"),
@@ -138,7 +138,7 @@ void WindowMenu::action(const gcn::ActionEvent &event)
{
window = guildWindow;
}
- else if (event.getId() == "Buddys")
+ else if (event.getId() == "Buddies")
{
window = buddyWindow;
}
diff --git a/src/inventory.cpp b/src/inventory.cpp
index 532d9ab6..202c3e52 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -29,11 +29,7 @@ struct SlotUsed : public std::unary_function<Item*, bool>
{
bool operator()(const Item *item) const
{
-#ifdef TMWSERV_SUPPORT
- return item && item->getId() && item->getQuantity();
-#else
- return item && item->getId() != -1 && item->getQuantity() > 0;
-#endif
+ return item && item->getId() >= 0 && item->getQuantity() > 0;
}
};
@@ -54,11 +50,7 @@ Inventory::~Inventory()
Item *Inventory::getItem(int index) const
{
-#ifdef TMWSERV_SUPPORT
- if (index < 0 || index >= mSize)
-#else
if (index < 0 || index >= mSize || !mItems[index] || mItems[index]->getQuantity() <= 0)
-#endif
return 0;
return mItems[index];
@@ -91,6 +83,7 @@ void Inventory::setItem(int index, int id, int quantity, bool equipment)
Item *item = new Item(id, quantity, equipment);
item->setInvIndex(index);
mItems[index] = item;
+ mItems[index]->setEquipment(equipment);
}
else if (id > 0)
{
diff --git a/src/item.cpp b/src/item.cpp
index 2fadc035..312a7f63 100644
--- a/src/item.cpp
+++ b/src/item.cpp
@@ -43,10 +43,8 @@ void Item::setId(int id)
{
mId = id;
-#ifdef TMWSERV_SUPPORT
// Types 0 and 1 are not equippable items.
mEquipment = id && getInfo().getType() >= 2;
-#endif
// Load the associated image
if (mImage)
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 241cfe99..1cc0ae34 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -40,25 +40,25 @@
#include "gui/gui.h"
#include "gui/ministatus.h"
#include "gui/palette.h"
-#ifdef EATHENA_SUPPORT
+#include "gui/skilldialog.h"
+#include "gui/statuswindow.h"
#include "gui/storagewindow.h"
-#endif
+
+#include "gui/widgets/chattab.h"
#include "net/inventoryhandler.h"
#include "net/net.h"
#include "net/partyhandler.h"
#include "net/playerhandler.h"
+#include "net/specialhandler.h"
#include "net/tradehandler.h"
-#ifdef TMWSERV_SUPPORT
#include "effectmanager.h"
+#ifdef TMWSERV_SUPPORT
#include "guild.h"
-#include "net/tmwserv/gameserver/player.h"
+//#include "net/tmwserv/gameserver/player.h"
#include "net/tmwserv/chatserver/guild.h"
-#else
-#include "net/ea/partyhandler.h"
-#include "net/ea/skillhandler.h"
#endif
#include "resources/animation.h"
@@ -80,44 +80,26 @@ const short walkingKeyboardDelay = 40;
LocalPlayer *player_node = NULL;
-#ifdef TMWSERV_SUPPORT
-LocalPlayer::LocalPlayer():
- Player(65535, 0, NULL),
- mEquipment(new Equipment),
-#else
LocalPlayer::LocalPlayer(int id, int job, Map *map):
Player(id, job, map),
- mCharId(0),
- mJobXp(0),
- mJobLevel(0),
- mXpForNextLevel(0), mJobXpForNextLevel(0),
- mMp(0), mMaxMp(0),
+#ifdef EATHENA_SUPPORT
mAttackRange(0),
- ATK(0), MATK(0), DEF(0), MDEF(0), HIT(0), FLEE(0),
- ATK_BONUS(0), MATK_BONUS(0), DEF_BONUS(0), MDEF_BONUS(0), FLEE_BONUS(0),
- mStatPoint(0), mSkillPoint(0),
- mStatsPointsToAttribute(0),
- mEquipment(new Equipment),
#endif
+ mEquipment(new Equipment),
mInStorage(false),
#ifdef EATHENA_SUPPORT
- mXp(0),
mTargetTime(-1),
#endif
mLastTarget(-1),
-#ifdef TMWSERV_SUPPORT
- mAttributeBase(NB_CHARACTER_ATTRIBUTES, -1),
- mAttributeEffective(NB_CHARACTER_ATTRIBUTES, -1),
- mExpCurrent(CHAR_SKILL_NB, -1),
- mExpNext(CHAR_SKILL_NB, -1),
- mCharacterPoints(-1),
- mCorrectionPoints(-1),
- mLevelProgress(0),
-#endif
+ mCharacterPoints(0),
+ mCorrectionPoints(0),
mLevel(1),
+ mExp(0), mExpNeeded(0),
+ mMp(0), mMaxMp(0),
mMoney(0),
mTotalWeight(1), mMaxWeight(1),
mHp(1), mMaxHp(1),
+ mSkillPoints(0),
mTarget(NULL), mPickUpTarget(NULL),
mTrading(false), mGoingToTarget(false), mKeepAttacking(false),
mLastAction(-1),
@@ -127,10 +109,8 @@ LocalPlayer::LocalPlayer(int id, int job, Map *map):
#ifdef TMWSERV_SUPPORT
mLocalWalkTime(-1),
#endif
- mStorage(new Inventory(STORAGE_SIZE))
-#ifdef TMWSERV_SUPPORT
- , mExpMessageTime(0)
-#endif
+ mStorage(new Inventory(STORAGE_SIZE)),
+ mMessageTime(0)
{
// Variable to keep the local player from doing certain actions before a map
// is initialized. e.g. drawing a player's name using the TextManager, since
@@ -164,25 +144,28 @@ void LocalPlayer::logic()
if (get_elapsed_time(mLastAction) >= 1000)
mLastAction = -1;
-#ifdef TMWSERV_SUPPORT
// Show XP messages
- if (!mExpMessages.empty())
+ if (!mMessages.empty())
{
- if (mExpMessageTime == 0)
+ if (mMessageTime == 0)
{
- const Vector &pos = getPosition();
+ //const Vector &pos = getPosition();
+
+ MessagePair info = mMessages.front();
particleEngine->addTextRiseFadeOutEffect(
- mExpMessages.front(),
- (int) pos.x + 16,
- (int) pos.y - 16,
- &guiPalette->getColor(Palette::EXP_INFO),
+ info.first,
+ /*(int) pos.x,
+ (int) pos.y - 48,*/
+ getPixelX(),
+ getPixelY() - 48,
+ &guiPalette->getColor(info.second),
gui->getInfoParticleFont(), true);
- mExpMessages.pop_front();
- mExpMessageTime = 30;
+ mMessages.pop_front();
+ mMessageTime = 30;
}
- mExpMessageTime--;
+ mMessageTime--;
}
if ((mSpecialRechargeUpdateNeeded%11) == 0)
@@ -201,7 +184,7 @@ void LocalPlayer::logic()
}
mSpecialRechargeUpdateNeeded++;
-#else
+#ifdef EATHENA_SUPPORT
// Targeting allowed 4 times a second
if (get_elapsed_time(mLastTarget) >= 250)
mLastTarget = -1;
@@ -213,7 +196,6 @@ void LocalPlayer::logic()
setTarget(NULL);
mLastTarget = -1;
}
-
#endif
if (mTarget)
@@ -232,8 +214,8 @@ void LocalPlayer::logic()
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);
+ const int rangeX = abs(mTarget->getTileX() - getTileX());
+ const int rangeY = abs(mTarget->getTileY() - getTileY());
#endif
const int attackRange = getAttackRange();
const int inRange = rangeX > attackRange || rangeY > attackRange
@@ -366,13 +348,8 @@ void LocalPlayer::setInvItem(int index, int id, int amount)
void LocalPlayer::pickUp(FloorItem *item)
{
-#ifdef TMWSERV_SUPPORT
int dx = item->getX() - (int) getPosition().x / 32;
int dy = item->getY() - (int) getPosition().y / 32;
-#else
- int dx = item->getX() - mX;
- int dy = item->getY() - mY;
-#endif
if (dx * dx + dy * dy < 4)
{
@@ -409,22 +386,12 @@ void LocalPlayer::walk(unsigned char dir)
#ifdef TMWSERV_SUPPORT
Being::setDestination(pos.x, pos.y);
#else
- Being::setDestination(mX, mY);
+ Being::setDestination(getTileX(), getTileY());
#endif
return;
}
int dx = 0, dy = 0;
-#ifdef TMWSERV_SUPPORT
- if (dir & UP)
- dy -= 32;
- if (dir & DOWN)
- dy += 32;
- if (dir & LEFT)
- dx -= 32;
- if (dir & RIGHT)
- dx += 32;
-#else
if (dir & UP)
dy--;
if (dir & DOWN)
@@ -433,7 +400,6 @@ void LocalPlayer::walk(unsigned char dir)
dx--;
if (dir & RIGHT)
dx++;
-#endif
// Prevent skipping corners over colliding tiles
#ifdef TMWSERV_SUPPORT
@@ -444,9 +410,9 @@ void LocalPlayer::walk(unsigned char dir)
((int) pos.y + dy) / 32, getWalkMask()))
dy = 16 - (int) pos.y % 32;
#else
- if (dx && !mMap->getWalk(mX + dx, mY, getWalkMask()))
+ if (dx && !mMap->getWalk(getTileX() + dx, getTileY(), getWalkMask()))
dx = 0;
- if (dy && !mMap->getWalk(mX, mY + dy, getWalkMask()))
+ if (dy && !mMap->getWalk(getTileX(), getTileY() + dy, getWalkMask()))
dy = 0;
#endif
@@ -460,7 +426,7 @@ void LocalPlayer::walk(unsigned char dir)
// Checks our path up to 1 tiles, if a blocking tile is found
// We go to the last good tile, and break out of the loop
- for (dScaler = 1; dScaler <= 1; dScaler++)
+ for (dScaler = 1; dScaler <= 32; dScaler++)
{
if ( (dx || dy) &&
!mMap->getWalk( ((int) pos.x + (dx * dScaler)) / 32,
@@ -473,16 +439,17 @@ void LocalPlayer::walk(unsigned char dir)
if (dScaler >= 0)
{
- setDestination((int) pos.x + (dx * dScaler), (int) pos.y + (dy * dScaler));
+ effectManager->trigger(15, (int) pos.x + (dx * dScaler), (int) pos.y + (dy * dScaler));
+ setDestination((int) pos.x + (dx * dScaler), (int) pos.y + (dy * dScaler));
}
#else
- if (dx && dy && !mMap->getWalk(mX + dx, mY + dy, getWalkMask()))
+ if (dx && dy && !mMap->getWalk(getTileX() + dx, getTileY() + dy, getWalkMask()))
dx = 0;
// Walk to where the player can actually go
- if ((dx || dy) && mMap->getWalk(mX + dx, mY + dy, getWalkMask()))
+ if ((dx || dy) && mMap->getWalk(getTileX() + dx, getTileY() + dy, getWalkMask()))
{
- setDestination(mX + dx, mY + dy);
+ setDestination(getTileX() + dx, getTileY() + dy);
}
#endif
else if (dir)
@@ -588,21 +555,22 @@ void LocalPlayer::setWalkingDir(int dir)
}
}
-#ifdef TMWSERV_SUPPORT
void LocalPlayer::stopWalking(bool sendToServer)
{
if (mAction == WALK && mWalkingDir) {
mWalkingDir = 0;
+#ifdef TMWSERV_SUPPORT
mLocalWalkTime = 0;
+#endif
Being::setDestination(getPosition().x,getPosition().y);
if (sendToServer)
- Net::GameServer::Player::walk(getPosition().x, getPosition().y);
+ Net::getPlayerHandler()->setDestination(getPosition().x,
+ getPosition().y);
setAction(STAND);
}
clearPath();
}
-#endif
void LocalPlayer::toggleSit()
{
@@ -682,9 +650,10 @@ void LocalPlayer::attack()
Net::GameServer::Player::attack(getSpriteDirection());
}
*/
+
void LocalPlayer::useSpecial(int special)
{
- Net::GameServer::Player::useSpecial(special);
+ Net::getSpecialHandler()->use(special);
}
void LocalPlayer::setSpecialStatus(int id, int current, int max, int recharge)
@@ -724,8 +693,8 @@ void LocalPlayer::attack(Being *target, bool keep)
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;
+ int dist_x = target->getTileX() - getTileX();
+ int dist_y = target->getTileY() - getTileY();
// Must be standing to attack
if (mAction != STAND)
@@ -802,14 +771,14 @@ void LocalPlayer::stopAttack()
mLastTarget = -1;
}
-#ifdef TMWSERV_SUPPORT
-
void LocalPlayer::raiseAttribute(size_t attr)
{
// we assume that the server allows the change. When not we will undo it later.
mCharacterPoints--;
- mAttributeBase.at(attr)++;
- Net::GameServer::Player::raiseAttribute(attr + CHAR_ATTR_BEGIN);
+ IntMap::iterator it = mAttributeBase.find(attr);
+ if (it != mAttributeBase.end())
+ (*it).second++;
+ Net::getPlayerHandler()->increaseAttribute(attr);
}
void LocalPlayer::lowerAttribute(size_t attr)
@@ -817,90 +786,179 @@ void LocalPlayer::lowerAttribute(size_t attr)
// we assume that the server allows the change. When not we will undo it later.
mCorrectionPoints--;
mCharacterPoints++;
- mAttributeBase.at(attr)--;
- Net::GameServer::Player::lowerAttribute(attr + CHAR_ATTR_BEGIN);
+ IntMap::iterator it = mAttributeBase.find(attr);
+ if (it != mAttributeBase.end())
+ (*it).second--;
+ Net::getPlayerHandler()->decreaseAttribute(attr);
}
-const struct LocalPlayer::SkillInfo& LocalPlayer::getSkillInfo(int skill)
+void LocalPlayer::setAttributeBase(int num, int value)
{
- static const SkillInfo skills[CHAR_SKILL_NB + 1] =
- {
- { _("Unarmed"), "graphics/images/unarmed.png" }, // CHAR_SKILL_WEAPON_NONE
- { _("Knife"), "graphics/images/knife.png" }, // CHAR_SKILL_WEAPON_KNIFE
- { _("Sword"), "graphics/images/sword.png" }, // CHAR_SKILL_WEAPON_SWORD
- { _("Polearm"), "graphics/images/polearm.png" }, // CHAR_SKILL_WEAPON_POLEARM
- { _("Staff"), "graphics/images/staff.png" }, // CHAR_SKILL_WEAPON_STAFF
- { _("Whip"), "graphics/images/whip.png" }, // CHAR_SKILL_WEAPON_WHIP
- { _("Bow"), "graphics/images/bow.png" }, // CHAR_SKILL_WEAPON_BOW
- { _("Shooting"), "graphics/images/shooting.png" }, // CHAR_SKILL_WEAPON_SHOOTING
- { _("Mace"), "graphics/images/mace.png" }, // CHAR_SKILL_WEAPON_MACE
- { _("Axe"), "graphics/images/axe.png" }, // CHAR_SKILL_WEAPON_AXE
- { _("Thrown"), "graphics/images/thrown.png" }, // CHAR_SKILL_WEAPON_THROWN
- { _("Magic"), "graphics/images/magic.png" }, // CHAR_SKILL_MAGIC_IAMJUSTAPLACEHOLDER
- { _("Craft"), "graphics/images/craft.png" }, // CHAR_SKILL_CRAFT_IAMJUSTAPLACEHOLDER
- { _("Unknown Skill"), "graphics/images/unknown.png" }
- };
-
- if ((skill < 0) || (skill > CHAR_SKILL_NB))
- {
- return skills[CHAR_SKILL_NB];
- }
- else
+ int old = mAttributeBase[num];
+
+ mAttributeBase[num] = value;
+ if (skillDialog)
{
- return skills[skill];
+ if (skillDialog->update(num).empty() || !(value > old))
+ return;
+
+ effectManager->trigger(1, this);
}
+
+ if (statusWindow)
+ statusWindow->update(num);
+}
+
+void LocalPlayer::setAttributeEffective(int num, int value)
+{
+ mAttributeEffective[num] = value;
+ if (skillDialog)
+ skillDialog->update(num);
+
+ if (statusWindow)
+ statusWindow->update(num);
+}
+
+void LocalPlayer::setCharacterPoints(int n)
+{
+ mCharacterPoints = n;
+
+ if (statusWindow)
+ statusWindow->update(StatusWindow::CHAR_POINTS);
+}
+
+void LocalPlayer::setCorrectionPoints(int n)
+{
+ mCorrectionPoints = n;
+
+ if (statusWindow)
+ statusWindow->update(StatusWindow::CHAR_POINTS);
+}
+
+void LocalPlayer::setSkillPoints(int points)
+{
+ mSkillPoints = points;
+ if (skillDialog)
+ skillDialog->update();
}
void LocalPlayer::setExperience(int skill, int current, int next)
{
- int diff = current - mExpCurrent.at(skill);
- if (mMap && mExpCurrent.at(skill) != -1 && diff > 0)
+ std::pair<int, int> cur = getExperience(skill);
+ int diff = current - cur.first;
+
+ cur = std::pair<int, int>(current, next);
+
+ mSkillExp[skill] = cur;
+ std::string name;
+ if (skillDialog)
+ name = skillDialog->update(skill);
+
+ if (mMap && cur.first != -1 && diff > 0 && !name.empty())
{
- const std::string text = toString(diff) + " " + getSkillInfo(skill).name + " xp";
- mExpMessages.push_back(text);
+ addMessageToQueue(strprintf("%d %s xp", diff, name.c_str()));
}
-
- mExpCurrent.at(skill) = current;
- mExpNext.at(skill) = next;
}
std::pair<int, int> LocalPlayer::getExperience(int skill)
{
- return std::pair<int, int> (mExpCurrent.at(skill), mExpNext.at(skill));
+ return mSkillExp[skill];
}
-#else
+void LocalPlayer::setHp(int value)
+{
+ mHp = value;
-void LocalPlayer::setXp(int xp)
+ if (statusWindow)
+ statusWindow->update(StatusWindow::HP);
+}
+
+void LocalPlayer::setMaxHp(int value)
{
- if (mMap && xp > mXp)
+ mMaxHp = value;
+
+ if (statusWindow)
+ statusWindow->update(StatusWindow::HP);
+}
+
+void LocalPlayer::setLevel(int value)
+{
+ mLevel = value;
+
+ if (statusWindow)
+ statusWindow->update(StatusWindow::LEVEL);
+}
+
+void LocalPlayer::setExp(int value)
+{
+ if (mMap && value > mExp)
{
- const std::string text = toString(xp - mXp) + " xp";
-
- // Show XP number
- particleEngine->addTextRiseFadeOutEffect(
- text,
- getPixelX(),
- getPixelY() - 48,
- &guiPalette->getColor(Palette::EXP_INFO),
- gui->getInfoParticleFont(), true);
+ addMessageToQueue(toString(value - mExp) + " xp");
}
- mXp = xp;
+ mExp = value;
+
+ if (statusWindow)
+ statusWindow->update(StatusWindow::EXP);
}
-#endif
+void LocalPlayer::setExpNeeded(int value)
+{
+ mExpNeeded = value;
-void LocalPlayer::pickedUp(const std::string &item)
+ if (statusWindow)
+ statusWindow->update(StatusWindow::EXP);
+}
+
+void LocalPlayer::setMP(int value)
+{
+ mMp = value;
+
+ if (statusWindow)
+ statusWindow->update(StatusWindow::MP);
+}
+
+void LocalPlayer::setMaxMP(int value)
+{
+ mMaxMp = value;
+
+ if (statusWindow)
+ statusWindow->update(StatusWindow::MP);
+}
+
+void LocalPlayer::setMoney(int value)
+{
+ mMoney = value;
+
+ if (statusWindow)
+ statusWindow->update(StatusWindow::MONEY);
+}
+
+void LocalPlayer::pickedUp(const ItemInfo &itemInfo, int amount)
{
- if (mMap)
+ if (!amount)
{
- // Show pickup notification
- particleEngine->addTextRiseFadeOutEffect(
- item,
- getPixelX(),
- getPixelY() - 48,
- &guiPalette->getColor(Palette::PICKUP_INFO),
- gui->getInfoParticleFont(), true);
+ if (config.getValue("showpickupchat", 1))
+ {
+ localChatTab->chatLog(_("Unable to pick up item."), BY_SERVER);
+ }
+ }
+ else
+ {
+ if (config.getValue("showpickupchat", 1))
+ {
+ // TRANSLATORS: This sentence may be translated differently
+ // for different grammatical numbers (singular, plural, ...)
+ localChatTab->chatLog(strprintf(ngettext("You picked up %d "
+ "[@@%d|%s@@].", "You picked up %d [@@%d|%s@@].", amount),
+ amount, itemInfo.getId(), itemInfo.getName().c_str()),
+ BY_SERVER);
+ }
+
+ if (mMap && config.getValue("showpickupparticle", 0))
+ {
+ // Show pickup notification
+ addMessageToQueue(itemInfo.getName(), Palette::PICKUP_INFO);
+ }
}
}
@@ -930,8 +988,8 @@ bool LocalPlayer::withinAttackRange(Being *target)
return !(dx > range || dy > range);
#else
- int dist_x = abs(target->mX - mX);
- int dist_y = abs(target->mY - mY);
+ int dist_x = abs(target->getTileX() - getTileY());
+ int dist_y = abs(target->getTileY() - getTileX());
if (dist_x > getAttackRange() || dist_y > getAttackRange())
{
@@ -953,7 +1011,7 @@ void LocalPlayer::setGotoTarget(Being *target)
#else
setTarget(target);
mGoingToTarget = true;
- setDestination(target->mX, target->mY);
+ setDestination(target->getTileX(), target->getTileY());
#endif
}
@@ -1049,3 +1107,9 @@ void LocalPlayer::setInStorage(bool inStorage)
storageWindow->setVisible(inStorage);
}
#endif
+
+void LocalPlayer::addMessageToQueue(const std::string &message,
+ Palette::ColorType color)
+{
+ mMessages.push_back(MessagePair(message, color));
+}
diff --git a/src/localplayer.h b/src/localplayer.h
index 0a3f742b..0b41ca82 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -26,6 +26,7 @@
#include <vector>
#include "player.h"
+#include "gui/palette.h"
class Equipment;
class FloorItem;
@@ -34,7 +35,6 @@ class Inventory;
class Item;
class Map;
-#ifdef TMWSERV_SUPPORT
struct Special
{
@@ -43,6 +43,7 @@ struct Special
int recharge;
};
+
/**
* Attributes used during combat. Available to all the beings.
*/
@@ -91,66 +92,26 @@ enum
CHAR_ATTR_END,
CHAR_ATTR_NB = CHAR_ATTR_END - CHAR_ATTR_BEGIN,
- CHAR_SKILL_BEGIN = CHAR_ATTR_END,
-
- CHAR_SKILL_WEAPON_BEGIN = CHAR_SKILL_BEGIN,
- CHAR_SKILL_WEAPON_NONE = CHAR_SKILL_WEAPON_BEGIN,
- CHAR_SKILL_WEAPON_KNIFE,
- CHAR_SKILL_WEAPON_SWORD,
- CHAR_SKILL_WEAPON_POLEARM,
- CHAR_SKILL_WEAPON_STAFF,
- CHAR_SKILL_WEAPON_WHIP,
- CHAR_SKILL_WEAPON_BOW,
- CHAR_SKILL_WEAPON_SHOOTING,
- CHAR_SKILL_WEAPON_MACE,
- CHAR_SKILL_WEAPON_AXE,
- CHAR_SKILL_WEAPON_THROWN,
- CHAR_SKILL_WEAPON_END,
- CHAR_SKILL_WEAPON_NB = CHAR_SKILL_WEAPON_END - CHAR_SKILL_WEAPON_BEGIN,
-
- CHAR_SKILL_MAGIC_BEGIN = CHAR_SKILL_WEAPON_END,
- CHAR_SKILL_MAGIC_IAMJUSTAPLACEHOLDER = CHAR_SKILL_MAGIC_BEGIN,
- // add magic skills here
- CHAR_SKILL_MAGIC_END,
- CHAR_SKILL_MAGIC_NB = CHAR_SKILL_MAGIC_END - CHAR_SKILL_MAGIC_BEGIN,
-
- CHAR_SKILL_CRAFT_BEGIN = CHAR_SKILL_MAGIC_END,
- CHAR_SKILL_CRAFT_IAMJUSTAPLACEHOLDER = CHAR_SKILL_CRAFT_BEGIN,
- // add crafting skills here
- CHAR_SKILL_CRAFT_END,
- CHAR_SKILL_CRAFT_NB = CHAR_SKILL_CRAFT_END - CHAR_SKILL_CRAFT_BEGIN,
-
- CHAR_SKILL_END = CHAR_SKILL_CRAFT_END,
- CHAR_SKILL_NB = CHAR_SKILL_END - CHAR_SKILL_BEGIN,
-
- NB_CHARACTER_ATTRIBUTES = CHAR_SKILL_END
+ NB_CHARACTER_ATTRIBUTES = CHAR_ATTR_END
};
-#endif
-
/**
* The local player character.
*/
class LocalPlayer : public Player
{
public:
+#ifdef TMWSERV_SUPPORT
enum Attribute
{
-#ifdef TMWSERV_SUPPORT
STR = 0, AGI, DEX, VIT, INT, WIL, CHR
-#else
- STR = 0, AGI, VIT, INT, DEX, LUK
-#endif
};
+#endif
/**
* Constructor.
*/
-#ifdef TMWSERV_SUPPORT
- LocalPlayer();
-#else
- LocalPlayer(int id, int job, Map *map);
-#endif
+ LocalPlayer(int id= 65535, int job = 0, Map *map = NULL);
/**
* Destructor.
@@ -220,14 +181,13 @@ class LocalPlayer : public Player
*/
void setTrading(bool trading) { mTrading = trading; }
-#ifdef TMWSERV_SUPPORT
void useSpecial(int id);
void setSpecialStatus(int id, int current, int max, int recharge);
const std::map<int, Special> &getSpecialStatus() const
{ return mSpecials; }
-#endif
+
void attack(Being *target = NULL, bool keep = false);
/**
@@ -292,7 +252,6 @@ class LocalPlayer : public Player
*/
bool withinAttackRange(Being *target);
-#ifdef TMWSERV_SUPPORT
/**
* Stops the player dead in his tracks
*/
@@ -307,15 +266,14 @@ class LocalPlayer : public Player
* Uses a correction point to lower an attribute
*/
void lowerAttribute(size_t attr);
-#endif
void toggleSit();
void emote(Uint8 emotion);
/**
- * Shows item pickup effect if the player is on a map.
+ * Shows item pickup notifications.
*/
- void pickedUp(const std::string &item);
+ void pickedUp(const ItemInfo &itemInfo, int amount);
/**
* Accessors for mInStorage
@@ -324,34 +282,7 @@ class LocalPlayer : public Player
void setInStorage(bool inStorage);
#ifdef EATHENA_SUPPORT
- /**
- * Sets the amount of XP. Shows XP gaining effect if the player is on
- * a map.
- */
- void setXp(int xp);
-
- /**
- * Returns the amount of experience points.
- */
- int getXp() const { return mXp; }
-
- Uint32 mCharId; /**< Used only during character selection. */
-
- Uint32 mJobXp;
- Uint32 mJobLevel;
- Uint32 mXpForNextLevel, mJobXpForNextLevel;
- Uint16 mMp, mMaxMp;
-
Uint16 mAttackRange;
-
- Uint8 mAttr[6];
- Uint8 mAttrUp[6];
-
- int ATK, MATK, DEF, MDEF, HIT, FLEE;
- int ATK_BONUS, MATK_BONUS, DEF_BONUS, MDEF_BONUS, FLEE_BONUS;
-
- Uint16 mStatPoint, mSkillPoint;
- Uint16 mStatsPointsToAttribute;
#endif
int getHp() const
@@ -360,31 +291,39 @@ class LocalPlayer : public Player
int getMaxHp() const
{ return mMaxHp; }
- void setHp(int value)
- { mHp = value; }
+ void setHp(int value);
- void setMaxHp(int value)
- { mMaxHp = value; }
+ void setMaxHp(int value);
int getLevel() const
{ return mLevel; }
- void setLevel(int value)
- { mLevel = value; }
+ void setLevel(int value);
-#ifdef TMWSERV_SUPPORT
- void setLevelProgress(int percent)
- { mLevelProgress = percent; }
+ void setExp(int value);
- int getLevelProgress() const
- { return mLevelProgress; }
-#endif
+ int getExp() const
+ { return mExp; }
+
+ void setExpNeeded(int value);
+
+ int getExpNeeded() const
+ { return mExpNeeded; }
+
+ void setMP(int value);
+
+ int getMP() const
+ { return mMp; }
+
+ void setMaxMP(int value);
+
+ int getMaxMP() const
+ { return mMaxMp; }
int getMoney() const
{ return mMoney; }
- void setMoney(int value)
- { mMoney = value; }
+ void setMoney(int value);
int getTotalWeight() const
{ return mTotalWeight; }
@@ -398,42 +337,34 @@ class LocalPlayer : public Player
void setMaxWeight(int value)
{ mMaxWeight = value; }
-#ifdef TMWSERV_SUPPORT
- int getAttributeBase(int num) const
+ int getAttributeBase(int num)
{ return mAttributeBase[num]; }
- void setAttributeBase(int num, int value)
- { mAttributeBase[num] = value; }
+ void setAttributeBase(int num, int value);
- int getAttributeEffective(int num) const
+ int getAttributeEffective(int num)
{ return mAttributeEffective[num]; }
- void setAttributeEffective(int num, int value)
- { mAttributeEffective[num] = value; }
+ void setAttributeEffective(int num, int value);
int getCharacterPoints() const
{ return mCharacterPoints; }
- void setCharacterPoints(int n)
- { mCharacterPoints = n; }
+ void setCharacterPoints(int n);
int getCorrectionPoints() const
{ return mCorrectionPoints; }
- void setCorrectionPoints(int n)
- { mCorrectionPoints = n; }
+ void setCorrectionPoints(int n);
- void setExperience(int skill, int current, int next);
+ int getSkillPoints() const
+ { return mSkillPoints; }
- struct SkillInfo {
- std::string name;
- std::string icon;
- };
+ void setSkillPoints(int points);
- static const SkillInfo& getSkillInfo(int skill);
+ void setExperience(int skill, int current, int next);
std::pair<int, int> getExperience(int skill);
-#endif
bool mUpdateName; /** Whether or not the name settings have changed */
@@ -441,6 +372,9 @@ class LocalPlayer : public Player
const std::auto_ptr<Equipment> mEquipment;
+ void addMessageToQueue(const std::string &message,
+ Palette::ColorType color = Palette::EXP_INFO);
+
protected:
virtual void handleStatusEffect(StatusEffect *effect, int effectId);
@@ -448,29 +382,29 @@ class LocalPlayer : public Player
bool mInStorage; /**< Whether storage is currently accessible */
#ifdef EATHENA_SUPPORT
- int mXp; /**< Experience points. */
int mTargetTime; /** How long the being has been targeted **/
#endif
int mLastTarget; /** Time stamp of last targeting action, -1 if none. */
-#ifdef TMWSERV_SUPPORT
// Character status:
- std::vector<int> mAttributeBase;
- std::vector<int> mAttributeEffective;
- std::vector<int> mExpCurrent;
- std::vector<int> mExpNext;
+ typedef std::map<int, int> IntMap;
+ IntMap mAttributeBase;
+ IntMap mAttributeEffective;
+ std::map<int, std::pair<int, int> > mSkillExp;
int mCharacterPoints;
int mCorrectionPoints;
int mLevelProgress;
std::map<int, Special> mSpecials;
char mSpecialRechargeUpdateNeeded;
-#endif
int mLevel;
+ int mExp, mExpNeeded;
+ int mMp, mMaxMp;
int mMoney;
int mTotalWeight;
int mMaxWeight;
int mHp;
int mMaxHp;
+ int mSkillPoints;
int mGMLevel;
@@ -512,10 +446,10 @@ class LocalPlayer : public Player
/** Animated target cursors. */
SimpleAnimation *mTargetCursor[2][NUM_TC];
-#ifdef TMWSERV_SUPPORT
- std::list<std::string> mExpMessages; /**< Queued exp messages*/
- int mExpMessageTime;
-#endif
+ typedef std::pair<std::string, Palette::ColorType> MessagePair;
+ /** Queued exp messages*/
+ std::list<MessagePair> mMessages;
+ int mMessageTime;
};
extern LocalPlayer *player_node;
diff --git a/src/main.cpp b/src/main.cpp
index 3ea8aa2d..10145dfc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -143,9 +143,6 @@ namespace
} listener;
}
-static const int defaultScreenWidth = 800;
-static const int defaultScreenHeight = 600;
-
static const int defaultSfxVolume = 100;
static const int defaultMusicVolume = 60;
@@ -260,7 +257,7 @@ static void setUpdatesDir()
else
{
logger->log("Error: Invalid update host: %s", updateHost.c_str());
- errorMessage = _("Invalid update host: ") + updateHost;
+ errorMessage = strprintf(_("Invalid update host: %s"), updateHost.c_str());
state = STATE_ERROR;
}
}
@@ -335,10 +332,8 @@ static void initHomeDir(const Options &options)
(errno != EEXIST))
#endif
{
- std::cout << homeDir
- << _(" can't be created, but it doesn't exist! Exiting.")
- << std::endl;
- exit(1);
+ logger->error(strprintf(_("%s doesn't exist and can't be created! "
+ "Exiting."), homeDir.c_str()));
}
}
@@ -389,8 +384,7 @@ static void initConfiguration(const Options &options)
configFile = fopen(configPath.c_str(), "wt");
}
if (configFile == NULL) {
- std::cout << "Can't create " << configPath << ". "
- << "Using Defaults." << std::endl;
+ logger->log("Can't create %s. Using defaults.", configPath.c_str());
} else {
fclose(configFile);
config.init(configPath);
@@ -405,9 +399,8 @@ static void initEngine(const Options &options)
// Initialize SDL
logger->log("Initializing SDL...");
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) {
- std::cerr << "Could not initialize SDL: " <<
- SDL_GetError() << std::endl;
- exit(1);
+ logger->error(strprintf("Could not initialize SDL: %s",
+ SDL_GetError()));
}
atexit(SDL_Quit);
@@ -420,10 +413,8 @@ static void initEngine(const Options &options)
ResourceManager *resman = ResourceManager::getInstance();
if (!resman->setWriteDir(homeDir)) {
- std::cout << homeDir
- << " couldn't be set as home directory! Exiting."
- << std::endl;
- exit(1);
+ logger->error(strprintf("%s couldn't be set as home directory! "
+ "Exiting.", homeDir.c_str()));
}
// Add the user's homedir to PhysicsFS search path
@@ -489,10 +480,8 @@ static void initEngine(const Options &options)
// Try to set the desired video mode
if (!graphics->setVideoMode(width, height, bpp, fullscreen, hwaccel))
{
- std::cerr << _("Couldn't set ")
- << width << "x" << height << "x" << bpp << _(" video mode: ")
- << SDL_GetError() << std::endl;
- exit(1);
+ logger->error(strprintf("Couldn't set %dx%dx%d video mode: %s",
+ width, height, bpp, SDL_GetError()));
}
// Initialize for drawing
@@ -1160,7 +1149,7 @@ int main(int argc, char *argv[])
case STATE_LOGIN_ERROR:
logger->log("State: LOGIN ERROR");
- currentDialog = new OkDialog("Error ", errorMessage);
+ currentDialog = new OkDialog(_("Error"), errorMessage);
currentDialog->addActionListener(&loginListener);
currentDialog = NULL; // OkDialog deletes itself
break;
@@ -1214,8 +1203,8 @@ int main(int argc, char *argv[])
case STATE_CHANGEEMAIL:
logger->log("State: CHANGE EMAIL");
- currentDialog = new OkDialog("Email Address change",
- "Email Address changed successfully!");
+ currentDialog = new OkDialog(_("Email Address Change"),
+ _("Email address changed successfully!"));
currentDialog->addActionListener(&accountListener);
currentDialog = NULL; // OkDialog deletes itself
loginData.email = loginData.newEmail;
@@ -1231,8 +1220,8 @@ int main(int argc, char *argv[])
case STATE_CHANGEPASSWORD:
logger->log("State: CHANGE PASSWORD");
- currentDialog = new OkDialog("Password change",
- "Password changed successfully!");
+ currentDialog = new OkDialog(_("Password Change"),
+ _("Password changed successfully!"));
currentDialog->addActionListener(&accountListener);
currentDialog = NULL; // OkDialog deletes itself
loginData.password = loginData.newPassword;
@@ -1248,8 +1237,8 @@ int main(int argc, char *argv[])
case STATE_UNREGISTER:
logger->log("State: UNREGISTER");
accountServerConnection->disconnect();
- currentDialog = new OkDialog("Unregister successful",
- "Farewell, come back any time ....");
+ currentDialog = new OkDialog(_("Unregister Successful"),
+ _("Farewell, come back any time..."));
loginData.clear();
//The errorlistener sets the state to STATE_CHOOSE_SERVER
currentDialog->addActionListener(&errorListener);
@@ -1258,7 +1247,7 @@ int main(int argc, char *argv[])
case STATE_ACCOUNTCHANGE_ERROR:
logger->log("State: ACCOUNT CHANGE ERROR");
- currentDialog = new OkDialog("Error ", errorMessage);
+ currentDialog = new OkDialog(_("Error"), errorMessage);
currentDialog->addActionListener(&accountListener);
currentDialog = NULL; // OkDialog deletes itself
break;
@@ -1266,7 +1255,7 @@ int main(int argc, char *argv[])
case STATE_ERROR:
logger->log("State: ERROR");
- currentDialog = new OkDialog("Error", errorMessage);
+ currentDialog = new OkDialog(_("Error"), errorMessage);
currentDialog->addActionListener(&errorListener);
currentDialog = NULL; // OkDialog deletes itself
gameServerConnection->disconnect();
@@ -1555,8 +1544,8 @@ int main(int argc, char *argv[])
case STATE_CHANGEPASSWORD:
logger->log("State: CHANGE PASSWORD");
- currentDialog = new OkDialog("Password change",
- "Password changed successfully!");
+ currentDialog = new OkDialog(_("Password Change"),
+ _("Password changed successfully!"));
currentDialog->addActionListener(&accountListener);
currentDialog = NULL; // OkDialog deletes itself
loginData.password = loginData.newPassword;
@@ -1565,7 +1554,7 @@ int main(int argc, char *argv[])
case STATE_ACCOUNTCHANGE_ERROR:
logger->log("State: ACCOUNT CHANGE ERROR");
- currentDialog = new OkDialog("Error ", errorMessage);
+ currentDialog = new OkDialog(_("Error"), errorMessage);
currentDialog->addActionListener(&accountListener);
currentDialog = NULL; // OkDialog deletes itself
break;
diff --git a/src/map.cpp b/src/map.cpp
index 61fcdfe8..dbecda3d 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -218,11 +218,12 @@ void Map::initializeOverlays()
const float speedX = getFloatProperty(name + "scrollX");
const float speedY = getFloatProperty(name + "scrollY");
const float parallax = getFloatProperty(name + "parallax");
+ const bool keepRatio = getBoolProperty(name + "keepratio");
if (img)
{
mOverlays.push_back(
- new AmbientOverlay(img, parallax, speedX, speedY));
+ new AmbientOverlay(img, parallax, speedX, speedY, keepRatio));
// The AmbientOverlay takes control over the image.
img->decRef();
@@ -448,7 +449,7 @@ bool Map::occupied(int x, int y) const
const Being *being = *i;
// job 45 is a portal, they don't collide
- if (being->mX == x && being->mY == y && being->mJob != 45)
+ if (being->getTileX() == x && being->getTileY() == y && being->mJob != 45)
return true;
}
@@ -490,50 +491,6 @@ const std::string &Map::getName() const
return getProperty("mapname");
}
-Path Map::findSimplePath(int startX, int startY,
- int destX, int destY,
- unsigned char walkmask)
-{
- // Path to be built up (empty by default)
- Path path;
- int positionX = startX, positionY = startY;
- int directionX, directionY;
- // Checks our path up to 1 tiles, if a blocking tile is found
- // We go to the last good tile, and break out of the loop
- while(true)
- {
- directionX = destX - positionX;
- directionY = destY - positionY;
-
- if (directionX > 0)
- directionX = 1;
- else if(directionX < 0)
- directionX = -1;
-
- if (directionY > 0)
- directionY = 1;
- else if(directionY < 0)
- directionY = -1;
-
- positionX += directionX;
- positionY += directionY;
-
- if (getWalk(positionX, positionY, walkmask))
- {
- path.push_back(Position(positionX, positionY));
-
- if ((positionX == destX) && (positionY == destY))
- {
- return path;
- }
- }
- else
- {
- return path;
- }
- }
-}
-
static int const basicCost = 100;
Path Map::findPath(int startX, int startY, int destX, int destY,
diff --git a/src/map.h b/src/map.h
index 1cf3c922..6baf7411 100644
--- a/src/map.h
+++ b/src/map.h
@@ -258,13 +258,6 @@ class Map : public Properties
const std::string &getName() const;
/**
- * Find a simple path from one location to the next.
- */
- Path findSimplePath(int startX, int startY,
- int destX, int destY,
- unsigned char walkmask);
-
- /**
* Find a path from one location to the next.
*/
Path findPath(int startX, int startY, int destX, int destY,
diff --git a/src/net/ea/beinghandler.cpp b/src/net/ea/beinghandler.cpp
index f149f15f..1d780a60 100644
--- a/src/net/ea/beinghandler.cpp
+++ b/src/net/ea/beinghandler.cpp
@@ -194,14 +194,15 @@ void BeingHandler::handleMessage(MessageIn &msg)
Uint16 srcX, srcY, dstX, dstY;
msg.readCoordinatePair(srcX, srcY, dstX, dstY);
dstBeing->setAction(Being::STAND);
- dstBeing->mX = srcX;
- dstBeing->mY = srcY;
+ dstBeing->setTileCoords(srcX, srcY);
dstBeing->setDestination(dstX, dstY);
}
else
{
Uint8 dir;
- msg.readCoordinates(dstBeing->mX, dstBeing->mY, dir);
+ Uint16 x, y;
+ msg.readCoordinates(x, y, dir);
+ dstBeing->setTileCoords(x, y);
dstBeing->setDirection(dir);
}
@@ -234,8 +235,7 @@ void BeingHandler::handleMessage(MessageIn &msg)
if (dstBeing) {
dstBeing->setAction(Being::STAND);
- dstBeing->mX = srcX;
- dstBeing->mY = srcY;
+ dstBeing->setTileCoords(srcX, srcY);
dstBeing->setDestination(dstX, dstY);
}
@@ -515,14 +515,15 @@ void BeingHandler::handleMessage(MessageIn &msg)
{
Uint16 srcX, srcY, dstX, dstY;
msg.readCoordinatePair(srcX, srcY, dstX, dstY);
- dstBeing->mX = srcX;
- dstBeing->mY = srcY;
+ dstBeing->setTileCoords(srcX, srcY);
dstBeing->setDestination(dstX, dstY);
}
else
{
Uint8 dir;
- msg.readCoordinates(dstBeing->mX, dstBeing->mY, dir);
+ Uint16 x, y;
+ msg.readCoordinates(x, y, dir);
+ dstBeing->setTileCoords(x, y);
dstBeing->setDirection(dir);
}
@@ -577,8 +578,10 @@ void BeingHandler::handleMessage(MessageIn &msg)
if (mSync || id != player_node->getId()) {
dstBeing = beingManager->findBeing(id);
if (dstBeing) {
- dstBeing->mX = msg.readInt16();
- dstBeing->mY = msg.readInt16();
+ Uint16 x, y;
+ x = msg.readInt16();
+ y = msg.readInt16();
+ dstBeing->setTileCoords(x, y);
if (dstBeing->mAction == Being::WALK) {
dstBeing->mFrame = 0;
dstBeing->setAction(Being::STAND);
diff --git a/src/net/ea/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp
index 77bfaa50..6fae1864 100644
--- a/src/net/ea/charserverhandler.cpp
+++ b/src/net/ea/charserverhandler.cpp
@@ -61,18 +61,16 @@ CharServerHandler::CharServerHandler():
void CharServerHandler::handleMessage(MessageIn &msg)
{
- int slot, flags;
+ int slot;
LocalPlayer *tempPlayer;
logger->log("CharServerHandler: Packet ID: %x, Length: %d",
msg.getId(), msg.getLength());
switch (msg.getId())
{
- case 0x006b:
+ case SMSG_CHAR_LOGIN:
msg.skip(2); // Length word
- flags = msg.readInt32(); // Aethyra extensions flags
- logger->log("Server flags are: %x", flags);
- msg.skip(16); // Unused
+ msg.skip(20); // Unused
// Derive number of characters from message length
n_character = (msg.getLength() - 24) / 106;
@@ -92,13 +90,13 @@ void CharServerHandler::handleMessage(MessageIn &msg)
case SMSG_CHAR_LOGIN_ERROR:
switch (msg.readInt8()) {
case 0:
- errorMessage = _("Access denied");
+ errorMessage = _("Access denied.");
break;
case 1:
- errorMessage = _("Cannot use this ID");
+ errorMessage = _("Cannot use this ID.");
break;
default:
- errorMessage = _("Unknown failure to select character");
+ errorMessage = _("Unknown failure to select character.");
break;
}
mCharInfo->unlock();
@@ -169,14 +167,15 @@ void CharServerHandler::handleMessage(MessageIn &msg)
LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
{
- LocalPlayer *tempPlayer = new LocalPlayer(mLoginData->account_ID, 0, NULL);
+ LocalPlayer *tempPlayer = new LocalPlayer(msg.readInt32(), 0, NULL);
tempPlayer->setGender(mLoginData->sex);
- tempPlayer->mCharId = msg.readInt32();
- tempPlayer->setXp(msg.readInt32());
+ tempPlayer->setExp(msg.readInt32());
tempPlayer->setMoney(msg.readInt32());
- tempPlayer->mJobXp = msg.readInt32();
- tempPlayer->mJobLevel = msg.readInt32();
+ tempPlayer->setExperience(JOB, msg.readInt32(), 1);
+ 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());
@@ -187,8 +186,8 @@ LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
msg.skip(2); // unknown
tempPlayer->setHp(msg.readInt16());
tempPlayer->setMaxHp(msg.readInt16());
- tempPlayer->mMp = msg.readInt16();
- tempPlayer->mMaxMp = msg.readInt16();
+ tempPlayer->setMP(msg.readInt16());
+ tempPlayer->setMaxMP(msg.readInt16());
msg.readInt16(); // speed
msg.readInt16(); // class
int hairStyle = msg.readInt16();
@@ -205,7 +204,7 @@ LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
tempPlayer->setSprite(Being::MISC2_SPRITE, msg.readInt16());
tempPlayer->setName(msg.readString(24));
for (int i = 0; i < 6; i++) {
- tempPlayer->mAttr[i] = msg.readInt8();
+ tempPlayer->setAttributeBase(i + STR, msg.readInt8());
}
slot = msg.readInt8(); // character slot
msg.readInt8(); // unknown
@@ -272,7 +271,7 @@ void CharServerHandler::newCharacter(const std::string &name, int slot,
void CharServerHandler::deleteCharacter(int slot, LocalPlayer* character)
{
MessageOut outMsg(CMSG_CHAR_DELETE);
- outMsg.writeInt32(character->mCharId);
+ outMsg.writeInt32(character->getId());
outMsg.writeString("a@a.com", 40);
}
diff --git a/src/net/ea/chathandler.cpp b/src/net/ea/chathandler.cpp
index 49f83e67..65f1db3c 100644
--- a/src/net/ea/chathandler.cpp
+++ b/src/net/ea/chathandler.cpp
@@ -166,7 +166,7 @@ void ChatHandler::handleMessage(MessageIn &msg)
case SMSG_MVP:
// Display MVP player
msg.readInt32(); // id
- localChatTab->chatLog("MVP player", BY_SERVER);
+ localChatTab->chatLog(_("MVP player."), BY_SERVER);
break;
}
}
diff --git a/src/net/ea/equipmenthandler.cpp b/src/net/ea/equipmenthandler.cpp
index 0153b5da..3520bca5 100644
--- a/src/net/ea/equipmenthandler.cpp
+++ b/src/net/ea/equipmenthandler.cpp
@@ -35,10 +35,112 @@
#include "utils/gettext.h"
+const Equipment::EquipmentSlots EQUIP_POINTS[Equipment::EQUIP_VECTOREND] = {
+ Equipment::EQUIP_LEGS_SLOT,
+ Equipment::EQUIP_FIGHT1_SLOT,
+ Equipment::EQUIP_GLOVES_SLOT,
+ Equipment::EQUIP_RING2_SLOT,
+ Equipment::EQUIP_RING1_SLOT,
+ Equipment::EQUIP_FIGHT2_SLOT,
+ Equipment::EQUIP_FEET_SLOT,
+ Equipment::EQUIP_NECK_SLOT,
+ Equipment::EQUIP_HEAD_SLOT,
+ Equipment::EQUIP_TORSO_SLOT,
+ Equipment::EQUIP_PROJECTILE_SLOT};
+
+Item *equips[Equipment::EQUIP_VECTOREND];
+
namespace EAthena {
enum { debugEquipment = 1 };
+void setEquipment(int eAthenaSlot, int index, bool equiped)
+{
+ if (!eAthenaSlot)
+ return;
+
+ Item *item = player_node->getInventory()->getItem(index);
+
+ if (!item)
+ return;
+
+ int position = 0;
+
+ if (eAthenaSlot & 0x8000) { // Arrows
+ position = Equipment::EQUIP_PROJECTILE_SLOT;
+ }
+ else
+ {
+ /*
+ * An item may occupy more than 1 slot. If so, it's
+ * only shown as equipped on the *first* slot.
+ */
+ int mask = 1;
+ while (!(eAthenaSlot & mask))
+ {
+ mask <<= 1;
+ position++;
+ }
+
+ position = EQUIP_POINTS[position];
+ }
+
+ if (equips[position])
+ equips[position]->setEquipped(false);
+
+ if (equiped && item)
+ {
+ equips[position] = item;
+ item->setEquipped(true);
+ player_node->mEquipment->setEquipment(position, item->getId(), item->getQuantity());
+
+ if (debugEquipment)
+ {
+ logger->log("Equipping: %i %i at position %i",
+ index, eAthenaSlot, position);
+ }
+ }
+ else
+ {
+ equips[position] = NULL;
+ player_node->mEquipment->setEquipment(position, -1);
+
+ if (debugEquipment)
+ {
+ logger->log("Unequipping: %i %i at position %i",
+ index, eAthenaSlot, position);
+ }
+ }
+}
+
+void clearEquipment()
+{
+ for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
+ {
+ if (equips[i])
+ {
+ equips[i]->setEquipped(false);
+ player_node->mEquipment->setEquipment(i, -1);
+ }
+
+ equips[i] = NULL;
+ }
+}
+
+Item *getRealEquipedItem(const Item *equipped)
+{
+ if (!equipped)
+ return NULL;
+
+ for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
+ {
+ if (equips[i] && equipped->getId() == equips[i]->getId())
+ return equips[i];
+ }
+
+ return NULL;
+}
+
EquipmentHandler::EquipmentHandler()
{
static const Uint16 _messages[] = {
@@ -50,6 +152,7 @@ EquipmentHandler::EquipmentHandler()
0
};
handledMessages = _messages;
+ memset(equips, 0, sizeof(equips));
}
void EquipmentHandler::handleMessage(MessageIn &msg)
@@ -57,8 +160,6 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
int itemCount;
int index, equipPoint, itemId;
int type;
- int mask, position;
- Item *item;
Inventory *inventory = player_node->getInventory();
switch (msg.getId())
@@ -79,25 +180,9 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
msg.readInt8(); // refine
msg.skip(8); // card
- if (debugEquipment)
- {
- logger->log("Index: %d, ID: %d", index, itemId);
- }
-
inventory->setItem(index, itemId, 1, true);
- if (equipPoint)
- {
- mask = 1;
- position = 0;
- while (!(equipPoint & mask))
- {
- mask <<= 1;
- position++;
- }
- item = inventory->getItem(index);
- player_node->mEquipment->setEquipment(position, index);
- }
+ setEquipment(equipPoint, index, true);
}
break;
@@ -112,35 +197,7 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
break;
}
- // No point in searching when no point given
- if (!equipPoint)
- break;
-
- /*
- * An item may occupy more than 1 slot. If so, it's
- * only shown as equipped on the *first* slot.
- */
- mask = 1;
- position = 0;
- while (!(equipPoint & mask)) {
- mask <<= 1;
- position++;
- }
-
- if (debugEquipment)
- {
- logger->log("Equipping: %i %i %i at position %i",
- index, equipPoint, type, position);
- }
-
- item = inventory->getItem(player_node->mEquipment->getEquipment(position));
-
- // Unequip any existing equipped item in this position
- if (item)
- item->setEquipped(false);
-
- item = inventory->getItem(index);
- player_node->mEquipment->setEquipment(position, index);
+ setEquipment(equipPoint, index, true);
break;
case SMSG_PLAYER_UNEQUIP:
@@ -153,36 +210,7 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
break;
}
- if (!equipPoint) {
- // No point given, no point in searching
- break;
- }
-
- mask = 1;
- position = 0;
- while (!(equipPoint & mask)) {
- mask <<= 1;
- position++;
- }
-
- item = inventory->getItem(index);
- if (!item)
- break;
-
- item->setEquipped(false);
-
- if (equipPoint & 0x8000) { // Arrows
- player_node->mEquipment->setArrows(-1);
- }
- else {
- player_node->mEquipment->removeEquipment(position);
- }
-
- if (debugEquipment)
- {
- logger->log("Unequipping: %i %i(%i) %i",
- index, equipPoint, type, position);
- }
+ setEquipment(equipPoint, index, false);
break;
case SMSG_PLAYER_ATTACK_RANGE:
@@ -197,13 +225,8 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
index -= INVENTORY_OFFSET;
- item = inventory->getItem(index);
-
- if (item) {
- item->setEquipped(true);
- player_node->mEquipment->setArrows(index);
- logger->log("Arrows equipped: %i", index);
- }
+ logger->log("Arrows equipped: %i", index);
+ setEquipment(0x8000, index, true);
break;
}
}
diff --git a/src/net/ea/equipmenthandler.h b/src/net/ea/equipmenthandler.h
index 852be3c9..47c2f803 100644
--- a/src/net/ea/equipmenthandler.h
+++ b/src/net/ea/equipmenthandler.h
@@ -24,8 +24,14 @@
#include "net/messagehandler.h"
+class Item;
+
namespace EAthena {
+void setEquipment(int eAthenaSlot, int index, bool equiped);
+void clearEquipment();
+Item *getRealEquipedItem(const Item *equipped);
+
class EquipmentHandler : public MessageHandler
{
public:
diff --git a/src/net/ea/generalhandler.cpp b/src/net/ea/generalhandler.cpp
index 404bff69..1d500d62 100644
--- a/src/net/ea/generalhandler.cpp
+++ b/src/net/ea/generalhandler.cpp
@@ -19,10 +19,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "gui/inventorywindow.h"
-
#include "net/ea/generalhandler.h"
+#include "gui/inventorywindow.h"
+#include "gui/skilldialog.h"
+#include "gui/statuswindow.h"
+
#include "net/ea/network.h"
#include "net/ea/protocol.h"
@@ -41,7 +43,7 @@
#include "net/ea/playerhandler.h"
#include "net/ea/partyhandler.h"
#include "net/ea/tradehandler.h"
-#include "net/ea/skillhandler.h"
+#include "net/ea/specialhandler.h"
#include "net/ea/gui/partytab.h"
@@ -77,7 +79,7 @@ GeneralHandler::GeneralHandler():
mNpcHandler(new NpcHandler),
mPartyHandler(new PartyHandler),
mPlayerHandler(new PlayerHandler),
- mSkillHandler(new SkillHandler),
+ mSpecialHandler(new SpecialHandler),
mTradeHandler(new TradeHandler)
{
static const Uint16 _messages[] = {
@@ -115,26 +117,26 @@ void GeneralHandler::handleMessage(MessageIn &msg)
switch (code) {
case 0:
- errorMessage = _("Authentication failed");
+ errorMessage = _("Authentication failed.");
break;
case 1:
- errorMessage = _("No servers available");
+ errorMessage = _("No servers available.");
break;
case 2:
if (state == STATE_GAME)
errorMessage = _("Someone else is trying to use this "
- "account");
+ "account.");
else
- errorMessage = _("This account is already logged in");
+ errorMessage = _("This account is already logged in.");
break;
case 3:
- errorMessage = _("Speed hack detected");
+ errorMessage = _("Speed hack detected.");
break;
case 8:
- errorMessage = _("Duplicated login");
+ errorMessage = _("Duplicated login.");
break;
default:
- errorMessage = _("Unknown connection error");
+ errorMessage = _("Unknown connection error.");
break;
}
state = STATE_ERROR;
@@ -157,7 +159,7 @@ void GeneralHandler::load()
mNetwork->registerHandler(mMapHandler.get());
mNetwork->registerHandler(mNpcHandler.get());
mNetwork->registerHandler(mPlayerHandler.get());
- mNetwork->registerHandler(mSkillHandler.get());
+ mNetwork->registerHandler(mSpecialHandler.get());
mNetwork->registerHandler(mTradeHandler.get());
mNetwork->registerHandler(mPartyHandler.get());
}
@@ -201,6 +203,22 @@ void GeneralHandler::guiWindowsLoaded()
{
partyTab = new PartyTab;
inventoryWindow->setSplitAllowed(false);
+ skillDialog->loadSkills("ea-skills.xml");
+
+ statusWindow->addAttribute(STR, _("Strength"), true);
+ statusWindow->addAttribute(AGI, _("Agility"), true);
+ statusWindow->addAttribute(VIT, _("Vitality"), true);
+ statusWindow->addAttribute(INT, _("Intelligence"), true);
+ statusWindow->addAttribute(DEX, _("Dexterity"), true);
+ statusWindow->addAttribute(LUK, _("Luck"), true);
+
+ statusWindow->addAttribute(ATK, _("Attack"), false);
+ statusWindow->addAttribute(DEF, _("Defense"), false);
+ statusWindow->addAttribute(MATK, _("M.Attack"), false);
+ statusWindow->addAttribute(MDEF, _("M.Defense"), false);
+ statusWindow->addAttribute(HIT, _("% Accuracy"), false);
+ statusWindow->addAttribute(FLEE, _("% Evade"), false);
+ statusWindow->addAttribute(CRIT, _("% Critical"), false);
}
void GeneralHandler::guiWindowsUnloaded()
diff --git a/src/net/ea/generalhandler.h b/src/net/ea/generalhandler.h
index ebbc84ca..98364e5d 100644
--- a/src/net/ea/generalhandler.h
+++ b/src/net/ea/generalhandler.h
@@ -66,7 +66,7 @@ class GeneralHandler : public MessageHandler, public Net::GeneralHandler
MessageHandlerPtr mNpcHandler;
MessageHandlerPtr mPartyHandler;
MessageHandlerPtr mPlayerHandler;
- MessageHandlerPtr mSkillHandler;
+ MessageHandlerPtr mSpecialHandler;
MessageHandlerPtr mTradeHandler;
};
diff --git a/src/net/ea/inventoryhandler.cpp b/src/net/ea/inventoryhandler.cpp
index c1f04661..b6e91609 100644
--- a/src/net/ea/inventoryhandler.cpp
+++ b/src/net/ea/inventoryhandler.cpp
@@ -21,6 +21,7 @@
#include "net/ea/inventoryhandler.h"
+#include "net/ea/equipmenthandler.h"
#include "net/ea/protocol.h"
#include "net/messagein.h"
@@ -86,6 +87,7 @@ void InventoryHandler::handleMessage(MessageIn &msg)
if (msg.getId() == SMSG_PLAYER_INVENTORY)
{
// Clear inventory - this will be a complete refresh
+ clearEquipment();
inventory->clear();
}
else
@@ -178,42 +180,25 @@ void InventoryHandler::handleMessage(MessageIn &msg)
equipType = msg.readInt16();
itemType = msg.readInt8();
- if (msg.readInt8() > 0)
- {
- if (config.getValue("showpickupchat", 1))
- {
- localChatTab->chatLog(_("Unable to pick up item."),
- BY_SERVER);
- }
- }
- else
{
const ItemInfo &itemInfo = ItemDB::get(itemId);
- const std::string amountStr =
- // TRANSLATORS: Used as in "You picked up a ...", when
- // picking up only one item.
- (amount > 1) ? toString(amount) : _("a");
- if (config.getValue("showpickupchat", 1))
+ if (msg.readInt8() > 0)
{
- localChatTab->chatLog(strprintf(_("You picked up %s [@@%d|%s@@]."),
- amountStr.c_str(), itemInfo.getId(), itemInfo.getName().c_str()),
- BY_SERVER);
+ player_node->pickedUp(itemInfo, 0);
}
-
- if (config.getValue("showpickupparticle", 0))
+ else
{
- player_node->pickedUp(itemInfo.getName());
- }
+ player_node->pickedUp(itemInfo, amount);
+
+ Item *item = inventory->getItem(index);
+
+ if (item && item->getId() == itemId)
+ amount += inventory->getItem(index)->getQuantity();
- if (Item *item = inventory->getItem(index)) {
- item->setId(itemId);
- item->increaseQuantity(amount);
- } else {
inventory->setItem(index, itemId, amount, equipType != 0);
}
- }
- break;
+ } break;
case SMSG_PLAYER_INVENTORY_REMOVE:
index = msg.readInt16() - INVENTORY_OFFSET;
@@ -319,11 +304,13 @@ void InventoryHandler::equipItem(const Item *item)
void InventoryHandler::unequipItem(const Item *item)
{
- if (!item)
+ const Item *real_item = item->isEquipped() ? item : getRealEquipedItem(item);
+
+ if (!real_item)
return;
MessageOut outMsg(CMSG_PLAYER_UNEQUIP);
- outMsg.writeInt16(item->getInvIndex() + INVENTORY_OFFSET);
+ outMsg.writeInt16(real_item->getInvIndex() + INVENTORY_OFFSET);
}
void InventoryHandler::useItem(const Item *item)
diff --git a/src/net/ea/loginhandler.cpp b/src/net/ea/loginhandler.cpp
index 54e31cf3..8e7187c0 100644
--- a/src/net/ea/loginhandler.cpp
+++ b/src/net/ea/loginhandler.cpp
@@ -76,13 +76,13 @@ void LoginHandler::handleMessage(MessageIn &msg)
errorMessage = _("Account was not found. Please re-login.");
break;
case 2:
- errorMessage = _("Old password incorrect");
+ errorMessage = _("Old password incorrect.");
break;
case 3:
- errorMessage = _("New password too short");
+ errorMessage = _("New password too short.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_ACCOUNTCHANGE_ERROR;
@@ -96,7 +96,7 @@ void LoginHandler::handleMessage(MessageIn &msg)
len = msg.readInt16() - 4;
mUpdateHost = msg.readString(len);
- logger->log("Received update host \"%s\" from login server",
+ logger->log("Received update host \"%s\" from login server.",
mUpdateHost.c_str());
break;
@@ -139,21 +139,21 @@ void LoginHandler::handleMessage(MessageIn &msg)
switch (code) {
case 0:
- errorMessage = _("Unregistered ID");
+ errorMessage = _("Unregistered ID.");
break;
case 1:
- errorMessage = _("Wrong password");
+ errorMessage = _("Wrong password.");
break;
case 2:
- errorMessage = _("Account expired");
+ errorMessage = _("Account expired.");
break;
case 3:
- errorMessage = _("Rejected from server");
+ errorMessage = _("Rejected from server.");
break;
case 4:
errorMessage = _("You have been permanently banned from "
- "the game. Please contact the GM Team.");
+ "the game. Please contact the GM team.");
break;
case 6:
errorMessage = strprintf(_("You have been temporarily "
@@ -163,10 +163,10 @@ void LoginHandler::handleMessage(MessageIn &msg)
msg.readString(20).c_str());
break;
case 9:
- errorMessage = _("This user name is already taken");
+ errorMessage = _("This user name is already taken.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_ERROR;
diff --git a/src/net/ea/maphandler.cpp b/src/net/ea/maphandler.cpp
index 6f8a9827..c3c9437c 100644
--- a/src/net/ea/maphandler.cpp
+++ b/src/net/ea/maphandler.cpp
@@ -61,14 +61,17 @@ void MapHandler::handleMessage(MessageIn &msg)
switch (msg.getId())
{
case SMSG_MAP_LOGIN_SUCCESS:
+ {
+ Uint16 x, y;
msg.readInt32(); // server tick
- msg.readCoordinates(player_node->mX, player_node->mY, direction);
+ msg.readCoordinates(x, y, direction);
msg.skip(2); // unknown
logger->log("Protocol: Player start position: (%d, %d), Direction: %d",
- player_node->mX, player_node->mY, direction);
+ x, y, direction);
state = STATE_GAME;
+ player_node->setTileCoords(x, y);
game = new Game;
- break;
+ } break;
case SMSG_SERVER_PING:
// We ignore this for now
@@ -76,22 +79,27 @@ void MapHandler::handleMessage(MessageIn &msg)
break;
case SMSG_WHO_ANSWER:
- localChatTab->chatLog("Online users: " + toString(msg.readInt32()),
- BY_SERVER);
+ localChatTab->chatLog(strprintf(_("Online users: %d"),
+ msg.readInt32()), BY_SERVER);
break;
}
}
+#include <fstream>
+
void MapHandler::connect(LoginData *loginData)
{
// Send login infos
MessageOut outMsg(CMSG_MAP_SERVER_CONNECT);
outMsg.writeInt32(loginData->account_ID);
- outMsg.writeInt32(player_node->mCharId);
+ outMsg.writeInt32(player_node->getId());
outMsg.writeInt32(loginData->session_ID1);
outMsg.writeInt32(loginData->session_ID2);
outMsg.writeInt8((loginData->sex == GENDER_MALE) ? 1 : 0);
+ // Change the player's ID to the account ID to match what eAthena uses
+ player_node->setId(loginData->account_ID);
+
// We get 4 useless bytes before the real answer comes in (what are these?)
mNetwork->skip(4);
}
diff --git a/src/net/ea/network.cpp b/src/net/ea/network.cpp
index 956d7877..c6bc712c 100644
--- a/src/net/ea/network.cpp
+++ b/src/net/ea/network.cpp
@@ -318,9 +318,9 @@ bool Network::realConnect()
if (SDLNet_ResolveHost(&ipAddress, mAddress.c_str(), mPort) == -1)
{
- std::string error = "Unable to resolve host \"" + mAddress + "\"";
- setError(error);
- logger->log("SDLNet_ResolveHost: %s", error.c_str());
+ std::string errorMessage = "Unable to resolve host \"" + mAddress + "\"";
+ setError(errorMessage);
+ logger->log("SDLNet_ResolveHost: %s", errorMessage.c_str());
return false;
}
diff --git a/src/net/ea/partyhandler.cpp b/src/net/ea/partyhandler.cpp
index 5e7f43c4..a4a84b07 100644
--- a/src/net/ea/partyhandler.cpp
+++ b/src/net/ea/partyhandler.cpp
@@ -230,6 +230,7 @@ void PartyHandler::handleMessage(MessageIn &msg)
if (id == player_node->getId())
{
partyWindow->clearMembers();
+ partyWindow->clearPartyName();
partyWindow->setVisible(false);
partyTab->chatLog(_("You have left the party."), BY_SERVER);
}
diff --git a/src/net/ea/playerhandler.cpp b/src/net/ea/playerhandler.cpp
index 58167339..3e379d82 100644
--- a/src/net/ea/playerhandler.cpp
+++ b/src/net/ea/playerhandler.cpp
@@ -37,7 +37,7 @@
#include "gui/gui.h"
#include "gui/okdialog.h"
#include "gui/sell.h"
-#include "gui/skill.h"
+#include "gui/statuswindow.h"
#include "gui/storagewindow.h"
#include "gui/viewport.h"
@@ -54,6 +54,9 @@ OkDialog *deathNotice = NULL;
// everything beyond will reset the port hard.
static const int MAP_TELEPORT_SCROLL_DISTANCE = 8;
+#define ATTR_BONUS(atr) \
+(player_node->getAttributeEffective(atr) - player_node->getAttributeBase(atr))
+
// TODO Move somewhere else
namespace {
@@ -197,17 +200,16 @@ void PlayerHandler::handleMessage(MessageIn &msg)
/* Scroll if neccessary */
if (!nearby
- || (abs(x - player_node->mX) > MAP_TELEPORT_SCROLL_DISTANCE)
- || (abs(y - player_node->mY) > MAP_TELEPORT_SCROLL_DISTANCE))
+ || (abs(x - player_node->getTileX()) > MAP_TELEPORT_SCROLL_DISTANCE)
+ || (abs(y - player_node->getTileY()) > MAP_TELEPORT_SCROLL_DISTANCE))
{
- scrollOffsetX = (x - player_node->mX) * 32;
- scrollOffsetY = (y - player_node->mY) * 32;
+ scrollOffsetX = (x - player_node->getTileX()) * 32;
+ scrollOffsetY = (y - player_node->getTileY()) * 32;
}
player_node->setAction(Being::STAND);
player_node->mFrame = 0;
- player_node->mX = x;
- player_node->mY = y;
+ player_node->setTileCoords(x, y);
logger->log("Adjust scrolling by %d:%d", (int) scrollOffsetX,
(int) scrollOffsetY);
@@ -224,18 +226,14 @@ void PlayerHandler::handleMessage(MessageIn &msg)
switch (type)
{
case 0x0000: player_node->setWalkSpeed(value); break;
+ case 0x0004: break; // manner
case 0x0005: player_node->setHp(value); break;
case 0x0006: player_node->setMaxHp(value); break;
- case 0x0007: player_node->mMp = value; break;
- case 0x0008: player_node->mMaxMp = value; break;
- case 0x0009:
- player_node->mStatsPointsToAttribute = value;
- break;
+ case 0x0007: player_node->setMP(value); break;
+ case 0x0008: player_node->setMaxMP(value); break;
+ case 0x0009: player_node->setCharacterPoints(value); break;
case 0x000b: player_node->setLevel(value); break;
- case 0x000c:
- player_node->mSkillPoint = value;
- skillDialog->update();
- break;
+ case 0x000c: player_node->setSkillPoints(value); break;
case 0x0018:
if (value >= player_node->getMaxWeight() / 2 &&
player_node->getTotalWeight() <
@@ -251,15 +249,48 @@ void PlayerHandler::handleMessage(MessageIn &msg)
player_node->setTotalWeight(value);
break;
case 0x0019: player_node->setMaxWeight(value); break;
- case 0x0029: player_node->ATK = value; break;
- case 0x002b: player_node->MATK = value; break;
- case 0x002d: player_node->DEF = value; break;
- case 0x002e: player_node->DEF_BONUS = value; break;
- case 0x002f: player_node->MDEF = value; break;
- case 0x0031: player_node->HIT = value; break;
- case 0x0032: player_node->FLEE = value; break;
+
+ case 0x0029: player_node->setAttributeEffective(ATK, value
+ + ATTR_BONUS(ATK));
+ player_node->setAttributeBase(ATK, value);
+ break;
+ case 0x002a: value += player_node->getAttributeBase(ATK);
+ player_node->setAttributeEffective(ATK, value); break;
+
+ case 0x002b: player_node->setAttributeEffective(MATK, value
+ + ATTR_BONUS(MATK));
+ player_node->setAttributeBase(MATK, value);
+ statusWindow->update(StatusWindow::MP); break;
+ case 0x002c: value += player_node->getAttributeBase(MATK);
+ player_node->setAttributeEffective(MATK, value);
+ statusWindow->update(StatusWindow::MP); break;
+ case 0x002d: player_node->setAttributeEffective(DEF, value
+ + ATTR_BONUS(DEF));
+ player_node->setAttributeBase(DEF, value); break;
+ case 0x002e: value += player_node->getAttributeBase(DEF);
+ player_node->setAttributeEffective(DEF, value); break;
+
+ case 0x002f: player_node->setAttributeEffective(MDEF, value
+ + ATTR_BONUS(MDEF));
+ player_node->setAttributeBase(MDEF, value); break;
+ case 0x0030: value += player_node->getAttributeBase(MDEF);
+ player_node->setAttributeEffective(MDEF, value); break;
+
+ case 0x0031: player_node->setAttributeBase(HIT, value);
+ player_node->setAttributeEffective(HIT, value); break;
+
+ case 0x0032: player_node->setAttributeEffective(FLEE, value
+ + ATTR_BONUS(FLEE));
+ player_node->setAttributeBase(FLEE, value); break;
+ case 0x0033: value += player_node->getAttributeBase(FLEE);
+ player_node->setAttributeEffective(FLEE, value); break;
+
+ case 0x0034: player_node->setAttributeBase(CRIT, value);
+ player_node->setAttributeEffective(CRIT, value); break;
+
case 0x0035: player_node->mAttackSpeed = value; break;
- case 0x0037: player_node->mJobLevel = value; break;
+ case 0x0037: player_node->setAttributeBase(JOB, value);
+ player_node->setAttributeEffective(JOB, value); break;
case 500: player_node->setGMLevel(value); break;
}
@@ -276,54 +307,45 @@ void PlayerHandler::handleMessage(MessageIn &msg)
case SMSG_PLAYER_STAT_UPDATE_2:
switch (msg.readInt16()) {
case 0x0001:
- player_node->setXp(msg.readInt32());
+ player_node->setExp(msg.readInt32());
break;
case 0x0002:
- player_node->mJobXp = msg.readInt32();
+ player_node->setExperience(JOB, msg.readInt32(),
+ player_node->getExperience(JOB).second);
break;
case 0x0014: {
int curGp = player_node->getMoney();
player_node->setMoney(msg.readInt32());
if (player_node->getMoney() > curGp)
- localChatTab->chatLog(_("You picked up ") +
+ localChatTab->chatLog(strprintf(_("You picked up "
+ "%s."),
Units::formatCurrency(player_node->getMoney()
- - curGp), BY_SERVER);
+ - curGp).c_str()), BY_SERVER);
}
break;
case 0x0016:
- player_node->mXpForNextLevel = msg.readInt32();
+ player_node->setExpNeeded(msg.readInt32());
break;
case 0x0017:
- player_node->mJobXpForNextLevel = msg.readInt32();
+ player_node->setExperience(JOB,
+ player_node->getExperience(JOB).first,
+ msg.readInt32());
break;
}
break;
- case SMSG_PLAYER_STAT_UPDATE_3:
+ case SMSG_PLAYER_STAT_UPDATE_3: // Update a base attribute
{
int type = msg.readInt32();
int base = msg.readInt32();
int bonus = msg.readInt32();
- int total = base + bonus;
- switch (type) {
- case 0x000d: player_node->mAttr[LocalPlayer::STR] = total;
- break;
- case 0x000e: player_node->mAttr[LocalPlayer::AGI] = total;
- break;
- case 0x000f: player_node->mAttr[LocalPlayer::VIT] = total;
- break;
- case 0x0010: player_node->mAttr[LocalPlayer::INT] = total;
- break;
- case 0x0011: player_node->mAttr[LocalPlayer::DEX] = total;
- break;
- case 0x0012: player_node->mAttr[LocalPlayer::LUK] = total;
- break;
- }
+ player_node->setAttributeBase(type, base);
+ player_node->setAttributeEffective(type, base + bonus);
}
break;
- case SMSG_PLAYER_STAT_UPDATE_4:
+ case SMSG_PLAYER_STAT_UPDATE_4: // Attribute increase ack
{
int type = msg.readInt16();
int fail = msg.readInt8();
@@ -332,72 +354,105 @@ void PlayerHandler::handleMessage(MessageIn &msg)
if (fail != 1)
break;
- switch (type) {
- case 0x000d: player_node->mAttr[LocalPlayer::STR] = value;
- break;
- case 0x000e: player_node->mAttr[LocalPlayer::AGI] = value;
- break;
- case 0x000f: player_node->mAttr[LocalPlayer::VIT] = value;
- break;
- case 0x0010: player_node->mAttr[LocalPlayer::INT] = value;
- break;
- case 0x0011: player_node->mAttr[LocalPlayer::DEX] = value;
- break;
- case 0x0012: player_node->mAttr[LocalPlayer::LUK] = value;
- break;
- }
+ int bonus = ATTR_BONUS(type);
+
+ player_node->setAttributeBase(type, value);
+ player_node->setAttributeEffective(type, value + bonus);
}
break;
// Updates stats and status points
case SMSG_PLAYER_STAT_UPDATE_5:
- player_node->mStatsPointsToAttribute = msg.readInt16();
- player_node->mAttr[LocalPlayer::STR] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::STR] = msg.readInt8();
- player_node->mAttr[LocalPlayer::AGI] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::AGI] = msg.readInt8();
- player_node->mAttr[LocalPlayer::VIT] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::VIT] = msg.readInt8();
- player_node->mAttr[LocalPlayer::INT] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::INT] = msg.readInt8();
- player_node->mAttr[LocalPlayer::DEX] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::DEX] = msg.readInt8();
- player_node->mAttr[LocalPlayer::LUK] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::LUK] = msg.readInt8();
- player_node->ATK = msg.readInt16(); // ATK
- player_node->ATK_BONUS = msg.readInt16(); // ATK bonus
- player_node->MATK = msg.readInt16(); // MATK max
- player_node->MATK_BONUS = msg.readInt16(); // MATK min
- player_node->DEF = msg.readInt16(); // DEF
- player_node->DEF_BONUS = msg.readInt16(); // DEF bonus
- player_node->MDEF = msg.readInt16(); // MDEF
- player_node->MDEF_BONUS = msg.readInt16(); // MDEF bonus
- player_node->HIT = msg.readInt16(); // HIT
- player_node->FLEE = msg.readInt16(); // FLEE
- player_node->FLEE_BONUS = msg.readInt16(); // FLEE bonus
- msg.readInt16(); // critical
- msg.readInt16(); // unknown
+ player_node->setCharacterPoints(msg.readInt16());
+
+ {
+ int val = msg.readInt8();
+ player_node->setAttributeEffective(STR, val + ATTR_BONUS(STR));
+ player_node->setAttributeBase(STR, val);
+ statusWindow->setPointsNeeded(STR, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(AGI, val + ATTR_BONUS(AGI));
+ player_node->setAttributeBase(AGI, val);
+ statusWindow->setPointsNeeded(AGI, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(VIT, val + ATTR_BONUS(VIT));
+ player_node->setAttributeBase(VIT, val);
+ statusWindow->setPointsNeeded(VIT, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(INT, val + ATTR_BONUS(INT));
+ player_node->setAttributeBase(INT, val);
+ statusWindow->setPointsNeeded(INT, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(DEX, val + ATTR_BONUS(DEX));
+ player_node->setAttributeBase(DEX, val);
+ statusWindow->setPointsNeeded(DEX, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(LUK, val + ATTR_BONUS(LUK));
+ player_node->setAttributeBase(LUK, val);
+ statusWindow->setPointsNeeded(LUK, msg.readInt8());
+
+ val = msg.readInt16(); // ATK
+ player_node->setAttributeBase(ATK, val);
+ val += msg.readInt16(); // ATK bonus
+ player_node->setAttributeEffective(ATK, val);
+
+ val = msg.readInt16(); // MATK
+ player_node->setAttributeBase(MATK, val);
+ val += msg.readInt16(); // MATK bonus
+ player_node->setAttributeEffective(MATK, val);
+ statusWindow->update(StatusWindow::MP);
+
+ val = msg.readInt16(); // DEF
+ player_node->setAttributeBase(DEF, val);
+ val += msg.readInt16(); // DEF bonus
+ player_node->setAttributeEffective(DEF, val);
+
+ val = msg.readInt16(); // MDEF
+ player_node->setAttributeBase(MDEF, val);
+ val += msg.readInt16(); // MDEF bonus
+ player_node->setAttributeEffective(MDEF, val);
+
+ val = msg.readInt16(); // HIT
+ player_node->setAttributeBase(ATK, val);
+ player_node->setAttributeEffective(ATK, val);
+
+ val = msg.readInt16(); // FLEE
+ player_node->setAttributeBase(FLEE, val);
+ val += msg.readInt16(); // FLEE bonus
+ player_node->setAttributeEffective(FLEE, val);
+
+ val = msg.readInt16();
+ player_node->setAttributeBase(CRIT, val);
+ player_node->setAttributeEffective(CRIT, val);
+ }
+
+ msg.readInt16(); // manner
break;
case SMSG_PLAYER_STAT_UPDATE_6:
switch (msg.readInt16()) {
case 0x0020:
- player_node->mAttrUp[LocalPlayer::STR] = msg.readInt8();
+ statusWindow->setPointsNeeded(STR, msg.readInt8());
break;
case 0x0021:
- player_node->mAttrUp[LocalPlayer::AGI] = msg.readInt8();
+ statusWindow->setPointsNeeded(AGI, msg.readInt8());
break;
case 0x0022:
- player_node->mAttrUp[LocalPlayer::VIT] = msg.readInt8();
+ statusWindow->setPointsNeeded(VIT, msg.readInt8());
break;
case 0x0023:
- player_node->mAttrUp[LocalPlayer::INT] = msg.readInt8();
+ statusWindow->setPointsNeeded(INT, msg.readInt8());
break;
case 0x0024:
- player_node->mAttrUp[LocalPlayer::DEX] = msg.readInt8();
+ statusWindow->setPointsNeeded(DEX, msg.readInt8());
break;
case 0x0025:
- player_node->mAttrUp[LocalPlayer::LUK] = msg.readInt8();
+ statusWindow->setPointsNeeded(LUK, msg.readInt8());
break;
}
break;
@@ -433,44 +488,30 @@ void PlayerHandler::emote(int emoteId)
outMsg.writeInt8(emoteId);
}
-void PlayerHandler::increaseStat(LocalPlayer::Attribute attr)
+void PlayerHandler::increaseAttribute(size_t attr)
{
- MessageOut outMsg(CMSG_STAT_UPDATE_REQUEST);
-
- switch (attr)
+ if (attr >= STR && attr <= LUK)
{
- case LocalPlayer::STR:
- outMsg.writeInt16(0x000d);
- break;
-
- case LocalPlayer::AGI:
- outMsg.writeInt16(0x000e);
- break;
-
- case LocalPlayer::VIT:
- outMsg.writeInt16(0x000f);
- break;
-
- case LocalPlayer::INT:
- outMsg.writeInt16(0x0010);
- break;
-
- case LocalPlayer::DEX:
- outMsg.writeInt16(0x0011);
- break;
-
- case LocalPlayer::LUK:
- outMsg.writeInt16(0x0012);
- break;
+ MessageOut outMsg(CMSG_STAT_UPDATE_REQUEST);
+ outMsg.writeInt16(attr);
+ outMsg.writeInt8(1);
}
- outMsg.writeInt8(1);
}
-void PlayerHandler::decreaseStat(LocalPlayer::Attribute attr)
+void PlayerHandler::decreaseAttribute(size_t attr)
{
// Supported by eA?
}
+void PlayerHandler::increaseSkill(int skillId)
+{
+ if (player_node->getSkillPoints() <= 0)
+ return;
+
+ MessageOut outMsg(CMSG_SKILL_LEVELUP_REQUEST);
+ outMsg.writeInt16(skillId);
+}
+
void PlayerHandler::pickUp(FloorItem *floorItem)
{
MessageOut outMsg(CMSG_ITEM_PICKUP);
@@ -521,4 +562,9 @@ void PlayerHandler::ignoreAll(bool ignore)
// TODO
}
+bool PlayerHandler::canUseMagic()
+{
+ return player_node->getAttributeEffective(MATK) > 0;
+}
+
} // namespace EAthena
diff --git a/src/net/ea/playerhandler.h b/src/net/ea/playerhandler.h
index 5dbc171b..78e64a88 100644
--- a/src/net/ea/playerhandler.h
+++ b/src/net/ea/playerhandler.h
@@ -39,9 +39,11 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
void emote(int emoteId);
- void increaseStat(LocalPlayer::Attribute attr);
+ void increaseAttribute(size_t attr);
- void decreaseStat(LocalPlayer::Attribute attr);
+ void decreaseAttribute(size_t attr);
+
+ void increaseSkill(int skillId);
void pickUp(FloorItem *floorItem);
@@ -56,6 +58,8 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
void ignorePlayer(const std::string &player, bool ignore);
void ignoreAll(bool ignore);
+
+ bool canUseMagic();
};
} // namespace EAthena
diff --git a/src/net/ea/protocol.h b/src/net/ea/protocol.h
index b3759946..279e4c2f 100644
--- a/src/net/ea/protocol.h
+++ b/src/net/ea/protocol.h
@@ -22,6 +22,25 @@
#ifndef EA_PROTOCOL_H
#define EA_PROTOCOL_H
+enum {
+ JOB = 0xa,
+
+ STR = 0xd,
+ AGI,
+ VIT,
+ INT,
+ DEX,
+ LUK,
+
+ ATK,
+ DEF,
+ MATK,
+ MDEF,
+ HIT,
+ FLEE,
+ CRIT
+};
+
static const int INVENTORY_OFFSET = 2;
static const int STORAGE_OFFSET = 1;
@@ -69,6 +88,7 @@ static const int STORAGE_OFFSET = 1;
#define SMSG_PLAYER_ARROW_EQUIP 0x013c
#define SMSG_PLAYER_ARROW_MESSAGE 0x013b
#define SMSG_PLAYER_SKILLS 0x010f
+#define SMSG_PLAYER_SKILL_UP 0x010e
#define SMSG_SKILL_FAILED 0x0110
#define SMSG_ITEM_USE_RESPONSE 0x00a8
#define SMSG_ITEM_VISIBLE 0x009d /**< An item is on the floor */
@@ -160,6 +180,11 @@ static const int STORAGE_OFFSET = 1;
#define CMSG_SKILL_LEVELUP_REQUEST 0x0112
#define CMSG_STAT_UPDATE_REQUEST 0x00bb
+#define CMSG_SKILL_USE_BEING 0x0113
+#define CMSG_SKILL_USE_POSITION 0x0116
+// Variant of 0x116 with 80 char string at end (unsure of use)
+#define CMSG_SKILL_USE_POSITION_MORE 0x0190
+#define CMSG_SKILL_USE_MAP 0x011b
#define CMSG_PLAYER_INVENTORY_USE 0x00a7
#define CMSG_PLAYER_INVENTORY_DROP 0x00a2
diff --git a/src/net/ea/skillhandler.cpp b/src/net/ea/specialhandler.cpp
index 69b0fd65..528f531e 100644
--- a/src/net/ea/skillhandler.cpp
+++ b/src/net/ea/specialhandler.cpp
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "net/ea/skillhandler.h"
+#include "net/ea/specialhandler.h"
#include "net/ea/protocol.h"
@@ -29,7 +29,7 @@
#include "localplayer.h"
#include "log.h"
-#include "gui/skill.h"
+#include "gui/skilldialog.h"
#include "gui/widgets/chattab.h"
@@ -67,60 +67,68 @@
/** should always be zero if failed */
#define SKILL_FAILED 0x00
-Net::SkillHandler *skillHandler;
+Net::SpecialHandler *specialHandler;
namespace EAthena {
-SkillHandler::SkillHandler()
+SpecialHandler::SpecialHandler()
{
static const Uint16 _messages[] = {
SMSG_PLAYER_SKILLS,
SMSG_SKILL_FAILED,
+ SMSG_PLAYER_SKILL_UP,
0
};
handledMessages = _messages;
- skillHandler = this;
+ specialHandler = this;
}
-void SkillHandler::handleMessage(MessageIn &msg)
+void SpecialHandler::handleMessage(MessageIn &msg)
{
int skillCount;
+ int skillId;
switch (msg.getId())
{
case SMSG_PLAYER_SKILLS:
msg.readInt16(); // length
skillCount = (msg.getLength() - 4) / 37;
- skillDialog->cleanList();
for (int k = 0; k < skillCount; k++)
{
- int skillId = msg.readInt16();
+ skillId = msg.readInt16();
msg.readInt16(); // target type
- msg.readInt16(); // unknown
+ msg.skip(2); // unused
int level = msg.readInt16();
- int sp = msg.readInt16();
- msg.readInt16(); // range
- std::string skillName = msg.readString(24);
+ msg.readInt16(); // sp
+ msg.readInt16(); // range
+ msg.skip(24); // unused
int up = msg.readInt8();
- if (level != 0 || up != 0)
- {
- if (skillDialog->hasSkill(skillId)) {
- skillDialog->setSkill(skillId, level, sp);
- }
- else {
- skillDialog->addSkill(skillId, level, sp);
- }
- }
+ player_node->setAttributeBase(skillId, level);
+ player_node->setAttributeEffective(skillId, level);
+ skillDialog->setModifiable(skillId, up);
+ }
+ break;
+
+ case SMSG_PLAYER_SKILL_UP:
+ {
+ skillId = msg.readInt16();
+ int level = msg.readInt16();
+ msg.readInt16(); // sp
+ msg.readInt16(); // range
+ int up = msg.readInt8();
+
+ player_node->setAttributeBase(skillId, level);
+ player_node->setAttributeEffective(skillId, level);
+ skillDialog->setModifiable(skillId, up);
}
- skillDialog->update();
break;
case SMSG_SKILL_FAILED:
// Action failed (ex. sit because you have not reached the
// right level)
- short skill = msg.readInt16();
+ skillId = msg.readInt16();
short bskill = msg.readInt16();
msg.readInt16(); // unknown
char success = msg.readInt8();
@@ -131,7 +139,7 @@ void SkillHandler::handleMessage(MessageIn &msg)
}
std::string msg;
- if (success == SKILL_FAILED && skill == SKILL_BASIC)
+ if (success == SKILL_FAILED && skillId == SKILL_BASIC)
{
switch (bskill)
{
@@ -196,7 +204,7 @@ void SkillHandler::handleMessage(MessageIn &msg)
}
else
{
- switch (skill)
+ switch (skillId)
{
case SKILL_WARP :
msg = _("Warp failed...");
@@ -215,28 +223,33 @@ void SkillHandler::handleMessage(MessageIn &msg)
}
}
-void SkillHandler::up(int skillId)
+void SpecialHandler::use(int id)
{
- if (player_node->mSkillPoint <= 0)
- return;
-
- MessageOut outMsg(CMSG_SKILL_LEVELUP_REQUEST);
- outMsg.writeInt16(skillId);
+ // TODO
}
-void SkillHandler::use(int skillId, int level, int beingId)
+void SpecialHandler::use(int id, int level, int beingId)
{
- // TODO
+ MessageOut outMsg(CMSG_SKILL_USE_BEING);
+ outMsg.writeInt16(level);
+ outMsg.writeInt16(id);
+ outMsg.writeInt16(beingId);
}
-void SkillHandler::use(int skillId, int level, int x, int y)
+void SpecialHandler::use(int id, int level, int x, int y)
{
- // TODO
+ MessageOut outMsg(CMSG_SKILL_USE_POSITION);
+ outMsg.writeInt16(level);
+ outMsg.writeInt16(id);
+ outMsg.writeInt16(x);
+ outMsg.writeInt16(y);
}
-void SkillHandler::use(int skillId, const std::string &map)
+void SpecialHandler::use(int id, const std::string &map)
{
- // TODO
+ MessageOut outMsg(CMSG_SKILL_USE_MAP);
+ outMsg.writeInt16(id);
+ outMsg.writeString(map, 16);
}
} // namespace EAthena
diff --git a/src/net/ea/skillhandler.h b/src/net/ea/specialhandler.h
index c1965213..eac53569 100644
--- a/src/net/ea/skillhandler.h
+++ b/src/net/ea/specialhandler.h
@@ -24,24 +24,24 @@
#include "net/messagehandler.h"
#include "net/net.h"
-#include "net/skillhandler.h"
+#include "net/specialhandler.h"
namespace EAthena {
-class SkillHandler : public MessageHandler, public Net::SkillHandler
+class SpecialHandler : public MessageHandler, public Net::SpecialHandler
{
public:
- SkillHandler();
+ SpecialHandler();
void handleMessage(MessageIn &msg);
- void up(int skillId);
+ void use(int id);
- void use(int skillId, int level, int beingId);
+ void use(int id, int level, int beingId);
- void use(int skillId, int level, int x, int y);
+ void use(int id, int level, int x, int y);
- void use(int skillId, const std::string &map);
+ void use(int id, const std::string &map);
};
} // namespace EAthena
diff --git a/src/net/net.cpp b/src/net/net.cpp
index a329af1a..7df336c6 100644
--- a/src/net/net.cpp
+++ b/src/net/net.cpp
@@ -33,7 +33,7 @@
#include "net/npchandler.h"
#include "net/partyhandler.h"
#include "net/playerhandler.h"
-#include "net/skillhandler.h"
+#include "net/specialhandler.h"
#include "net/tradehandler.h"
extern Net::AdminHandler *adminHandler;
@@ -47,7 +47,7 @@ extern Net::MapHandler *mapHandler;
extern Net::NpcHandler *npcHandler;
extern Net::PartyHandler *partyHandler;
extern Net::PlayerHandler *playerHandler;
-extern Net::SkillHandler *skillHandler;
+extern Net::SpecialHandler *specialHandler;
extern Net::TradeHandler *tradeHandler;
Net::AdminHandler *Net::getAdminHandler()
@@ -111,9 +111,9 @@ Net::PlayerHandler *Net::getPlayerHandler()
return playerHandler;
}
-Net::SkillHandler *Net::getSkillHandler()
+Net::SpecialHandler *Net::getSpecialHandler()
{
- return skillHandler;
+ return specialHandler;
}
Net::TradeHandler *Net::getTradeHandler()
diff --git a/src/net/net.h b/src/net/net.h
index 9154c1ef..1d91faa7 100644
--- a/src/net/net.h
+++ b/src/net/net.h
@@ -36,7 +36,7 @@ class MapHandler;
class NpcHandler;
class PartyHandler;
class PlayerHandler;
-class SkillHandler;
+class SpecialHandler;
class TradeHandler;
AdminHandler *getAdminHandler();
@@ -51,7 +51,7 @@ MapHandler *getMapHandler();
NpcHandler *getNpcHandler();
PartyHandler *getPartyHandler();
PlayerHandler *getPlayerHandler();
-SkillHandler *getSkillHandler();
+SpecialHandler *getSpecialHandler();
TradeHandler *getTradeHandler();
} // namespace Net
diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h
index 163b48f3..a0fd8bac 100644
--- a/src/net/playerhandler.h
+++ b/src/net/playerhandler.h
@@ -35,9 +35,11 @@ class PlayerHandler
virtual void emote(int emoteId) = 0;
- virtual void increaseStat(LocalPlayer::Attribute attr) = 0;
+ virtual void increaseAttribute(size_t attr) = 0;
- virtual void decreaseStat(LocalPlayer::Attribute attr) = 0;
+ virtual void decreaseAttribute(size_t attr) = 0;
+
+ virtual void increaseSkill(int skillId) = 0;
virtual void pickUp(FloorItem *floorItem) = 0;
@@ -52,6 +54,8 @@ class PlayerHandler
virtual void ignorePlayer(const std::string &player, bool ignore) = 0;
virtual void ignoreAll(bool ignore) = 0;
+
+ virtual bool canUseMagic() = 0;
};
} // namespace Net
diff --git a/src/net/skillhandler.h b/src/net/specialhandler.h
index 9db6ac5b..602003aa 100644
--- a/src/net/skillhandler.h
+++ b/src/net/specialhandler.h
@@ -19,23 +19,23 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef SKILLHANDLER_H
-#define SKILLHANDLER_H
+#ifndef SPECIALHANDLER_H
+#define SPECIALHANDLER_H
#include <iosfwd>
namespace Net {
-class SkillHandler
+class SpecialHandler
{
public:
- virtual void up(int skillId) = 0;
+ virtual void use(int id) = 0;
- virtual void use(int skillId, int level, int beingId) = 0;
+ virtual void use(int id, int level, int beingId) = 0;
- virtual void use(int skillId, int level, int x, int y) = 0;
+ virtual void use(int id, int level, int x, int y) = 0;
- virtual void use(int skillId, const std::string &map) = 0;
+ virtual void use(int id, const std::string &map) = 0;
};
}
-#endif // SKILLHANDLER_H
+#endif // SPECIALHANDLER_H
diff --git a/src/net/tmwserv/beinghandler.cpp b/src/net/tmwserv/beinghandler.cpp
index 7076ff8e..acd6b62c 100644
--- a/src/net/tmwserv/beinghandler.cpp
+++ b/src/net/tmwserv/beinghandler.cpp
@@ -187,28 +187,14 @@ void BeingHandler::handleBeingsMoveMessage(MessageIn &msg)
Being *being = beingManager->findBeing(id);
int sx = 0;
int sy = 0;
- int dx = 0;
- int dy = 0;
int speed = 0;
if (flags & MOVING_POSITION)
{
- Uint16 sx2, sy2;
- msg.readCoordinates(sx2, sy2);
- sx = sx2 * 32 + 16;
- sy = sy2 * 32 + 16;
+ sx = msg.readInt16();
+ sy = msg.readInt16();
speed = msg.readInt8();
}
- if (flags & MOVING_DESTINATION)
- {
- dx = msg.readInt16();
- dy = msg.readInt16();
- if (!(flags & MOVING_POSITION))
- {
- sx = dx;
- sy = dy;
- }
- }
if (!being || !(flags & (MOVING_POSITION | MOVING_DESTINATION)))
{
continue;
@@ -228,33 +214,9 @@ void BeingHandler::handleBeingsMoveMessage(MessageIn &msg)
if (being == player_node)
continue;
- // If being is a player, and he only moves a little, its ok to be a little out of sync
- if (being->getType() == Being::PLAYER && abs(being->getPixelX() - dx) +
- abs(being->getPixelY() - dy) < 16 &&
- (dx != being->getDestination().x &&
- dy != being->getDestination().y))
- {
- being->setDestination(being->getPixelX(),being->getPixelY());
- continue;
- }
- if (abs(being->getPixelX() - sx) +
- abs(being->getPixelY() - sy) > 10 * 32)
- {
- // Too large a desynchronization.
- being->setPosition(sx, sy);
- being->setDestination(dx, dy);
- }
- else if (!(flags & MOVING_POSITION))
- {
- being->setDestination(dx, dy);
- }
- else if (!(flags & MOVING_DESTINATION))
- {
- being->adjustCourse(sx, sy);
- }
- else
+ if (flags & MOVING_POSITION)
{
- being->setDestination(sx, sy, dx, dy);
+ being->setDestination(sx, sy);
}
}
}
@@ -306,23 +268,27 @@ void BeingHandler::handleBeingActionChangeMessage(MessageIn &msg)
static char const *const deadMsg[] =
{
_("You are dead."),
- _("We regret to inform you that your character was killed in battle."),
+ _("We regret to inform you that your character was killed in "
+ "battle."),
_("You are not that alive anymore."),
_("The cold hands of the grim reaper are grabbing for your soul."),
_("Game Over!"),
- _("No, kids. Your character did not really die. It... err... went to a better place."),
- _("Your plan of breaking your enemies weapon by bashing it with your throat failed."),
+ _("No, kids. Your character did not really die. It... err... "
+ "went to a better place."),
+ _("Your plan of breaking your enemies weapon by bashing it with "
+ "your throat failed."),
_("I guess this did not run too well."),
_("Do you want your possessions identified?"), // Nethack reference
_("Sadly, no trace of you was ever found..."), // Secret of Mana reference
_("Annihilated."), // Final Fantasy VI reference
- _("Looks like you got your head handed to you."), //Earthbound reference
- _("You screwed up again, dump your body down the tubes and get you another one.") // Leisure Suit Larry 1 Reference
+ _("Looks like you got your head handed to you."), // Earthbound reference
+ _("You screwed up again, dump your body down the tubes and get "
+ "you another one.") // Leisure Suit Larry 1 Reference
};
std::string message(deadMsg[rand()%13]);
- message.append(_(" Press OK to respawn"));
- OkDialog *dlg = new OkDialog(_("You died"), message);
+ message.append(std::string(" ") + _("Press OK to respawn."));
+ OkDialog *dlg = new OkDialog(_("You Died"), message);
dlg->addActionListener(&(Net::GameServer::Player::respawnListener));
}
}
diff --git a/src/net/tmwserv/charserverhandler.cpp b/src/net/tmwserv/charserverhandler.cpp
index 7b74904f..0146babb 100644
--- a/src/net/tmwserv/charserverhandler.cpp
+++ b/src/net/tmwserv/charserverhandler.cpp
@@ -81,25 +81,25 @@ void CharServerHandler::handleMessage(MessageIn &msg)
delete mCharInfo->getEntry();
mCharInfo->setEntry(0);
mCharInfo->unlock();
- new OkDialog("Info", "Player deleted");
+ new OkDialog(_("Info"), _("Player deleted."));
}
// Character deletion failed
else
{
- std::string message = "";
+ std::string errorMessage = "";
switch (errMsg)
{
case ERRMSG_NO_LOGIN:
- message = "Not logged in";
+ errorMessage = _("Not logged in.");
break;
case ERRMSG_INVALID_ARGUMENT:
- message = "Selection out of range";
+ errorMessage = _("Selection out of range.");
break;
default:
- message = "Unknown error";
+ errorMessage = _("Unknown error.");
}
mCharInfo->unlock();
- new OkDialog("Error", message);
+ new OkDialog(_("Error"), errorMessage);
}
}
break;
@@ -131,44 +131,44 @@ void CharServerHandler::handleCharCreateResponse(MessageIn &msg)
// Character creation failed
if (errMsg != ERRMSG_OK)
{
- std::string message = "";
+ std::string errorMessage = "";
switch (errMsg)
{
case ERRMSG_NO_LOGIN:
- message = "Not logged in";
+ errorMessage = _("Not logged in.");
break;
case CREATE_TOO_MUCH_CHARACTERS:
- message = "No empty slot";
+ errorMessage = _("No empty slot.");
break;
case ERRMSG_INVALID_ARGUMENT:
- message = "Invalid name";
+ errorMessage = _("Invalid name.");
break;
case CREATE_EXISTS_NAME:
- message = "Character's name already exists";
+ errorMessage = _("Character's name already exists.");
break;
case CREATE_INVALID_HAIRSTYLE:
- message = "Invalid hairstyle";
+ errorMessage = _("Invalid hairstyle.");
break;
case CREATE_INVALID_HAIRCOLOR:
- message = "Invalid hair color";
+ errorMessage = _("Invalid hair color.");
break;
case CREATE_INVALID_GENDER:
- message = "Invalid gender";
+ errorMessage = _("Invalid gender.");
break;
case CREATE_RAW_STATS_TOO_HIGH:
- message = "Character's stats are too high";
+ errorMessage = _("Character's stats are too high.");
break;
case CREATE_RAW_STATS_TOO_LOW:
- message = "Character's stats are too low";
+ errorMessage = _("Character's stats are too low.");
break;
case CREATE_RAW_STATS_EQUAL_TO_ZERO:
- message = "One stat is zero";
+ errorMessage = _("One stat is zero.");
break;
default:
- message = "Unknown error";
+ errorMessage = _("Unknown error.");
break;
}
- new OkDialog("Error", message);
+ new OkDialog(_("Error"), errorMessage);
}
if (mCharCreateDialog)
diff --git a/src/net/tmwserv/chathandler.cpp b/src/net/tmwserv/chathandler.cpp
index e2d09534..ad3ae49b 100644
--- a/src/net/tmwserv/chathandler.cpp
+++ b/src/net/tmwserv/chathandler.cpp
@@ -159,7 +159,7 @@ void ChatHandler::handleEnterChannelResponse(MessageIn &msg)
std::string user;
std::string userModes;
- tab->chatLog("Players in this channel:", BY_CHANNEL);
+ tab->chatLog(_("Players in this channel:"), BY_CHANNEL);
while(msg.getUnreadLength())
{
user = msg.readString();
@@ -176,13 +176,13 @@ void ChatHandler::handleEnterChannelResponse(MessageIn &msg)
}
else
{
- localChatTab->chatLog("Error joining channel.", BY_SERVER);
+ localChatTab->chatLog(_("Error joining channel."), BY_SERVER);
}
}
void ChatHandler::handleListChannelsResponse(MessageIn &msg)
{
- localChatTab->chatLog("Listing channels", BY_SERVER);
+ localChatTab->chatLog(_("Listing channels."), BY_SERVER);
while(msg.getUnreadLength())
{
std::string channelName = msg.readString();
@@ -194,7 +194,7 @@ void ChatHandler::handleListChannelsResponse(MessageIn &msg)
channelName += numUsers.str();
localChatTab->chatLog(channelName, BY_SERVER);
}
- localChatTab->chatLog("End of channel list.", BY_SERVER);
+ localChatTab->chatLog(_("End of channel list."), BY_SERVER);
}
void ChatHandler::handlePrivateMessage(MessageIn &msg)
@@ -237,7 +237,7 @@ void ChatHandler::handleListChannelUsersResponse(MessageIn &msg)
std::string userNick;
std::string userModes;
Channel *channel = channelManager->findByName(channelName);
- channel->getTab()->chatLog("Players in this channel:", BY_CHANNEL);
+ channel->getTab()->chatLog(_("Players in this channel:"), BY_CHANNEL);
while(msg.getUnreadLength())
{
userNick = msg.readString();
@@ -266,15 +266,18 @@ void ChatHandler::handleChannelEvent(MessageIn &msg)
switch(eventId)
{
case CHAT_EVENT_NEW_PLAYER:
- line += " entered the channel.";
+ channel->getTab()->chatLog(strprintf(_("%s entered the "
+ "channel."), line.c_str()), BY_CHANNEL);
break;
case CHAT_EVENT_LEAVING_PLAYER:
- line += " left the channel.";
+ channel->getTab()->chatLog(strprintf(_("%s left the channel."),
+ line.c_str()), BY_CHANNEL);
break;
case CHAT_EVENT_TOPIC_CHANGE:
- line = "Topic: " + line;
+ channel->getTab()->chatLog(strprintf(_("Topic: %s"),
+ line.c_str()), BY_CHANNEL);
break;
case CHAT_EVENT_MODE_CHANGE:
@@ -284,7 +287,9 @@ void ChatHandler::handleChannelEvent(MessageIn &msg)
std::string user1 = line.substr(0, first);
std::string user2 = line.substr(first+1, second);
std::string mode = line.substr(second+1, line.length());
- line = user1 + " has set mode " + mode + " on user " + user2;
+ channel->getTab()->chatLog(strprintf(_("%s has set mode %s "
+ "on user %s."), user1.c_str(), mode.c_str(),
+ user2.c_str()), BY_CHANNEL);
} break;
case CHAT_EVENT_KICKED_PLAYER:
@@ -292,14 +297,14 @@ void ChatHandler::handleChannelEvent(MessageIn &msg)
int first = line.find(":");
std::string user1 = line.substr(0, first);
std::string user2 = line.substr(first+1, line.length());
- line = user1 + " has kicked " + user2;
+ channel->getTab()->chatLog(strprintf(_("%s has kicked %s."),
+ user1, user2), BY_CHANNEL);
} break;
default:
- line = "Unknown channel event.";
+ channel->getTab()->chatLog(_("Unknown channel event."),
+ BY_CHANNEL);
}
-
- channel->getTab()->chatLog(line, BY_CHANNEL);
}
}
diff --git a/src/net/tmwserv/gameserver/player.cpp b/src/net/tmwserv/gameserver/player.cpp
index 93853681..4e63930b 100644
--- a/src/net/tmwserv/gameserver/player.cpp
+++ b/src/net/tmwserv/gameserver/player.cpp
@@ -41,14 +41,6 @@ void Net::GameServer::Player::walk(int x, int y)
Net::GameServer::connection->send(msg);
}
-void Net::GameServer::Player::pickUp(int x, int y)
-{
- MessageOut msg(PGMSG_PICKUP);
- msg.writeInt16(x);
- msg.writeInt16(y);
- Net::GameServer::connection->send(msg);
-}
-
void Net::GameServer::Player::moveItem(int oldSlot, int newSlot, int amount)
{
MessageOut msg(PGMSG_MOVE_ITEM);
@@ -58,47 +50,6 @@ void Net::GameServer::Player::moveItem(int oldSlot, int newSlot, int amount)
Net::GameServer::connection->send(msg);
}
-void Net::GameServer::Player::useSpecial(int special)
-{
- MessageOut msg(PGMSG_USE_SPECIAL);
- msg.writeInt8(special);
- Net::GameServer::connection->send(msg);
-}
-
-void Net::GameServer::Player::requestTrade(int id)
-{
- MessageOut msg(PGMSG_TRADE_REQUEST);
- msg.writeInt16(id);
- Net::GameServer::connection->send(msg);
-}
-
-void Net::GameServer::Player::acceptTrade(bool accept)
-{
- MessageOut msg(accept ? PGMSG_TRADE_REQUEST : PGMSG_TRADE_CANCEL);
- Net::GameServer::connection->send(msg);
-}
-
-void Net::GameServer::Player::tradeMoney(int amount)
-{
- MessageOut msg(PGMSG_TRADE_SET_MONEY);
- msg.writeInt32(amount);
- Net::GameServer::connection->send(msg);
-}
-
-void Net::GameServer::Player::raiseAttribute(int attribute)
-{
- MessageOut msg(PGMSG_RAISE_ATTRIBUTE);
- msg.writeInt8(attribute);
- Net::GameServer::connection->send(msg);
-}
-
-void Net::GameServer::Player::lowerAttribute(int attribute)
-{
- MessageOut msg(PGMSG_LOWER_ATTRIBUTE);
- msg.writeInt8(attribute);
- Net::GameServer::connection->send(msg);
-}
-
void Net::GameServer::Player::respawn()
{
MessageOut msg(PGMSG_RESPAWN);
diff --git a/src/net/tmwserv/gameserver/player.h b/src/net/tmwserv/gameserver/player.h
index 24b25dc7..9a202c6e 100644
--- a/src/net/tmwserv/gameserver/player.h
+++ b/src/net/tmwserv/gameserver/player.h
@@ -41,14 +41,7 @@ namespace Net
namespace Player
{
void walk(int x, int y);
- void pickUp(int x, int y);
void moveItem(int oldSlot, int newSlot, int amount);
- void useSpecial(int special);
- void requestTrade(int id);
- void acceptTrade(bool accept);
- void tradeMoney(int amount);
- void raiseAttribute(int attribute);
- void lowerAttribute(int attribute);
void respawn();
static RespawnRequestListener respawnListener;
}
diff --git a/src/net/tmwserv/generalhandler.cpp b/src/net/tmwserv/generalhandler.cpp
index 5886aafb..d643586b 100644
--- a/src/net/tmwserv/generalhandler.cpp
+++ b/src/net/tmwserv/generalhandler.cpp
@@ -21,6 +21,8 @@
#include "gui/inventorywindow.h"
#include "gui/partywindow.h"
+#include "gui/skilldialog.h"
+#include "gui/statuswindow.h"
#include "net/tmwserv/generalhandler.h"
@@ -146,6 +148,16 @@ void GeneralHandler::guiWindowsLoaded()
{
inventoryWindow->setSplitAllowed(true);
partyWindow->clearPartyName();
+ skillDialog->loadSkills("tmw-skills.xml");
+
+ player_node->setExpNeeded(100);
+
+ statusWindow->addAttribute(16, _("Strength"), true);
+ statusWindow->addAttribute(17, _("Agility"), true);
+ statusWindow->addAttribute(18, _("Dexterity"), true);
+ statusWindow->addAttribute(19, _("Vitality"), true);
+ statusWindow->addAttribute(20, _("Intelligence"), true);
+ statusWindow->addAttribute(21, _("Willpower"), true);
}
void GeneralHandler::guiWindowsUnloaded()
diff --git a/src/net/tmwserv/loginhandler.cpp b/src/net/tmwserv/loginhandler.cpp
index 35739669..f728d831 100644
--- a/src/net/tmwserv/loginhandler.cpp
+++ b/src/net/tmwserv/loginhandler.cpp
@@ -77,16 +77,16 @@ void LoginHandler::handleMessage(MessageIn &msg)
{
switch (errMsg) {
case ERRMSG_INVALID_ARGUMENT:
- errorMessage = _("Wrong magic_token");
+ errorMessage = _("Wrong magic_token.");
break;
case ERRMSG_FAILURE:
- errorMessage = _("Already logged in");
+ errorMessage = _("Already logged in.");
break;
case LOGIN_SERVER_FULL:
- errorMessage = _("Server is full");
+ errorMessage = _("Server is full.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_ERROR;
@@ -107,16 +107,16 @@ void LoginHandler::handleMessage(MessageIn &msg)
{
switch (errMsg) {
case ERRMSG_INVALID_ARGUMENT:
- errorMessage = _("New password incorrect");
+ errorMessage = _("New password incorrect.");
break;
case ERRMSG_FAILURE:
- errorMessage = _("Old password incorrect");
+ errorMessage = _("Old password incorrect.");
break;
case ERRMSG_NO_LOGIN:
errorMessage = _("Account not connected. Please login first.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_ACCOUNTCHANGE_ERROR;
@@ -137,19 +137,19 @@ void LoginHandler::handleMessage(MessageIn &msg)
{
switch (errMsg) {
case ERRMSG_INVALID_ARGUMENT:
- errorMessage = _("New email address incorrect");
+ errorMessage = _("New email address incorrect.");
break;
case ERRMSG_FAILURE:
- errorMessage = _("Old email address incorrect");
+ errorMessage = _("Old email address incorrect.");
break;
case ERRMSG_NO_LOGIN:
errorMessage = _("Account not connected. Please login first.");
break;
case ERRMSG_EMAIL_ALREADY_EXISTS:
- errorMessage = _("The new Email Address already exists.");
+ errorMessage = _("The new email address already exists.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_ACCOUNTCHANGE_ERROR;
@@ -173,19 +173,19 @@ void LoginHandler::handleLoginResponse(MessageIn &msg)
{
switch (errMsg) {
case LOGIN_INVALID_VERSION:
- errorMessage = _("Client version is too old");
+ errorMessage = _("Client version is too old.");
break;
case ERRMSG_INVALID_ARGUMENT:
- errorMessage = _("Wrong username or password");
+ errorMessage = _("Wrong username or password.");
break;
case ERRMSG_FAILURE:
- errorMessage = _("Already logged in");
+ errorMessage = _("Already logged in.");
break;
case LOGIN_SERVER_FULL:
- errorMessage = _("Server is full");
+ errorMessage = _("Server is full.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_LOGIN_ERROR;
@@ -205,19 +205,19 @@ void LoginHandler::handleRegisterResponse(MessageIn &msg)
{
switch (errMsg) {
case REGISTER_INVALID_VERSION:
- errorMessage = _("Client version is too old");
+ errorMessage = _("Client version is too old.");
break;
case ERRMSG_INVALID_ARGUMENT:
- errorMessage = _("Wrong username, password or email address");
+ errorMessage = _("Wrong username, password or email address.");
break;
case REGISTER_EXISTS_USERNAME:
- errorMessage = _("Username already exists");
+ errorMessage = _("Username already exists.");
break;
case REGISTER_EXISTS_EMAIL:
- errorMessage = _("Email address already exists");
+ errorMessage = _("Email address already exists.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_LOGIN_ERROR;
diff --git a/src/net/tmwserv/partyhandler.cpp b/src/net/tmwserv/partyhandler.cpp
index 557a3a43..2af0e4cb 100644
--- a/src/net/tmwserv/partyhandler.cpp
+++ b/src/net/tmwserv/partyhandler.cpp
@@ -100,8 +100,8 @@ void PartyHandler::handleMessage(MessageIn &msg)
int id = msg.readInt16(); // being id
std::string name = msg.readString();
- localChatTab->chatLog(strprintf(_("%s joined the "
- "party."), name.c_str()));
+ localChatTab->chatLog(strprintf(_("%s joined the party.",
+ name.c_str()));
if (!player_node->isInParty())
player_node->setInParty(true);
@@ -117,7 +117,8 @@ void PartyHandler::handleMessage(MessageIn &msg)
case CPMSG_PARTY_REJECTED:
{
std::string name = msg.readString();
- localChatTab->chatLog(name + "rejected your invite.");
+ localChatTab->chatLog(strprintf(_("%s rejected your invite."),
+ name.c_str()));
} break;
}
}
diff --git a/src/net/tmwserv/playerhandler.cpp b/src/net/tmwserv/playerhandler.cpp
index bbc73b7c..ce1990ed 100644
--- a/src/net/tmwserv/playerhandler.cpp
+++ b/src/net/tmwserv/playerhandler.cpp
@@ -43,7 +43,6 @@
#include "gui/gui.h"
#include "gui/okdialog.h"
#include "gui/sell.h"
-#include "gui/skill.h"
#include "gui/viewport.h"
// TODO Move somewhere else
@@ -134,7 +133,7 @@ void PlayerHandler::handleMessage(MessageIn &msg)
logger->log("ATTRIBUTE UPDATE:");
while (msg.getUnreadLength())
{
- int stat = msg.readInt8();
+ int stat = msg.readInt16();
int base = msg.readInt16();
int value = msg.readInt16();
logger->log("%d set to %d %d", stat, base, value);
@@ -144,24 +143,11 @@ void PlayerHandler::handleMessage(MessageIn &msg)
player_node->setMaxHp(base);
player_node->setHp(value);
}
- else if (stat < NB_CHARACTER_ATTRIBUTES)
+ else
{
- if (stat >= CHAR_SKILL_BEGIN && stat < CHAR_SKILL_END
- && player_node->getAttributeBase(stat) < base
- && player_node->getAttributeBase(stat) > -1)
- {
- Particle* effect = particleEngine->addEffect("graphics/particles/skillup.particle.xml", 0, 0);
- player_node->controlParticle(effect);
- }
-
player_node->setAttributeBase(stat, base);
player_node->setAttributeEffective(stat, value);
}
- else
- {
- logger->log("Warning: server wants to update unknown "
- "attribute %d to %d", stat, value);
- }
}
} break;
@@ -174,15 +160,7 @@ void PlayerHandler::handleMessage(MessageIn &msg)
int current = msg.readInt32();
int next = msg.readInt32();
- if (skill < CHAR_SKILL_NB)
- {
- player_node->setExperience(skill, current, next);
- }
- else
- {
- logger->log("Warning: server wants to update experience of unknown "
- "skill %d to %d / %d", skill, current, next);
- }
+ player_node->setExperience(skill, current, next);
}
} break;
@@ -199,7 +177,7 @@ void PlayerHandler::handleMessage(MessageIn &msg)
case GPMSG_LEVEL_PROGRESS:
{
logger->log("Level Progress Update");
- player_node->setLevelProgress(msg.readInt8());
+ player_node->setExp(msg.readInt8());
} break;
@@ -358,20 +336,32 @@ void PlayerHandler::emote(int emoteId)
// TODO
}
-void PlayerHandler::increaseStat(LocalPlayer::Attribute attr)
+void PlayerHandler::increaseAttribute(size_t attr)
{
- // TODO
+ MessageOut msg(PGMSG_RAISE_ATTRIBUTE);
+ msg.writeInt8(attr);
+ Net::GameServer::connection->send(msg);
}
-void PlayerHandler::decreaseStat(LocalPlayer::Attribute attr)
+void PlayerHandler::decreaseAttribute(size_t attr)
{
- // TODO
+ MessageOut msg(PGMSG_LOWER_ATTRIBUTE);
+ msg.writeInt8(attr);
+ Net::GameServer::connection->send(msg);
+}
+
+void PlayerHandler::increaseSkill(int skillId)
+{
+ // Not used atm
}
void PlayerHandler::pickUp(FloorItem *floorItem)
{
int id = floorItem->getId();
- Net::GameServer::Player::pickUp(id >> 16, id & 0xFFFF);
+ MessageOut msg(PGMSG_PICKUP);
+ msg.writeInt16(id >> 16);
+ msg.writeInt16(id & 0xFFFF);
+ Net::GameServer::connection->send(msg);
}
void PlayerHandler::setDirection(char direction)
@@ -414,4 +404,9 @@ void PlayerHandler::ignoreAll(bool ignore)
// TODO
}
+bool PlayerHandler::canUseMagic()
+{
+ return true;
+}
+
} // namespace TmwServ
diff --git a/src/net/tmwserv/playerhandler.h b/src/net/tmwserv/playerhandler.h
index 164d30ae..287baa3d 100644
--- a/src/net/tmwserv/playerhandler.h
+++ b/src/net/tmwserv/playerhandler.h
@@ -38,9 +38,11 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
void emote(int emoteId);
- void increaseStat(LocalPlayer::Attribute attr);
+ void increaseAttribute(size_t attr);
- void decreaseStat(LocalPlayer::Attribute attr);
+ void decreaseAttribute(size_t attr);
+
+ void increaseSkill(int skillId);
void pickUp(FloorItem *floorItem);
@@ -56,6 +58,8 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
void ignoreAll(bool ignore);
+ bool canUseMagic();
+
private:
void handleMapChangeMessage(MessageIn &msg);
};
diff --git a/src/net/tmwserv/protocol.h b/src/net/tmwserv/protocol.h
index 2f1ea885..60a50d89 100644
--- a/src/net/tmwserv/protocol.h
+++ b/src/net/tmwserv/protocol.h
@@ -83,7 +83,7 @@ enum {
PGMSG_MOVE_ITEM = 0x0114, // B slot1, B slot2, B amount
GPMSG_INVENTORY = 0x0120, // { B slot, W item id [, B amount] }*
GPMSG_INVENTORY_FULL = 0x0121, // { B slot, W item id [, B amount] }*
- GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { B attribute, W base value, W modified value }*
+ GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { W attribute, W base value, W modified value }*
GPMSG_PLAYER_EXP_CHANGE = 0x0140, // { W skill, D exp got, D exp needed }*
GPMSG_LEVELUP = 0x0150, // W new level
GPMSG_LEVEL_PROGRESS = 0x0151, // B percent completed to next levelup
@@ -104,7 +104,7 @@ enum {
GPMSG_BEING_ACTION_CHANGE = 0x0271, // W being id, B action
PGMSG_DIRECTION_CHANGE = 0x0272, // B Direction
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_BEINGS_MOVE = 0x0280, // { W being id, B flags [, W*2 position, B speed] }*
GPMSG_ITEMS = 0x0281, // { W item id, W*2 position }*
PGMSG_ATTACK = 0x0290, // W being id
GPMSG_BEING_ATTACK = 0x0291, // W being id
diff --git a/src/net/tmwserv/skillhandler.cpp b/src/net/tmwserv/specialhandler.cpp
index e35b896a..f259e77a 100644
--- a/src/net/tmwserv/skillhandler.cpp
+++ b/src/net/tmwserv/specialhandler.cpp
@@ -19,33 +19,42 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "net/tmwserv/skillhandler.h"
+#include "net/tmwserv/specialhandler.h"
-Net::SkillHandler *skillHandler;
+#include "net/tmwserv/gameserver/internal.h"
+
+#include "net/tmwserv/connection.h"
+#include "net/tmwserv/protocol.h"
+
+#include "net/messageout.h"
+
+Net::SpecialHandler *specialHandler;
namespace TmwServ {
-SkillHandler::SkillHandler()
+SpecialHandler::SpecialHandler()
{
- skillHandler = this;
+ specialHandler = this;
}
-void SkillHandler::up(int skillId)
+void SpecialHandler::use(int id)
{
- // TODO
+ MessageOut msg(PGMSG_USE_SPECIAL);
+ msg.writeInt8(id);
+ Net::GameServer::connection->send(msg);
}
-void SkillHandler::use(int skillId, int level, int beingId)
+void SpecialHandler::use(int id, int level, int beingId)
{
// TODO
}
-void SkillHandler::use(int skillId, int level, int x, int y)
+void SpecialHandler::use(int id, int level, int x, int y)
{
// TODO
}
-void SkillHandler::use(int skillId, const std::string &map)
+void SpecialHandler::use(int id, const std::string &map)
{
// TODO
}
diff --git a/src/net/tmwserv/skillhandler.h b/src/net/tmwserv/specialhandler.h
index 8c459c4f..c7ebd6a2 100644
--- a/src/net/tmwserv/skillhandler.h
+++ b/src/net/tmwserv/specialhandler.h
@@ -22,22 +22,22 @@
#ifndef NET_TMWSERV_SKILLHANDLER_H
#define NET_TMWSERV_SKILLHANDLER_H
-#include "net/skillhandler.h"
+#include "net/specialhandler.h"
namespace TmwServ {
-class SkillHandler : public Net::SkillHandler
+class SpecialHandler : public Net::SpecialHandler
{
public:
- SkillHandler();
+ SpecialHandler();
- void up(int skillId);
+ void use(int id);
- void use(int skillId, int level, int beingId);
+ void use(int id, int level, int beingId);
- void use(int skillId, int level, int x, int y);
+ void use(int id, int level, int x, int y);
- void use(int skillId, const std::string &map);
+ void use(int id, const std::string &map);
};
} // namespace TmwServ
diff --git a/src/net/tmwserv/tradehandler.cpp b/src/net/tmwserv/tradehandler.cpp
index aabd8b2a..55a00d4c 100644
--- a/src/net/tmwserv/tradehandler.cpp
+++ b/src/net/tmwserv/tradehandler.cpp
@@ -55,7 +55,11 @@ namespace {
void action(const gcn::ActionEvent &event)
{
if (event.getId() == "yes")
- Net::GameServer::Player::requestTrade(tradePartnerID);
+ {
+ MessageOut msg(PGMSG_TRADE_REQUEST);
+ msg.writeInt16(tradePartnerID);
+ Net::GameServer::connection->send(msg);
+ }
else
Net::getTradeHandler()->cancel();
}
@@ -105,7 +109,7 @@ void TradeHandler::handleMessage(MessageIn &msg)
Being *being = beingManager->findBeing(msg.readInt16());
if (!being || !mAcceptTradeRequests)
{
- Net::GameServer::Player::acceptTrade(false);
+ respond(false);
break;
}
player_node->setTrading(true);
@@ -171,7 +175,9 @@ void TradeHandler::request(Being *being)
void TradeHandler::respond(bool accept)
{
- // TODO
+ MessageOut msg(accept ? PGMSG_TRADE_REQUEST : PGMSG_TRADE_CANCEL);
+ Net::GameServer::connection->send(msg);
+
if (!accept)
player_node->setTrading(false);
}
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp
index b9d837ad..4d66a919 100644
--- a/src/openglgraphics.cpp
+++ b/src/openglgraphics.cpp
@@ -140,6 +140,42 @@ static inline void drawQuad(Image *image,
}
}
+static inline void drawRescaledQuad(Image *image,
+ int srcX, int srcY, int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight)
+{
+ if (image->getTextureType() == GL_TEXTURE_2D)
+ {
+ // Find OpenGL normalized texture coordinates.
+ float texX1 = srcX / (float) image->getTextureWidth();
+ float texY1 = srcY / (float) image->getTextureHeight();
+ float texX2 = (srcX + width) / (float) image->getTextureWidth();
+ float texY2 = (srcY + height) / (float) image->getTextureHeight();
+
+ glTexCoord2f(texX1, texY1);
+ glVertex2i(dstX, dstY);
+ glTexCoord2f(texX2, texY1);
+ glVertex2i(dstX + desiredWidth, dstY);
+ glTexCoord2f(texX2, texY2);
+ glVertex2i(dstX + desiredWidth, dstY + desiredHeight);
+ glTexCoord2f(texX1, texY2);
+ glVertex2i(dstX, dstY + desiredHeight);
+ }
+ else
+ {
+ glTexCoord2i(srcX, srcY);
+ glVertex2i(dstX, dstY);
+ glTexCoord2i(srcX + width, srcY);
+ glVertex2i(dstX + desiredWidth, dstY);
+ glTexCoord2i(srcX + width, srcY + height);
+ glVertex2i(dstX + desiredWidth, dstY + desiredHeight);
+ glTexCoord2i(srcX, srcY + height);
+ glVertex2i(dstX, dstY + desiredHeight);
+ }
+}
+
+
bool OpenGLGraphics::drawImage(Image *image, int srcX, int srcY,
int dstX, int dstY,
int width, int height, bool useColor)
@@ -168,6 +204,37 @@ bool OpenGLGraphics::drawImage(Image *image, int srcX, int srcY,
return true;
}
+bool OpenGLGraphics::drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor)
+{
+ if (!image)
+ return false;
+
+ srcX += image->mBounds.x;
+ srcY += image->mBounds.y;
+
+ if (!useColor)
+ glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha);
+
+ glBindTexture(Image::mTextureType, image->mGLImage);
+
+ setTexturingAndBlending(true);
+
+ // Draw a textured quad.
+ glBegin(GL_QUADS);
+ drawRescaledQuad(image, srcX, srcY, dstX, dstY, width, height,
+ desiredWidth, desiredHeight);
+ glEnd();
+
+ if (!useColor)
+ glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a);
+
+ return true;
+}
+
/* Optimising the functions that Graphics::drawImagePattern would call,
* so that glBegin...glEnd are outside the main loop. */
void OpenGLGraphics::drawImagePattern(Image *image, int x, int y, int w, int h)
@@ -210,6 +277,49 @@ void OpenGLGraphics::drawImagePattern(Image *image, int x, int y, int w, int h)
glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a);
}
+void OpenGLGraphics::drawRescaledImagePattern(Image *image, int x, int y,
+ int w, int h,
+ int scaledWidth, int scaledHeight)
+{
+ if (!image)
+ return;
+
+ const int srcX = image->mBounds.x;
+ const int srcY = image->mBounds.y;
+
+ const int iw = scaledWidth;
+ const int ih = scaledHeight;
+ if (iw == 0 || ih == 0)
+ return;
+
+ glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha);
+
+ glBindTexture(Image::mTextureType, image->mGLImage);
+
+ setTexturingAndBlending(true);
+
+ // Draw a set of textured rectangles
+ glBegin(GL_QUADS);
+
+ for (int py = 0; py < h; py += ih)
+ {
+ const int height = (py + ih >= h) ? h - py : ih;
+ const int dstY = y + py;
+ for (int px = 0; px < w; px += iw)
+ {
+ int width = (px + iw >= w) ? w - px : iw;
+ int dstX = x + px;
+
+ drawRescaledQuad(image, srcX, srcY, dstX, dstY,
+ width, height, scaledWidth, scaledHeight);
+ }
+ }
+
+ glEnd();
+
+ glColor4ub(mColor.r, mColor.g, mColor.b, mColor.a);
+}
+
void OpenGLGraphics::updateScreen()
{
glFlush();
diff --git a/src/openglgraphics.h b/src/openglgraphics.h
index dc748804..0bee48b4 100644
--- a/src/openglgraphics.h
+++ b/src/openglgraphics.h
@@ -46,10 +46,26 @@ class OpenGLGraphics : public Graphics
int width, int height,
bool useColor);
+ /**
+ * Draws a resclaled version of the image
+ */
+ bool drawRescaledImage(Image *image, int srcX, int srcY,
+ int dstX, int dstY,
+ int width, int height,
+ int desiredWidth, int desiredHeight,
+ bool useColor);
+
void drawImagePattern(Image *image,
int x, int y,
int w, int h);
+ /**
+ * Draw a pattern based on a rescaled version of the given image...
+ */
+ void drawRescaledImagePattern(Image *image,
+ int x, int y, int w, int h,
+ int scaledWidth, int scaledHeight);
+
void updateScreen();
void _beginDraw();
diff --git a/src/player.cpp b/src/player.cpp
index 3b2271bd..fd7cd0d6 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -255,21 +255,6 @@ void Player::updateCoords()
}
#ifdef TMWSERV_SUPPORT
-
-Path Player::findPath()
-{
- Path path;
-
- if (mMap)
- {
- path = mMap->findSimplePath(getPosition().x / 32, getPosition().y / 32,
- getDestination().x / 32, getDestination().y / 32,
- getWalkMask());
- }
-
- return path;
-}
-
Guild* Player::addGuild(short guildId, short rights)
{
Guild *guild = new Guild(guildId, rights);
diff --git a/src/player.h b/src/player.h
index cfd305a6..9a5c6c94 100644
--- a/src/player.h
+++ b/src/player.h
@@ -93,11 +93,6 @@ class Player : public Being
#ifdef TMWSERV_SUPPORT
/**
- * Returns the path to the player's current destination
- */
- Path findPath();
-
- /**
* Adds a guild to the player.
*/
Guild *addGuild(short guildId, short rights);
diff --git a/src/playerrelations.cpp b/src/playerrelations.cpp
index 316bd9ed..7bc1b14d 100644
--- a/src/playerrelations.cpp
+++ b/src/playerrelations.cpp
@@ -29,6 +29,7 @@
#include "playerrelations.h"
#include "utils/dtor.h"
+#include "utils/gettext.h"
#define PLAYER_IGNORE_STRATEGY_NOP "nop"
#define PLAYER_IGNORE_STRATEGY_EMOTE0 "emote0"
@@ -292,7 +293,7 @@ class PIS_nothing : public PlayerIgnoreStrategy
public:
PIS_nothing()
{
- mDescription = "completely ignore";
+ mDescription = _("Completely ignore");
mShortName = PLAYER_IGNORE_STRATEGY_NOP;
}
@@ -306,7 +307,7 @@ class PIS_dotdotdot : public PlayerIgnoreStrategy
public:
PIS_dotdotdot()
{
- mDescription = "print '...'";
+ mDescription = _("Print '...'");
mShortName = "dotdotdot";
}
@@ -322,7 +323,7 @@ class PIS_blinkname : public PlayerIgnoreStrategy
public:
PIS_blinkname()
{
- mDescription = "blink name";
+ mDescription = _("Blink name");
mShortName = "blinkname";
}
@@ -359,10 +360,10 @@ PlayerRelationsManager::getPlayerIgnoreStrategies()
{
// not initialised yet?
mIgnoreStrategies.push_back(new PIS_emote(FIRST_IGNORE_EMOTE,
- "floating '...' bubble",
+ _("Floating '...' bubble"),
PLAYER_IGNORE_STRATEGY_EMOTE0));
mIgnoreStrategies.push_back(new PIS_emote(FIRST_IGNORE_EMOTE + 1,
- "floating bubble",
+ _("Floating bubble"),
"emote1"));
mIgnoreStrategies.push_back(new PIS_nothing());
mIgnoreStrategies.push_back(new PIS_dotdotdot());
diff --git a/src/properties.h b/src/properties.h
index a2ce5b88..e7aab157 100644
--- a/src/properties.h
+++ b/src/properties.h
@@ -74,6 +74,28 @@ class Properties
}
/**
+ * Gets a map property as a boolean.
+ *
+ * @param name The name of the property.
+ * @param def Default value, false by default.
+ * @return the value of the given property, or false when it doesn't
+ * exist.
+ */
+ float getBoolProperty(const std::string &name, bool def = false) const
+ {
+ PropertyMap::const_iterator i = mProperties.find(name);
+ bool ret = def;
+ if (i != mProperties.end())
+ {
+ if (i->second == "true")
+ ret = true;
+ if (i->second == "false")
+ ret = false;
+ }
+ return ret;
+ }
+
+ /**
* Returns whether a certain property is available.
*
* @param name The name of the property.
diff --git a/src/resources/ambientoverlay.cpp b/src/resources/ambientoverlay.cpp
index 93c7c3e1..8c851e2e 100644
--- a/src/resources/ambientoverlay.cpp
+++ b/src/resources/ambientoverlay.cpp
@@ -22,16 +22,41 @@
#include "resources/ambientoverlay.h"
#include "resources/image.h"
-
+#include "resources/resourcemanager.h"
#include "graphics.h"
AmbientOverlay::AmbientOverlay(Image *img, float parallax,
- float speedX, float speedY):
+ float speedX, float speedY, bool keepRatio):
mImage(img), mParallax(parallax),
mPosX(0), mPosY(0),
- mSpeedX(speedX), mSpeedY(speedY)
+ mSpeedX(speedX), mSpeedY(speedY),
+ mKeepRatio(keepRatio)
{
- mImage->incRef();
+
+ if (keepRatio && !mImage->isAnOpenGLOne()
+ && defaultScreenWidth != 0
+ && defaultScreenHeight != 0
+ && graphics->getWidth() != defaultScreenWidth
+ && graphics->getHeight() != defaultScreenHeight)
+ {
+ // Rescale the overlay to keep the ratio as if we were on
+ // the default resolution...
+ Image *rescaledOverlay = mImage->SDLgetScaledImage(
+ (int) mImage->getWidth() / defaultScreenWidth * graphics->getWidth(),
+ (int) mImage->getHeight() / defaultScreenHeight * graphics->getHeight());
+
+ if (rescaledOverlay)
+ {
+ // Replace the resource with the new one...
+ std::string idPath = mImage->getIdPath() + "_rescaled";
+ ResourceManager::getInstance()->addResource(idPath, rescaledOverlay);
+ mImage = rescaledOverlay;
+ }
+ else
+ mImage->incRef();
+ }
+ else
+ mImage->incRef();
}
AmbientOverlay::~AmbientOverlay()
@@ -66,6 +91,13 @@ void AmbientOverlay::update(int timePassed, float dx, float dy)
void AmbientOverlay::draw(Graphics *graphics, int x, int y)
{
- graphics->drawImagePattern(mImage,
+ if (!mImage->isAnOpenGLOne() || !mKeepRatio)
+ graphics->drawImagePattern(mImage,
(int) -mPosX, (int) -mPosY, x + (int) mPosX, y + (int) mPosY);
+ else
+ graphics->drawRescaledImagePattern(mImage,
+ (int) -mPosX, (int) -mPosY, x + (int) mPosX, y + (int) mPosY,
+ (int) mImage->getWidth() / defaultScreenWidth * graphics->getWidth(),
+ (int) mImage->getHeight() / defaultScreenHeight * graphics->getHeight());
+
}
diff --git a/src/resources/ambientoverlay.h b/src/resources/ambientoverlay.h
index 756d0eb7..f2d2e588 100644
--- a/src/resources/ambientoverlay.h
+++ b/src/resources/ambientoverlay.h
@@ -35,9 +35,11 @@ class AmbientOverlay
* @param parallax scroll factor based on camera position
* @param speedX scrolling speed in x-direction
* @param speedY scrolling speed in y-direction
+ * @param keepRatio rescale the image to keep
+ * the same ratio than in 800x600 resolution mode.
*/
AmbientOverlay(Image *img, float parallax,
- float speedX, float speedY);
+ float speedX, float speedY, bool keepRatio = false);
~AmbientOverlay();
@@ -52,6 +54,7 @@ class AmbientOverlay
float mPosY; /**< Current layer Y position. */
float mSpeedX; /**< Scrolling speed in X direction. */
float mSpeedY; /**< Scrolling speed in Y direction. */
+ bool mKeepRatio; /**< Keep overlay ratio on every resolution */
};
#endif
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index 0c542a8b..9af3059a 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -26,6 +26,7 @@
#include "log.h"
#include <SDL_image.h>
+#include "resources/sdlrescalefacility.h"
#ifdef USE_OPENGL
bool Image::mUseOpenGL = false;
@@ -289,16 +290,13 @@ void Image::unload()
#endif
}
-Image *Image::getSubImage(int x, int y, int width, int height)
+bool Image::isAnOpenGLOne() const
{
- // Create a new clipped sub-image
#ifdef USE_OPENGL
- if (mUseOpenGL)
- return new SubImage(this, mGLImage, x, y, width, height,
- mTexWidth, mTexHeight);
+ return mUseOpenGL;
+#else
+ return false;
#endif
-
- return new SubImage(this, mImage, x, y, width, height);
}
void Image::setAlpha(float a)
@@ -345,7 +343,7 @@ Image* Image::merge(Image *image, int x, int y)
cur_pix = ((Uint32*) mImage->pixels)[current_offset];
// Retreiving each channel of the pixel using pixel format
- r = (Uint8)(((surface_pix & surface_fmt->Rmask) >>
+ r = (Uint8)(((surface_pix & surface_fmt->Rmask) >>
surface_fmt->Rshift) << surface_fmt->Rloss);
g = (Uint8)(((surface_pix & surface_fmt->Gmask) >>
surface_fmt->Gshift) << surface_fmt->Gloss);
@@ -360,14 +358,14 @@ Image* Image::merge(Image *image, int x, int y)
// new pixel with no alpha or nothing on previous pixel
if (a == SDL_ALPHA_OPAQUE || (p_a == 0 && a > 0))
- ((Uint32 *)(surface->pixels))[current_offset] =
+ ((Uint32 *)(surface->pixels))[current_offset] =
SDL_MapRGBA(current_fmt, r, g, b, a);
- else if (a > 0)
+ else if (a > 0)
{ // alpha is lower => merge color with previous value
f_a = (double) a / 255.0;
f_ca = 1.0 - f_a;
f_pa = (double) p_a / 255.0;
- p_r = (Uint8)(((cur_pix & current_fmt->Rmask) >>
+ p_r = (Uint8)(((cur_pix & current_fmt->Rmask) >>
current_fmt->Rshift) << current_fmt->Rloss);
p_g = (Uint8)(((cur_pix & current_fmt->Gmask) >>
current_fmt->Gshift) << current_fmt->Gloss);
@@ -395,6 +393,34 @@ float Image::getAlpha() const
return mAlpha;
}
+Image* Image::SDLgetScaledImage(int width, int height)
+{
+ // No scaling on incorrect new values.
+ if (width == 0 || height == 0)
+ return NULL;
+
+ // No scaling when there is ... no different given size ...
+ if (width == getWidth() && height == getHeight())
+ return NULL;
+
+ Image* scaledImage = NULL;
+ SDL_Surface* scaledSurface = NULL;
+
+ if (mImage)
+ {
+ scaledSurface = _SDLzoomSurface(mImage,
+ (double) width / getWidth(),
+ (double) height / getHeight(),
+ 1);
+
+ // The load function takes of the SDL<->OpenGL implementation
+ // and about freeing the given SDL_surface*.
+ if (scaledSurface)
+ scaledImage = load(scaledSurface);
+ }
+ return scaledImage;
+}
+
#ifdef USE_OPENGL
void Image::setLoadAsOpenGL(bool useOpenGL)
{
@@ -420,6 +446,18 @@ int Image::powerOfTwo(int input)
}
#endif
+Image *Image::getSubImage(int x, int y, int width, int height)
+{
+ // Create a new clipped sub-image
+#ifdef USE_OPENGL
+ if (mUseOpenGL)
+ return new SubImage(this, mGLImage, x, y, width, height,
+ mTexWidth, mTexHeight);
+#endif
+
+ return new SubImage(this, mImage, x, y, width, height);
+}
+
//============================================================================
// SubImage Class
//============================================================================
@@ -469,4 +507,3 @@ Image *SubImage::getSubImage(int x, int y, int w, int h)
{
return mParent->getSubImage(mBounds.x + x, mBounds.y + y, w, h);
}
-
diff --git a/src/resources/image.h b/src/resources/image.h
index 4422fcc8..f497f608 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -88,6 +88,16 @@ 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.
*/
virtual void unload();
@@ -105,6 +115,12 @@ class Image : public Resource
{ return mBounds.h; }
/**
+ * Tells if the image was loade using OpenGL or SDL
+ * @return true if OpenGL, false if SDL.
+ */
+ bool isAnOpenGLOne() const;
+
+ /**
* Creates a new image with the desired clipping rectangle.
*
* @return <code>NULL</code> if creation failed and a valid
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index b25f754f..900e3547 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -153,7 +153,7 @@ void ItemDB::load()
ItemInfo *itemInfo = new ItemInfo;
itemInfo->setId(id);
itemInfo->setImageName(image);
- itemInfo->setName(name.empty() ? _("Unnamed") : name);
+ itemInfo->setName(name.empty() ? _("unnamed") : name);
itemInfo->setDescription(description);
itemInfo->setType(itemTypeFromString(typeStr));
itemInfo->setView(view);
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index 0b8d6c35..bc3267da 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -214,6 +214,19 @@ std::string ResourceManager::getPath(const std::string &file)
return path;
}
+bool ResourceManager::addResource(const std::string &idPath,
+ Resource* resource)
+{
+ if (resource)
+ {
+ resource->incRef();
+ resource->mIdPath = idPath;
+ mResources[idPath] = resource;
+ return true;
+ }
+ return false;
+}
+
Resource *ResourceManager::get(const std::string &idPath, generator fun,
void *data)
{
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index b2ad3069..88fd60fc 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -125,6 +125,15 @@ class ResourceManager
Resource *load(const std::string &path, loader fun);
/**
+ * Adds a preformatted resource to the resource map.
+ *
+ * @param path The file name.
+ * @param Resource The Resource to add.
+ * @return true if successfull, false otherwise.
+ */
+ bool addResource(const std::string &idPath, Resource* resource);
+
+ /**
* Copies a file from one place to another (useful for extracting
* raw files from a zip archive, for example)
*
diff --git a/src/resources/sdlrescalefacility.cpp b/src/resources/sdlrescalefacility.cpp
new file mode 100644
index 00000000..49ba8aa4
--- /dev/null
+++ b/src/resources/sdlrescalefacility.cpp
@@ -0,0 +1,489 @@
+/*
+ * 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 Low 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
+ *
+ * Source code taken from:
+ *
+ * SDL_rotozoom - rotozoomer
+ *
+ * LGPL (c) A. Schiffler
+ *
+ */
+
+#include "sdlrescalefacility.h"
+
+#define VALUE_LIMIT 0.001
+
+typedef struct tColorRGBA {
+ Uint8 r;
+ Uint8 g;
+ Uint8 b;
+ Uint8 a;
+} tColorRGBA;
+
+void zoomSurfaceSize(int width, int height, double zoomx, double zoomy,
+ int *dstwidth, int *dstheight)
+{
+ /*
+ * Sanity check zoom factors
+ */
+ if (zoomx < VALUE_LIMIT) {
+ zoomx = VALUE_LIMIT;
+ }
+ if (zoomy < VALUE_LIMIT) {
+ zoomy = VALUE_LIMIT;
+ }
+
+ /*
+ * Calculate target size
+ */
+ *dstwidth = (int) ((double) width * zoomx);
+ *dstheight = (int) ((double) height * zoomy);
+ if (*dstwidth < 1) {
+ *dstwidth = 1;
+ }
+ if (*dstheight < 1) {
+ *dstheight = 1;
+ }
+}
+
+int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface * dst,
+ int flipx, int flipy, int smooth)
+{
+ int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep, lx, ly;
+ tColorRGBA *c00, *c01, *c10, *c11, *cswap;
+ tColorRGBA *sp, *csp, *dp;
+ int dgap;
+
+ /*
+ * Variable setup
+ */
+ if (smooth) {
+ /*
+ * For interpolation: assume source dimension is one pixel
+ */
+ /*
+ * smaller to avoid overflow on right and bottom edge.
+ */
+ sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w);
+ sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h);
+ } else {
+ sx = (int) (65536.0 * (float) src->w / (float) dst->w);
+ sy = (int) (65536.0 * (float) src->h / (float) dst->h);
+ }
+
+ /*
+ * Allocate memory for row increments
+ */
+ if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
+ return (-1);
+ }
+ if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
+ free(sax);
+ return (-1);
+ }
+
+ /*
+ * Precalculate row increments
+ */
+ sp = csp = (tColorRGBA *) src->pixels;
+ dp = (tColorRGBA *) dst->pixels;
+
+ if (flipx) csp += (src->w-1);
+ if (flipy) csp += (src->pitch*(src->h-1));
+
+ csx = 0;
+ csax = sax;
+ for (x = 0; x <= dst->w; x++) {
+ *csax = csx;
+ csax++;
+ csx &= 0xffff;
+ csx += sx;
+ }
+ csy = 0;
+ csay = say;
+ for (y = 0; y <= dst->h; y++) {
+ *csay = csy;
+ csay++;
+ csy &= 0xffff;
+ csy += sy;
+ }
+
+ dgap = dst->pitch - dst->w * 4;
+
+ /*
+ * Switch between interpolating and non-interpolating code
+ */
+ if (smooth) {
+
+ /*
+ * Interpolating Zoom
+ */
+
+ /*
+ * Scan destination
+ */
+ ly = 0;
+ csay = say;
+ for (y = 0; y < dst->h; y++) {
+ /*
+ * Setup color source pointers
+ */
+ c00 = csp;
+ c01 = csp;
+ c01++;
+ c10 = (tColorRGBA *) ((Uint8 *) csp + src->pitch);
+ c11 = c10;
+ c11++;
+ csax = sax;
+ if (flipx) {
+ cswap = c00; c00=c01; c01=cswap;
+ cswap = c10; c10=c11; c11=cswap;
+ }
+ if (flipy) {
+ cswap = c00; c00=c10; c10=cswap;
+ cswap = c01; c01=c11; c11=cswap;
+ }
+ lx = 0;
+ for (x = 0; x < dst->w; x++) {
+ /*
+ * Interpolate colors
+ */
+ ex = (*csax & 0xffff);
+ ey = (*csay & 0xffff);
+ t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff;
+ t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff;
+ dp->r = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff;
+ t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff;
+ dp->g = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff;
+ t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff;
+ dp->b = (((t2 - t1) * ey) >> 16) + t1;
+ t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff;
+ t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff;
+ dp->a = (((t2 - t1) * ey) >> 16) + t1;
+
+ /*
+ * Advance source pointers
+ */
+ csax++;
+ sstep = (*csax >> 16);
+ lx += sstep;
+ if (lx >= src->w) sstep = 0;
+ if (flipx) sstep = -sstep;
+ c00 += sstep;
+ c01 += sstep;
+ c10 += sstep;
+ c11 += sstep;
+ /*
+ * Advance destination pointer
+ */
+ dp++;
+ }
+ /*
+ * Advance source pointer
+ */
+ csay++;
+ sstep = (*csay >> 16);
+ ly += sstep;
+ if (ly >= src->h) sstep = 0;
+ sstep *= src->pitch;
+ if (flipy) sstep = -sstep;
+ csp = (tColorRGBA *) ((Uint8 *) csp + sstep);
+
+ /*
+ * Advance destination pointers
+ */
+ dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
+ }
+ } else {
+
+ /*
+ * Non-Interpolating Zoom
+ */
+
+ csay = say;
+ for (y = 0; y < dst->h; y++) {
+ sp = csp;
+ csax = sax;
+ for (x = 0; x < dst->w; x++) {
+ /*
+ * Draw
+ */
+ *dp = *sp;
+ /*
+ * Advance source pointers
+ */
+ csax++;
+ sstep = (*csax >> 16);
+ if (flipx) sstep = -sstep;
+ sp += sstep;
+ /*
+ * Advance destination pointer
+ */
+ dp++;
+ }
+ /*
+ * Advance source pointer
+ */
+ csay++;
+ sstep = (*csay >> 16) * src->pitch;
+ if (flipy) sstep = -sstep;
+ csp = (tColorRGBA *) ((Uint8 *) csp + sstep);
+
+ /*
+ * Advance destination pointers
+ */
+ dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
+ }
+ }
+
+ /*
+ * Remove temp arrays
+ */
+ free(sax);
+ free(say);
+
+ return (0);
+}
+
+
+
+int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst, int flipx, int flipy)
+{
+ int x, y;
+ Uint32 sx, sy, *sax, *say, *csax, *csay, csx, csy, sstep;
+ Uint8 *sp, *dp, *csp;
+ int dgap;
+
+ /*
+ * Variable setup
+ */
+ sx = (Uint32) (65536.0 * (float) src->w / (float) dst->w);
+ sy = (Uint32) (65536.0 * (float) src->h / (float) dst->h);
+
+
+ /*
+ * Allocate memory for row increments
+ */
+ if ((sax = (Uint32 *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) {
+ return (-1);
+ }
+ if ((say = (Uint32 *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) {
+ free(sax);
+ return (-1);
+ }
+
+ /*
+ * Pointer setup
+ */
+ sp = csp = (Uint8 *) src->pixels;
+ dp = (Uint8 *) dst->pixels;
+ dgap = dst->pitch - dst->w;
+
+ if (flipx) csp += (src->w-1);
+ if (flipy) csp = ( (Uint8*)csp + src->pitch*(src->h-1) );
+
+ /*
+ * Precalculate row increments
+ */
+ csx = 0;
+ csax = sax;
+ for (x = 0; x <= dst->w; x++) {
+ *csax = csx;
+ csax++;
+ csx &= 0xffff;
+ csx += sx;
+ }
+ csy = 0;
+ csay = say;
+ for (y = 0; y <= dst->h; y++) {
+ *csay = csy;
+ csay++;
+ csy &= 0xffff;
+ csy += sy;
+ }
+
+
+ /*
+ * Draw
+ */
+ csay = say;
+ for (y = 0; y < dst->h; y++) {
+ csax = sax;
+ sp = csp;
+ for (x = 0; x < dst->w; x++) {
+ /*
+ * Draw
+ */
+ *dp = *sp;
+ /*
+ * Advance source pointers
+ */
+ csax++;
+ sstep = (*csax >> 16);
+ if (flipx) sstep = -sstep;
+ sp += sstep;
+ /*
+ * Advance destination pointer
+ */
+ dp++;
+ }
+ /*
+ * Advance source pointer (for row)
+ */
+ csay++;
+ sstep = (*csay >> 16) * src->pitch;
+ if (flipy) sstep = -sstep;
+ csp = ((Uint8 *) csp + sstep);
+
+ /*
+ * Advance destination pointers
+ */
+ dp += dgap;
+ }
+
+ /*
+ * Remove temp arrays
+ */
+ free(sax);
+ free(say);
+
+ return (0);
+}
+
+
+
+SDL_Surface *_SDLzoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth)
+{
+ SDL_Surface *rz_src;
+ SDL_Surface *rz_dst;
+ int dstwidth, dstheight;
+ int is32bit;
+ int i, src_converted;
+ int flipx, flipy;
+
+ /*
+ * Sanity check
+ */
+ if (src == NULL)
+ return (NULL);
+
+ /*
+ * Determine if source surface is 32bit or 8bit
+ */
+ is32bit = (src->format->BitsPerPixel == 32);
+ if ((is32bit) || (src->format->BitsPerPixel == 8)) {
+ /*
+ * Use source surface 'as is'
+ */
+ rz_src = src;
+ src_converted = 0;
+ } else {
+ /*
+ * New source surface is 32bit with a defined RGBA ordering
+ */
+ rz_src =
+ SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN
+ 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
+#else
+ 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff
+#endif
+ );
+ SDL_BlitSurface(src, NULL, rz_src, NULL);
+ src_converted = 1;
+ is32bit = 1;
+ }
+
+ flipx = (zoomx<0.0);
+ if (flipx) zoomx = -zoomx;
+ flipy = (zoomy<0.0);
+ if (flipy) zoomy = -zoomy;
+
+ /* Get size if target */
+ zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight);
+
+ /*
+ * Alloc space to completely contain the zoomed surface
+ */
+ rz_dst = NULL;
+ if (is32bit) {
+ /*
+ * Target surface is 32bit with source RGBA/ABGR ordering
+ */
+ rz_dst =
+ SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32,
+ rz_src->format->Rmask, rz_src->format->Gmask,
+ rz_src->format->Bmask, rz_src->format->Amask);
+ } else {
+ /*
+ * Target surface is 8bit
+ */
+ rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0);
+ }
+
+ /*
+ * Lock source surface
+ */
+ SDL_LockSurface(rz_src);
+ /*
+ * Check which kind of surface we have
+ */
+ if (is32bit) {
+ /*
+ * Call the 32bit transformation routine to do the zooming (using alpha)
+ */
+ zoomSurfaceRGBA(rz_src, rz_dst, flipx, flipy, smooth);
+ /*
+ * Turn on source-alpha support
+ */
+ SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255);
+ } else {
+ /*
+ * Copy palette and colorkey info
+ */
+ for (i = 0; i < rz_src->format->palette->ncolors; i++) {
+ rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i];
+ }
+ rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors;
+ /*
+ * Call the 8bit transformation routine to do the zooming
+ */
+ zoomSurfaceY(rz_src, rz_dst, flipx, flipy);
+ SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey);
+ }
+ /*
+ * Unlock source surface
+ */
+ SDL_UnlockSurface(rz_src);
+
+ /*
+ * Cleanup temp surface
+ */
+ if (src_converted) {
+ SDL_FreeSurface(rz_src);
+ }
+
+ /*
+ * Return destination surface
+ */
+ return (rz_dst);
+}
diff --git a/src/resources/sdlrescalefacility.h b/src/resources/sdlrescalefacility.h
new file mode 100644
index 00000000..971f5d73
--- /dev/null
+++ b/src/resources/sdlrescalefacility.h
@@ -0,0 +1,52 @@
+/*
+ * 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 Low 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
+ *
+ * Source code taken from:
+ *
+ * SDL_rotozoom - rotozoomer
+ *
+ * LGPL (c) A. Schiffler
+ *
+ */
+
+#ifndef SDLRESCALEFACILITY_H
+#define SDLRESCALEFACILITY_H
+
+#include <SDL.h>
+#include "image.h"
+
+/**
+ * _SDLzoomSurface is internally used by Image::getScaledImage() to provide
+ * a rescaled copy of its internal mImage member.
+ *
+ * @see Image::getScaledImage() for more details
+ *
+ * @param src the original surface to rescale
+ * @param zoomx the zoom factor used to rescale the surface horizontally. 1.0 doesn't rescale.
+ * A value lesser than 1.O shrink the image.
+ * @param zoomy the zoom factor used to rescale the surface vertically.
+ * @param smooth transform the scaled surface into a 32bit aliased image to smooth the rescaling.
+ *
+ * @return SDL_Surface The rescaled surface.
+ */
+
+SDL_Surface *_SDLzoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth);
+
+#endif