summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2012-02-05 15:00:58 +0300
committerAndrei Karas <akaras@inbox.ru>2012-02-05 15:00:58 +0300
commit9a3a196dbf633a699c26d0227802a42f025c8bfd (patch)
treedfbdb2ff1e2c54d75a2bf6411d3f70df22518c28 /src
parentfc17ff22d9df50df9c5d1cf3dc0de358001271ed (diff)
parentece36a40d4e9a838cde01075d7681b8fc517b19f (diff)
downloadmanaverse-9a3a196dbf633a699c26d0227802a42f025c8bfd.tar.gz
manaverse-9a3a196dbf633a699c26d0227802a42f025c8bfd.tar.bz2
manaverse-9a3a196dbf633a699c26d0227802a42f025c8bfd.tar.xz
manaverse-9a3a196dbf633a699c26d0227802a42f025c8bfd.zip
Merge branch 'master' into stripped
Conflicts: src/guichan/gui.cpp src/guichan/include/guichan/sdl/sdlpixel.hpp
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/Makefile.am6
-rw-r--r--src/actorsprite.cpp19
-rw-r--r--src/actorspritemanager.h22
-rw-r--r--src/animatedsprite.cpp2
-rw-r--r--src/animatedsprite.h4
-rw-r--r--src/being.cpp37
-rw-r--r--src/being.h28
-rw-r--r--src/channel.h5
-rw-r--r--src/chatlogger.cpp8
-rw-r--r--src/chatlogger.h2
-rw-r--r--src/client.cpp108
-rw-r--r--src/client.h7
-rw-r--r--src/commandhandler.cpp10
-rw-r--r--src/compoundsprite.cpp78
-rw-r--r--src/compoundsprite.h21
-rw-r--r--src/configuration.h4
-rw-r--r--src/debug.h13
-rw-r--r--src/defaults.cpp6
-rw-r--r--src/dropshortcut.cpp7
-rw-r--r--src/emoteshortcut.h2
-rw-r--r--src/equipment.h2
-rw-r--r--src/flooritem.h2
-rw-r--r--src/game.cpp137
-rw-r--r--src/game.h4
-rw-r--r--src/graphics.cpp48
-rw-r--r--src/graphics.h28
-rw-r--r--src/graphicsvertexes.h2
-rw-r--r--src/gui/charcreatedialog.cpp163
-rw-r--r--src/gui/charcreatedialog.h16
-rw-r--r--src/gui/charselectdialog.cpp2
-rw-r--r--src/gui/chatwindow.cpp11
-rw-r--r--src/gui/editdialog.h2
-rw-r--r--src/gui/editserverdialog.cpp239
-rw-r--r--src/gui/editserverdialog.h104
-rw-r--r--src/gui/equipmentwindow.h2
-rw-r--r--src/gui/gui.cpp36
-rw-r--r--src/gui/gui.h5
-rw-r--r--src/gui/inventorywindow.cpp12
-rw-r--r--src/gui/inventorywindow.h2
-rw-r--r--src/gui/itemamountwindow.cpp10
-rw-r--r--src/gui/logindialog.cpp14
-rw-r--r--src/gui/npcdialog.cpp40
-rw-r--r--src/gui/npcdialog.h10
-rw-r--r--src/gui/outfitwindow.cpp381
-rw-r--r--src/gui/outfitwindow.h4
-rw-r--r--src/gui/palette.h10
-rw-r--r--src/gui/popupmenu.cpp12
-rw-r--r--src/gui/serverdialog.cpp329
-rw-r--r--src/gui/serverdialog.h42
-rw-r--r--src/gui/setup.cpp2
-rw-r--r--src/gui/setup_relations.cpp7
-rw-r--r--src/gui/setup_video.cpp76
-rw-r--r--src/gui/setup_video.h5
-rw-r--r--src/gui/shopwindow.cpp13
-rw-r--r--src/gui/shopwindow.h2
-rw-r--r--src/gui/skilldialog.h2
-rw-r--r--src/gui/socialwindow.cpp8
-rw-r--r--src/gui/socialwindow.h4
-rw-r--r--src/gui/statuswindow.cpp17
-rw-r--r--src/gui/theme.h2
-rw-r--r--src/gui/tradewindow.h2
-rw-r--r--src/gui/updaterwindow.cpp10
-rw-r--r--src/gui/userpalette.h2
-rw-r--r--src/gui/viewport.cpp49
-rw-r--r--src/gui/viewport.h24
-rw-r--r--src/gui/whoisonline.cpp179
-rw-r--r--src/gui/whoisonline.h68
-rw-r--r--src/gui/widgets/browserbox.h2
-rw-r--r--src/gui/widgets/button.h6
-rw-r--r--src/gui/widgets/channeltab.h3
-rw-r--r--src/gui/widgets/chattab.cpp14
-rw-r--r--src/gui/widgets/chattab.h8
-rw-r--r--src/gui/widgets/desktop.cpp8
-rw-r--r--src/gui/widgets/emoteshortcutcontainer.cpp2
-rw-r--r--src/gui/widgets/guildchattab.h3
-rw-r--r--src/gui/widgets/icon.h3
-rw-r--r--src/gui/widgets/layout.h4
-rw-r--r--src/gui/widgets/popup.h18
-rw-r--r--src/gui/widgets/progressbar.h6
-rw-r--r--src/gui/widgets/scrollarea.h3
-rw-r--r--src/gui/widgets/setupitem.cpp10
-rw-r--r--src/gui/widgets/setupitem.h4
-rw-r--r--src/gui/widgets/setuptabscroll.h2
-rw-r--r--src/gui/widgets/shoplistbox.h3
-rw-r--r--src/gui/widgets/tab.h4
-rw-r--r--src/gui/widgets/tabbedarea.h4
-rw-r--r--src/gui/widgets/textbox.h3
-rw-r--r--src/gui/widgets/textfield.cpp54
-rw-r--r--src/gui/widgets/textfield.h2
-rw-r--r--src/gui/widgets/vertcontainer.cpp7
-rw-r--r--src/gui/widgets/vertcontainer.h6
-rw-r--r--src/gui/widgets/window.cpp78
-rw-r--r--src/gui/widgets/window.h15
-rw-r--r--src/gui/widgets/windowcontainer.cpp12
-rw-r--r--src/gui/widgets/windowcontainer.h6
-rw-r--r--src/gui/windowmenu.cpp2
-rw-r--r--src/guild.cpp7
-rw-r--r--src/guild.h2
-rw-r--r--src/guildmanager.h2
-rw-r--r--src/keyboardconfig.cpp14
-rw-r--r--src/keyboardconfig.h6
-rw-r--r--src/localplayer.cpp31
-rw-r--r--src/localplayer.h62
-rw-r--r--src/main.h4
-rw-r--r--src/manaplus.rc5
-rw-r--r--src/map.cpp11
-rw-r--r--src/map.h28
-rw-r--r--src/mumblemanager.cpp8
-rw-r--r--src/mumblemanager.h7
-rw-r--r--src/net/adminhandler.h6
-rw-r--r--src/net/download.cpp2
-rw-r--r--src/net/ea/adminhandler.cpp6
-rw-r--r--src/net/ea/adminhandler.h6
-rw-r--r--src/net/ea/playerhandler.cpp1
-rw-r--r--src/net/inventoryhandler.h4
-rw-r--r--src/net/manaserv/adminhandler.cpp6
-rw-r--r--src/net/manaserv/adminhandler.h6
-rw-r--r--src/net/manaserv/attributes.cpp8
-rw-r--r--src/net/manaserv/connection.h2
-rw-r--r--src/net/manaserv/gamehandler.h6
-rw-r--r--src/net/manaserv/guildhandler.h2
-rw-r--r--src/net/manaserv/loginhandler.cpp2
-rw-r--r--src/net/manaserv/playerhandler.cpp5
-rw-r--r--src/net/manaserv/playerhandler.h2
-rw-r--r--src/net/manaserv/specialhandler.cpp10
-rw-r--r--src/net/manaserv/specialhandler.h6
-rw-r--r--src/net/messagein.cpp19
-rw-r--r--src/net/messagein.h2
-rw-r--r--src/net/playerhandler.h2
-rw-r--r--src/net/serverinfo.h2
-rw-r--r--src/net/specialhandler.h6
-rw-r--r--src/net/tmwa/beinghandler.cpp2
-rw-r--r--src/net/tmwa/charserverhandler.cpp7
-rw-r--r--src/net/tmwa/inventoryhandler.cpp4
-rw-r--r--src/net/tmwa/inventoryhandler.h2
-rw-r--r--src/net/tmwa/network.cpp2
-rw-r--r--src/net/tmwa/network.h2
-rw-r--r--src/net/tmwa/npchandler.cpp83
-rw-r--r--src/net/tmwa/npchandler.h7
-rw-r--r--src/net/tmwa/playerhandler.cpp50
-rw-r--r--src/net/tmwa/playerhandler.h1
-rw-r--r--src/net/tmwa/protocol.h2
-rw-r--r--src/net/tmwa/specialhandler.cpp6
-rw-r--r--src/net/tmwa/specialhandler.h6
-rw-r--r--src/opengl1graphics.cpp21
-rw-r--r--src/opengl1graphics.h4
-rw-r--r--src/openglgraphics.cpp20
-rw-r--r--src/openglgraphics.h4
-rw-r--r--src/particle.h2
-rw-r--r--src/resources/action.h2
-rw-r--r--src/resources/colordb.cpp65
-rw-r--r--src/resources/colordb.h4
-rw-r--r--src/resources/emotedb.cpp5
-rw-r--r--src/resources/image.cpp49
-rw-r--r--src/resources/image.h23
-rw-r--r--src/resources/imageset.h4
-rw-r--r--src/resources/iteminfo.h5
-rw-r--r--src/resources/music.cpp51
-rw-r--r--src/resources/music.h22
-rw-r--r--src/resources/resource.h2
-rw-r--r--src/resources/resourcemanager.cpp39
-rw-r--r--src/resources/resourcemanager.h10
-rw-r--r--src/resources/soundeffect.cpp8
-rw-r--r--src/resources/soundeffect.h8
-rw-r--r--src/sound.cpp102
-rw-r--r--src/sound.h25
-rw-r--r--src/textcommand.h2
-rw-r--r--src/utils/checkutils.cpp39
-rw-r--r--src/utils/checkutils.h30
-rw-r--r--src/utils/copynpaste.cpp2
-rw-r--r--src/utils/physfsrwops.cpp186
-rw-r--r--src/utils/physfsrwops.h82
-rw-r--r--src/utils/stringutils.cpp36
-rw-r--r--src/utils/stringutils.h4
175 files changed, 2650 insertions, 1506 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6c612629c..f389c4364 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -247,6 +247,8 @@ SET(SRCS
gui/debugwindow.h
gui/didyouknowwindow.cpp
gui/didyouknowwindow.h
+ gui/editserverdialog.cpp
+ gui/editserverdialog.h
gui/emotepopup.cpp
gui/emotepopup.h
gui/equipmentwindow.cpp
@@ -445,6 +447,8 @@ SET(SRCS
resources/wallpaper.h
utils/base64.cpp
utils/base64.h
+ utils/checkutils.cpp
+ utils/checkutils.h
utils/copynpaste.cpp
utils/copynpaste.h
utils/dtor.h
@@ -452,6 +456,8 @@ SET(SRCS
utils/mathutils.h
utils/paths.cpp
utils/paths.h
+ utils/physfsrwops.cpp
+ utils/physfsrwops.h
utils/process.cpp
utils/process.h
utils/stringutils.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index 1893adb80..a241b60b0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -153,6 +153,8 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \
gui/debugwindow.h \
gui/didyouknowwindow.cpp \
gui/didyouknowwindow.h \
+ gui/editserverdialog.cpp \
+ gui/editserverdialog.h \
gui/emotepopup.cpp \
gui/emotepopup.h \
gui/equipmentwindow.cpp \
@@ -353,6 +355,8 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \
resources/wallpaper.h \
utils/base64.cpp \
utils/base64.h \
+ utils/checkutils.cpp \
+ utils/checkutils.h \
utils/copynpaste.cpp \
utils/copynpaste.h \
utils/dtor.h \
@@ -362,6 +366,8 @@ manaplus_SOURCES += gui/widgets/avatarlistbox.cpp \
utils/mkdir.h \
utils/paths.cpp \
utils/paths.h \
+ utils/physfsrwops.cpp \
+ utils/physfsrwops.h \
utils/process.cpp \
utils/process.h \
utils/specialfolder.cpp \
diff --git a/src/actorsprite.cpp b/src/actorsprite.cpp
index c1c139bb9..916b599f9 100644
--- a/src/actorsprite.cpp
+++ b/src/actorsprite.cpp
@@ -39,6 +39,8 @@
#include "resources/imageset.h"
#include "resources/resourcemanager.h"
+#include "utils/checkutils.h"
+
#include "debug.h"
#define EFFECTS_FILE "effects.xml"
@@ -70,7 +72,7 @@ ActorSprite::~ActorSprite()
for (ActorSpriteListenerIterator iter = mActorSpriteListeners.begin(),
e = mActorSpriteListeners.end(); iter != e; ++iter)
{
- if (*iter)
+ if (reportFalse(*iter))
(*iter)->actorSpriteDestroyed(*this);
}
}
@@ -166,6 +168,9 @@ static bool effects_initialized = false;
static EffectDescription *getEffectDescription(XmlNodePtr node, int *id)
{
+ if (!id)
+ return nullptr;
+
EffectDescription *ed = new EffectDescription;
*id = atoi(XML::getProperty(node, "id", "-1").c_str());
@@ -245,7 +250,7 @@ void ActorSprite::setStatusEffectBlock(int offset, Uint16 newEffects)
void ActorSprite::internalTriggerEffect(int effectId, bool sfx, bool gfx)
{
- if (!particleEngine)
+ if (reportTrue(!particleEngine))
return;
if (player_node)
@@ -256,13 +261,13 @@ void ActorSprite::internalTriggerEffect(int effectId, bool sfx, bool gfx)
EffectDescription *ed = getEffectDescription(effectId);
- if (!ed)
+ if (reportTrue(!ed))
{
logger->log1("Unknown special effect and no default recorded");
return;
}
- if (gfx && !ed->mGFXEffect.empty() && particleEngine)
+ if (gfx && !ed->mGFXEffect.empty())
{
Particle *selfFX;
@@ -287,7 +292,7 @@ void ActorSprite::updateStatusEffect(int index, bool newStatus)
void ActorSprite::handleStatusEffect(StatusEffect *effect, int effectId)
{
- if (!effect)
+ if (reportTrue(!effect))
return;
// TODO: Find out how this is meant to be used
@@ -392,7 +397,7 @@ void ActorSprite::load()
void ActorSprite::unload()
{
- if (!loaded)
+ if (reportTrue(!loaded))
return;
cleanupTargetCursors();
@@ -476,7 +481,7 @@ void ActorSprite::cleanupTargetCursors()
void ActorSprite::loadTargetCursor(const std::string &filename,
int width, int height, int type, int size)
{
- if (size < TC_SMALL || size >= NUM_TC)
+ if (reportTrue(size < TC_SMALL || size >= NUM_TC))
return;
ImageSet *currentImageSet = Theme::getImageSetFromTheme(
diff --git a/src/actorspritemanager.h b/src/actorspritemanager.h
index 7960c6301..a78e3ad49 100644
--- a/src/actorspritemanager.h
+++ b/src/actorspritemanager.h
@@ -231,10 +231,10 @@ class ActorSpriteManager: public ConfigListener
void addIgnoreAttackMob(std::string name);
- std::list<std::string> getPriorityAttackMobs()
+ std::list<std::string> getPriorityAttackMobs() const
{ return mPriorityAttackMobs; }
- std::list<std::string> getAttackMobs()
+ std::list<std::string> getAttackMobs() const
{ return mAttackMobs; }
void setPriorityAttackMobs(std::list<std::string> mobs)
@@ -243,29 +243,29 @@ class ActorSpriteManager: public ConfigListener
void setAttackMobs(std::list<std::string> mobs)
{ mAttackMobs = mobs; }
- int getPriorityAttackMobsSize()
+ int getPriorityAttackMobsSize() const
{ return mPriorityAttackMobs.size(); }
- int getAttackMobsSize()
+ int getAttackMobsSize() const
{ return mAttackMobs.size(); }
- std::list<std::string> getIgnoreAttackMobs()
+ std::list<std::string> getIgnoreAttackMobs() const
{ return mIgnoreAttackMobs; }
- std::set<std::string> getAttackMobsSet()
+ std::set<std::string> getAttackMobsSet() const
{ return mAttackMobsSet; }
- std::set<std::string> getPriorityAttackMobsSet()
+ std::set<std::string> getPriorityAttackMobsSet() const
{ return mPriorityAttackMobsSet; }
- std::set<std::string> getIgnoreAttackMobsSet()
+ std::set<std::string> getIgnoreAttackMobsSet() const
{ return mIgnoreAttackMobsSet; }
void rebuildPriorityAttackMobs();
void rebuildAttackMobs();
- bool isInAttackList(const std::string &name)
+ bool isInAttackList(const std::string &name) const
{ return mAttackMobsSet.find(name) != mAttackMobsSet.end(); }
bool isInPriorityAttackList(const std::string &name)
@@ -280,10 +280,10 @@ class ActorSpriteManager: public ConfigListener
!= mIgnoreAttackMobsSet.end();
}
- std::map<std::string, int> getAttackMobsMap()
+ std::map<std::string, int> getAttackMobsMap() const
{ return mAttackMobsMap; }
- std::map<std::string, int> getPriorityAttackMobsMap()
+ std::map<std::string, int> getPriorityAttackMobsMap() const
{ return mPriorityAttackMobsMap; }
int getAttackMobIndex(std::string name);
diff --git a/src/animatedsprite.cpp b/src/animatedsprite.cpp
index f4f3451cb..11329b321 100644
--- a/src/animatedsprite.cpp
+++ b/src/animatedsprite.cpp
@@ -285,7 +285,7 @@ int AnimatedSprite::getHeight() const
return 0;
}
-std::string AnimatedSprite::getIdPath()
+std::string AnimatedSprite::getIdPath() const
{
if (!mSprite)
return "";
diff --git a/src/animatedsprite.h b/src/animatedsprite.h
index 4a41eac52..d28badfc1 100644
--- a/src/animatedsprite.h
+++ b/src/animatedsprite.h
@@ -71,10 +71,10 @@ class AnimatedSprite : public Sprite
bool setSpriteDirection(SpriteDirection direction);
- int getNumberOfLayers()
+ int getNumberOfLayers() const
{ return 1; }
- std::string getIdPath();
+ std::string getIdPath() const;
unsigned int getCurrentFrame() const;
diff --git a/src/being.cpp b/src/being.cpp
index 39d0bd450..9edfaad7b 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -2517,26 +2517,31 @@ void Being::saveComment(const std::string &name,
resman->saveTextFile(dir, "comment.txt", name + "\n" + comment);
}
+void Being::setState(Uint8 state)
+{
+ mAdvanced = true;
+ bool shop = (state & FLAG_SHOP);
+ bool away = (state & FLAG_AWAY);
+ bool inactive = (state & FLAG_INACTIVE);
+ bool needUpdate = (shop != mShop || away != mAway
+ || inactive != mInactive);
+
+ mShop = shop;
+ mAway = away;
+ mInactive = inactive;
+
+ if (needUpdate)
+ {
+ updateName();
+ addToCache();
+ }
+}
+
void Being::setEmote(Uint8 emotion, int emote_time)
{
if ((emotion & FLAG_SPECIAL) == FLAG_SPECIAL)
{
- mAdvanced = true;
- bool shop = (emotion & FLAG_SHOP);
- bool away = (emotion & FLAG_AWAY);
- bool inactive = (emotion & FLAG_INACTIVE);
- bool needUpdate = (shop != mShop || away != mAway
- || inactive != mInactive);
-
- mShop = shop;
- mAway = away;
- mInactive = inactive;
-
- if (needUpdate)
- {
- updateName();
- addToCache();
- }
+ setState(emotion);
}
else
{
diff --git a/src/being.h b/src/being.h
index 6052644c9..8b3db1919 100644
--- a/src/being.h
+++ b/src/being.h
@@ -102,6 +102,7 @@ class Being : public ActorSprite, public ConfigListener
FLAG_SHOP = 1,
FLAG_AWAY = 2,
FLAG_INACTIVE = 4,
+ FLAG_GENDER = 128,
FLAG_SPECIAL = 128 + 64
};
@@ -488,7 +489,7 @@ class Being : public ActorSprite, public ConfigListener
virtual void setDirectionDelayed(Uint8 direction)
{ mDirectionDelayed = direction; }
- Uint8 getDirectionDelayed()
+ Uint8 getDirectionDelayed() const
{ return mDirectionDelayed; }
/**
@@ -546,6 +547,8 @@ class Being : public ActorSprite, public ConfigListener
*/
void setEmote(Uint8 emotion, int emote_time);
+ void setState(Uint8 state);
+
/**
* Get the current Emoticon type displayed above
* the being.
@@ -585,7 +588,7 @@ class Being : public ActorSprite, public ConfigListener
void setIsReachable(int n)
{ mIsReachable = n; }
- int isReachable()
+ int isReachable() const
{ return mIsReachable; }
static void reReadConfig();
@@ -678,7 +681,7 @@ class Being : public ActorSprite, public ConfigListener
void setMaxHP(int hp);
- int getHP()
+ int getHP() const
{ return mHP; }
Uint8 calcDirection(int dstX, int dstY) const;
@@ -688,22 +691,22 @@ class Being : public ActorSprite, public ConfigListener
void setAttackDelay(int n)
{ mAttackDelay = n; }
- int getAttackDelay()
+ int getAttackDelay() const
{ return mAttackDelay; }
- int getMinHit()
+ int getMinHit() const
{ return mMinHit; }
void setMinHit(int n)
{ mMinHit = n; }
- int getMaxHit()
+ int getMaxHit() const
{ return mMaxHit; }
void setMaxHit(int n)
{ mMaxHit = n; }
- int getCriticalHit()
+ int getCriticalHit() const
{ return mCriticalHit; }
void setCriticalHit(int n)
@@ -715,7 +718,7 @@ class Being : public ActorSprite, public ConfigListener
void undressItemById(int id);
- int getGoodStatus()
+ int getGoodStatus() const
{ return mGoodStatus; }
void setGoodStatus(int n)
@@ -727,7 +730,7 @@ class Being : public ActorSprite, public ConfigListener
void updateComment();
- std::string getComment()
+ const std::string getComment() const
{ return mComment; }
void setComment(std::string n)
@@ -740,15 +743,18 @@ class Being : public ActorSprite, public ConfigListener
static void saveComment(const std::string &name,
const std::string &comment, int type);
- bool isAdvanced()
+ bool isAdvanced() const
{ return mAdvanced; }
void setAdvanced(bool n)
{ mAdvanced = n; addToCache(); }
- bool isShopEnabled()
+ bool isShopEnabled() const
{ return mShop; }
+ void enableShop(bool b)
+ { mShop = b; }
+
/**
* Sets the attack range.
*/
diff --git a/src/channel.h b/src/channel.h
index 559002296..cf52743f0 100644
--- a/src/channel.h
+++ b/src/channel.h
@@ -46,7 +46,8 @@ class Channel
/**
* Get the id associated witht his channel.
*/
- int getId() const { return mId; }
+ int getId() const
+ { return mId; }
/**
* Get this channel's name.
@@ -72,7 +73,7 @@ class Channel
void setAnnouncement(const std::string &channelAnnouncement)
{ mAnnouncement = channelAnnouncement; }
- ChannelTab *getTab()
+ ChannelTab *getTab() const
{ return mTab; }
protected:
diff --git a/src/chatlogger.cpp b/src/chatlogger.cpp
index ad86de8e9..33763e561 100644
--- a/src/chatlogger.cpp
+++ b/src/chatlogger.cpp
@@ -39,7 +39,6 @@
#include "logger.h"
#include "configuration.h"
-
#include "utils/mkdir.h"
#include "utils/stringutils.h"
@@ -204,3 +203,10 @@ void ChatLogger::loadLast(std::string name, std::list<std::string> &list,
if (logFile.is_open())
logFile.close();
}
+
+void ChatLogger::clear()
+{
+ mLogDir = "";
+ mServerName = "";
+ mLogFileName = "";
+}
diff --git a/src/chatlogger.h b/src/chatlogger.h
index 91805a8bc..bb02d8127 100644
--- a/src/chatlogger.h
+++ b/src/chatlogger.h
@@ -59,6 +59,8 @@ class ChatLogger
void setBaseLogDir(const std::string &logDir)
{ mBaseLogDir = logDir; }
+ void clear();
+
private:
/**
* Sets the file to log to and opens it
diff --git a/src/client.cpp b/src/client.cpp
index 1c4629178..c21194834 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -167,7 +167,7 @@ volatile int frame_count = 0; /**< Counts the frames during one second */
volatile int cur_time;
volatile bool runCounters;
bool isSafeMode = false;
-int serverVersion;
+int serverVersion = 0;
int start_time;
int textures_count = 0;
@@ -251,7 +251,7 @@ Client::Client(const Options &options):
mServerConfigDir(""),
mUsersDir(""),
mNpcsDir(""),
- mRootDir(""),
+ mGame(nullptr),
mCurrentDialog(nullptr),
mQuitDialog(nullptr),
mDesktop(nullptr),
@@ -524,9 +524,12 @@ void Client::gameInit()
const int bpp = 0;
const bool fullscreen = config.getBoolValue("screen");
const bool hwaccel = config.getBoolValue("hwaccel");
+ const bool enableResize = config.getBoolValue("enableresize");
+ const bool noFrame = config.getBoolValue("noframe");
// Try to set the desired video mode
- if (!mainGraphics->setVideoMode(width, height, bpp, fullscreen, hwaccel))
+ if (!mainGraphics->setVideoMode(width, height, bpp,
+ fullscreen, hwaccel, enableResize, noFrame))
{
logger->log(strprintf("Couldn't set %dx%dx%d video mode: %s",
width, height, bpp, SDL_GetError()));
@@ -544,7 +547,7 @@ void Client::gameInit()
config.setValueInt("screenheight", oldHeight);
config.setValue("screen", oldFullscreen);
if (!mainGraphics->setVideoMode(oldWidth, oldHeight, bpp,
- oldFullscreen, hwaccel))
+ oldFullscreen, hwaccel, enableResize, noFrame))
{
logger->error(strprintf("Couldn't restore %dx%dx%d "
"video mode: %s", oldWidth, oldHeight, bpp,
@@ -612,6 +615,7 @@ void Client::gameInit()
{
mCurrentServer.hostname =
branding.getValue("defaultServer", "").c_str();
+ mOptions.serverName = mCurrentServer.hostname;
}
if (mCurrentServer.port == 0)
@@ -815,15 +819,14 @@ int Client::gameExec()
if (!mumbleManager)
mumbleManager = new MumbleManager();
- Game *game = nullptr;
SDL_Event event;
while (mState != STATE_EXIT)
{
- if (game)
+ if (mGame)
{
// Let the game handle the events while it is active
- game->handleInput();
+ mGame->handleInput();
}
else
{
@@ -839,6 +842,10 @@ int Client::gameExec()
case SDL_KEYDOWN:
default:
break;
+
+ case SDL_VIDEORESIZE:
+ resizeVideo(event.resize.w, event.resize.h, false);
+ break;
}
guiInput->pushInput(event);
@@ -857,8 +864,8 @@ int Client::gameExec()
{
if (gui)
gui->logic();
- if (game)
- game->logic();
+ if (mGame)
+ mGame->logic();
sound.logic();
@@ -966,10 +973,8 @@ int Client::gameExec()
top->add(mThemesButton);
#endif
- int screenWidth = config.getIntValue("screenwidth");
- int screenHeight = config.getIntValue("screenheight");
-
- mDesktop->setSize(screenWidth, screenHeight);
+ mDesktop->setSize(mainGraphics->getWidth(),
+ mainGraphics->getHeight());
}
if (mState == STATE_SWITCH_LOGIN && mOldState == STATE_GAME)
@@ -984,8 +989,8 @@ int Client::gameExec()
if (mOldState == STATE_GAME)
{
- delete game;
- game = nullptr;
+ delete mGame;
+ mGame = nullptr;
Game::clearInstance();
ResourceManager *resman = ResourceManager::getInstance();
if (resman)
@@ -995,6 +1000,8 @@ int Client::gameExec()
Net::getNpcHandler()->clearDialogs();
Net::getGuildHandler()->clear();
Net::getPartyHandler()->clear();
+ if (chatLogger)
+ chatLogger->clear();
}
mOldState = mState;
@@ -1231,6 +1238,10 @@ int Client::gameExec()
CharSelectDialog::Focus);
}
+ // Choosing character on the command line should work only
+ // once, clear it so that 'switch character' works.
+ mOptions.character.clear();
+
break;
case STATE_CONNECT_GAME:
@@ -1286,7 +1297,7 @@ int Client::gameExec()
logger->log1("State: GAME");
if (Net::getGeneralHandler())
Net::getGeneralHandler()->reloadPartially();
- game = new Game;
+ mGame = new Game;
break;
case STATE_LOGIN_ERROR:
@@ -1563,7 +1574,7 @@ void Client::initLocalDataDir()
// Use Application Directory instead of .mana
mLocalDataDir = std::string(PHYSFS_getUserDir()) +
"/Library/Application Support/" +
- branding.getValue("appName", "Mana");
+ branding.getValue("appName", "ManaPlus");
#elif defined __HAIKU__
mLocalDataDir = std::string(PHYSFS_getUserDir()) +
"/config/data/Mana";
@@ -1597,13 +1608,13 @@ void Client::initConfigDir()
#elif defined __HAIKU__
mConfigDir = std::string(PHYSFS_getUserDir()) +
"/config/settings/Mana" +
- branding.getValue("appName", "Mana");
+ branding.getValue("appName", "ManaPlus");
#elif defined WIN32
mConfigDir = getSpecialFolderLocation(CSIDL_APPDATA);
if (mConfigDir.empty())
mConfigDir = mLocalDataDir;
else
- mConfigDir += "/mana/" + branding.getValue("appShort", "Mana");
+ mConfigDir += "/mana/" + branding.getValue("appShort", "mana");
#else
mConfigDir = std::string(PHYSFS_getUserDir()) +
"/.config/mana/" + branding.getValue("appShort", "mana");
@@ -1855,7 +1866,7 @@ void Client::initScreenshotDir()
if (config.getBoolValue("useScreenshotDirectorySuffix"))
{
std::string configScreenshotSuffix =
- branding.getValue("appShort", "Mana");
+ branding.getValue("appShort", "mana");
if (!configScreenshotSuffix.empty())
{
@@ -1917,7 +1928,7 @@ bool Client::createConfig(std::string &configPath)
// Use Application Directory instead of .mana
oldHomeDir = std::string(PHYSFS_getUserDir()) +
"/Library/Application Support/" +
- branding.getValue("appName", "Mana");
+ branding.getValue("appName", "ManaPlus");
#else
oldHomeDir = std::string(PHYSFS_getUserDir()) +
"/." + branding.getValue("appShort", "mana");
@@ -2349,3 +2360,58 @@ bool Client::isTmw()
}
return false;
}
+
+void Client::resizeVideo(int width, int height, bool always)
+{
+ // Keep a minimum size. This isn't adhered to by the actual window, but
+ // it keeps some window positions from getting messed up.
+ width = std::max(640, width);
+ height = std::max(480, height);
+
+ if (!mainGraphics)
+ return;
+ if (!always && mainGraphics->mWidth == width
+ && mainGraphics->mHeight == height)
+ {
+ return;
+ }
+
+ if (mainGraphics->resizeScreen(width, height))
+ {
+ if (gui)
+ gui->videoResized();
+
+ if (mDesktop)
+ mDesktop->setSize(width, height);
+
+ if (mSetupButton)
+ {
+// mSetupButton->setPosition(width - mSetupButton->getWidth() - 3, 3);
+
+ int x = width - mSetupButton->getWidth() - 3;
+ mSetupButton->setPosition(x, 3);
+
+#ifndef WIN32
+ x -= mPerfomanceButton->getWidth() + 6;
+ mPerfomanceButton->setPosition(x, 3);
+
+ x -= mVideoButton->getWidth() + 6;
+ mVideoButton->setPosition(x, 3);
+
+ x -= mThemesButton->getWidth() + 6;
+ mThemesButton->setPosition(x, 3);
+#endif
+ }
+
+ if (mGame)
+ mGame->videoResized(width, height);
+
+ if (gui)
+ gui->draw();
+
+ // Since everything appears to have worked out, remember to store the
+ // new size in the configuration.
+ config.setValue("screenwidth", width);
+ config.setValue("screenheight", height);
+ }
+}
diff --git a/src/client.h b/src/client.h
index 27e6249bd..6c93adbdf 100644
--- a/src/client.h
+++ b/src/client.h
@@ -38,6 +38,7 @@
class Button;
class Desktop;
+class Game;
class LoginData;
class Window;
class QuitDialog;
@@ -257,6 +258,9 @@ public:
static std::string getServerName()
{ return instance()->mServerName; }
+ static void resize(int width, int height, bool always = false)
+ { instance()->resizeVideo(width, height, always); }
+
static void setGuiAlpha(float n);
static float getGuiAlpha();
@@ -281,6 +285,8 @@ public:
void writePacketLimits(std::string packetLimitsName);
+ void resizeVideo(int width, int height, bool always);
+
static bool limitPackets(int type);
static bool checkPackets(int type);
@@ -334,6 +340,7 @@ private:
ServerInfo mCurrentServer;
+ Game *mGame;
Window *mCurrentDialog;
QuitDialog *mQuitDialog;
Desktop *mDesktop;
diff --git a/src/commandhandler.cpp b/src/commandhandler.cpp
index 0f1e60a25..4022d8d58 100644
--- a/src/commandhandler.cpp
+++ b/src/commandhandler.cpp
@@ -54,6 +54,7 @@
#include "net/guildhandler.h"
#include "net/net.h"
#include "net/partyhandler.h"
+#include "net/playerhandler.h"
#include "net/tradehandler.h"
#ifdef DEBUG_DUMP_LEAKS
@@ -664,6 +665,9 @@ void CommandHandler::handleNavigate(const std::string &args,
bool CommandHandler::parse2Int(const std::string &args, int *x, int *y)
{
+ if (!x || !y)
+ return false;
+
bool isValid = false;
const std::string::size_type pos = args.find(" ");
if (pos != std::string::npos)
@@ -748,7 +752,10 @@ void CommandHandler::handlePseudoAway(const std::string &args,
ChatTab *tab A_UNUSED)
{
if (player_node)
+ {
player_node->setPseudoAway(args);
+ player_node->updateStatus();
+ }
}
void CommandHandler::handleFollow(const std::string &args, ChatTab *tab)
@@ -1185,6 +1192,9 @@ void showRes(std::string str, ResourceManager::Resources *res);
void showRes(std::string str, ResourceManager::Resources *res)
{
+ if (!res)
+ return;
+
if (debugChatTab)
debugChatTab->chatLog(str + toString(res->size()));
logger->log(str + toString(res->size()));
diff --git a/src/compoundsprite.cpp b/src/compoundsprite.cpp
index e76a55dcf..61fb3d4e0 100644
--- a/src/compoundsprite.cpp
+++ b/src/compoundsprite.cpp
@@ -61,10 +61,6 @@ CompoundSprite::CompoundSprite() :
CompoundSprite::~CompoundSprite()
{
- SpriteIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; ++it)
- delete (*it);
-
clear();
// delete mImage;
@@ -78,7 +74,7 @@ bool CompoundSprite::reset()
bool ret = false;
SpriteIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; ++it)
+ for (it = mSprites.begin(), it_end = mSprites.end(); it != it_end; ++ it)
{
if (*it)
ret |= (*it)->reset();
@@ -93,7 +89,7 @@ bool CompoundSprite::play(std::string action)
bool ret = false;
SpriteIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; ++it)
+ for (it = mSprites.begin(), it_end = mSprites.end(); it != it_end; ++ it)
{
if (*it)
ret |= (*it)->play(action);
@@ -108,7 +104,7 @@ bool CompoundSprite::update(int time)
bool ret = false;
SpriteIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; ++it)
+ for (it = mSprites.begin(), it_end = mSprites.end(); it != it_end; ++ it)
{
if (*it)
ret |= (*it)->update(time);
@@ -118,11 +114,14 @@ bool CompoundSprite::update(int time)
return ret;
}
-bool CompoundSprite::draw(Graphics* graphics, int posX, int posY) const
+bool CompoundSprite::draw(Graphics *graphics, int posX, int posY) const
{
if (mNeedsRedraw)
updateImages();
+ if (mSprites.empty()) // Nothing to draw
+ return false;
+
if (mAlpha == 1.0f && mImage)
{
return graphics->drawImage(mImage, posX + mOffsetX, posY + mOffsetY);
@@ -144,7 +143,7 @@ bool CompoundSprite::draw(Graphics* graphics, int posX, int posY) const
void CompoundSprite::drawSprites(Graphics* graphics, int posX, int posY) const
{
SpriteConstIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; ++it)
+ for (it = mSprites.begin(), it_end = mSprites.end(); it != it_end; ++ it)
{
if (*it)
{
@@ -158,7 +157,7 @@ void CompoundSprite::drawSpritesSDL(Graphics* graphics,
int posX, int posY) const
{
SpriteConstIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; ++it)
+ for (it = mSprites.begin(), it_end = mSprites.end(); it != it_end; ++ it)
{
if (*it)
(*it)->draw(graphics, posX, posY);
@@ -170,7 +169,7 @@ int CompoundSprite::getWidth() const
Sprite *base = nullptr;
SpriteConstIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; ++it)
+ for (it = mSprites.begin(), it_end = mSprites.end(); it != it_end; ++ it)
{
if ((base = (*it)))
break;
@@ -187,7 +186,7 @@ int CompoundSprite::getHeight() const
Sprite *base = nullptr;
SpriteConstIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; ++it)
+ for (it = mSprites.begin(), it_end = mSprites.end(); it != it_end; ++ it)
{
if ((base = (*it)))
break;
@@ -199,7 +198,7 @@ int CompoundSprite::getHeight() const
return 0;
}
-const Image* CompoundSprite::getImage() const
+const Image *CompoundSprite::getImage() const
{
return mImage;
}
@@ -209,7 +208,7 @@ bool CompoundSprite::setSpriteDirection(SpriteDirection direction)
bool ret = false;
SpriteIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; ++it)
+ for (it = mSprites.begin(), it_end = mSprites.end(); it != it_end; ++ it)
{
if (*it)
ret |= (*it)->setSpriteDirection(direction);
@@ -230,7 +229,7 @@ int CompoundSprite::getNumberOfLayers() const
unsigned int CompoundSprite::getCurrentFrame() const
{
SpriteConstIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; ++it)
+ for (it = mSprites.begin(), it_end = mSprites.end(); it != it_end; ++ it)
{
if (*it)
return (*it)->getCurrentFrame();
@@ -242,7 +241,7 @@ unsigned int CompoundSprite::getCurrentFrame() const
unsigned int CompoundSprite::getFrameCount() const
{
SpriteConstIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; ++it)
+ for (it = mSprites.begin(), it_end = mSprites.end(); it != it_end; ++ it)
{
if (*it)
return (*it)->getFrameCount();
@@ -251,42 +250,43 @@ unsigned int CompoundSprite::getFrameCount() const
return 0;
}
-void CompoundSprite::addSprite(Sprite* sprite)
+void CompoundSprite::addSprite(Sprite *sprite)
{
- push_back(sprite);
+ mSprites.push_back(sprite);
mNeedsRedraw = true;
}
void CompoundSprite::setSprite(int layer, Sprite* sprite)
{
// Skip if it won't change anything
- if (at(layer) == sprite)
+ if (mSprites.at(layer) == sprite)
return;
- if (at(layer))
- delete at(layer);
- at(layer) = sprite;
+ if (mSprites.at(layer))
+ delete mSprites.at(layer);
+ mSprites[layer] = sprite;
mNeedsRedraw = true;
}
void CompoundSprite::removeSprite(int layer)
{
// Skip if it won't change anything
- if (at(layer) == nullptr)
+ if (!mSprites.at(layer))
return;
- delete at(layer);
- at(layer) = nullptr;
+ delete mSprites.at(layer);
+ mSprites.at(layer) = nullptr;
mNeedsRedraw = true;
}
void CompoundSprite::clear()
{
// Skip if it won't change anything
- if (empty())
- return;
-
- std::vector<Sprite*>::clear();
+ if (!mSprites.empty())
+ {
+ delete_all(mSprites);
+ mSprites.clear();
+ }
mNeedsRedraw = true;
delete_all(imagesCache);
imagesCache.clear();
@@ -297,10 +297,11 @@ void CompoundSprite::clear()
void CompoundSprite::ensureSize(size_t layerCount)
{
// Skip if it won't change anything
- if (size() >= layerCount)
+ if (mSprites.size() >= layerCount)
return;
- resize(layerCount, nullptr);
+// resize(layerCount, nullptr);
+ mSprites.resize(layerCount);
}
/**
@@ -308,7 +309,7 @@ void CompoundSprite::ensureSize(size_t layerCount)
*/
unsigned int CompoundSprite::getCurrentFrame(unsigned int layer)
{
- if (layer >= size())
+ if (layer >= mSprites.size())
return 0;
Sprite *s = getSprite(layer);
@@ -323,7 +324,7 @@ unsigned int CompoundSprite::getCurrentFrame(unsigned int layer)
*/
unsigned int CompoundSprite::getFrameCount(unsigned int layer)
{
- if (layer >= size())
+ if (layer >= mSprites.size())
return 0;
Sprite *s = getSprite(layer);
@@ -418,7 +419,8 @@ void CompoundSprite::setAlpha(float alpha)
#endif
{
SpriteConstIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; ++ it)
+ for (it = mSprites.begin(), it_end = mSprites.end();
+ it != it_end; ++ it)
{
if (*it)
(*it)->setAlpha(alpha);
@@ -490,8 +492,8 @@ bool CompoundSprite::updateFromCache() const
if (ic && ic->data.size() == size())
{
bool fail(false);
- SpriteConstIterator it1 = begin();
- SpriteConstIterator it1_end = end();
+ SpriteConstIterator it1 = mSprites.begin();
+ SpriteConstIterator it1_end = mSprites.end();
VectorPointers::const_iterator it2 = ic->data.begin();
VectorPointers::const_iterator it2_end = ic->data.end();
@@ -535,7 +537,7 @@ void CompoundSprite::initCurrentCacheItem() const
// mCacheItem->alpha = mAlpha;
SpriteConstIterator it, it_end;
- for (it = begin(), it_end = end(); it != it_end; ++ it)
+ for (it = mSprites.begin(), it_end = mSprites.end(); it != it_end; ++ it)
{
if (*it)
mCacheItem->data.push_back((*it)->getHash());
@@ -548,7 +550,7 @@ bool CompoundSprite::updateNumber(unsigned num)
{
SpriteConstIterator it, it_end;
bool res(false);
- for (it = begin(), it_end = end(); it != it_end; ++ it)
+ for (it = mSprites.begin(), it_end = mSprites.end(); it != it_end; ++ it)
{
if (*it)
{
diff --git a/src/compoundsprite.h b/src/compoundsprite.h
index 1c04e44d2..1b9eeca34 100644
--- a/src/compoundsprite.h
+++ b/src/compoundsprite.h
@@ -44,11 +44,11 @@ class CompoundItem
Image *alphaImage;
};
-class CompoundSprite : public Sprite, private std::vector<Sprite*>
+class CompoundSprite : public Sprite
{
public:
- typedef CompoundSprite::iterator SpriteIterator;
- typedef CompoundSprite::const_iterator SpriteConstIterator;
+ typedef std::vector<Sprite*>::iterator SpriteIterator;
+ typedef std::vector<Sprite*>::const_iterator SpriteConstIterator;
CompoundSprite();
@@ -60,7 +60,7 @@ public:
virtual bool update(int time);
- virtual bool draw(Graphics* graphics, int posX, int posY) const;
+ virtual bool draw(Graphics *graphics, int posX, int posY) const;
/**
* Gets the width in pixels of the first sprite in the list.
@@ -72,7 +72,7 @@ public:
*/
virtual int getHeight() const;
- virtual const Image* getImage() const;
+ virtual const Image *getImage() const;
virtual bool setSpriteDirection(SpriteDirection direction);
@@ -83,17 +83,17 @@ public:
unsigned int getFrameCount() const;
size_t size() const
- { return std::vector<Sprite*>::size(); }
+ { return mSprites.size(); }
bool empty() const
- { return std::vector<Sprite*>::empty(); }
+ { return mSprites.empty(); }
- void addSprite(Sprite* sprite);
+ void addSprite(Sprite *sprite);
- void setSprite(int layer, Sprite* sprite);
+ void setSprite(int layer, Sprite *sprite);
Sprite *getSprite(int layer) const
- { return at(layer); }
+ { return mSprites.at(layer); }
void removeSprite(int layer);
@@ -144,6 +144,7 @@ private:
bool mEnableAlphaFix;
bool mDisableAdvBeingCaching;
bool mDisableBeingCaching;
+ std::vector<Sprite*> mSprites;
};
#endif // COMPOUNDSPRITE_H
diff --git a/src/configuration.h b/src/configuration.h
index 00479933e..122badfd5 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -253,10 +253,10 @@ class Configuration : public ConfigurationObject
void setSilent(const std::string &key, const std::string &value);
inline void setValue(const std::string &key, const char *value)
- { setValue(key, std::string(value)); }
+ { if (value) setValue(key, std::string(value)); }
inline void setSilent(const std::string &key, const char *value)
- { setSilent(key, std::string(value)); }
+ { if (value) setSilent(key, std::string(value)); }
inline void setValue(const std::string &key, float value)
{ setValue(key, toString(value)); }
diff --git a/src/debug.h b/src/debug.h
index 4b3934922..64a83e51c 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -23,6 +23,19 @@
//#define DEBUG_JOYSTICK 1
#ifdef ENABLE_MEM_DEBUG
+
//define _DEBUG_NEW_EMULATE_MALLOC 1
#include "debug/debug_new.h"
+
+#define reportFalse(val) reportFalse1(val, __FILE__, __LINE__)
+#define reportFalse1(val, file, line) reportFalseReal(val, file, line)
+
+#define reportTrue(val) reportTrue1(val, __FILE__, __LINE__)
+#define reportTrue1(val, file, line) reportTrueReal(val, file, line)
+
+#else
+
+#define reportFalse(val) (val)
+#define reportTrue(val) (val)
+
#endif
diff --git a/src/defaults.cpp b/src/defaults.cpp
index 8c0b84ae2..1bce806ff 100644
--- a/src/defaults.cpp
+++ b/src/defaults.cpp
@@ -225,6 +225,8 @@ DefaultsData* getConfigDefaults()
AddDEF(configData, "selectedJoystick", 0);
AddDEF(configData, "useInactiveJoystick", false);
AddDEF(configData, "testInfo", "");
+ AddDEF(configData, "enableresize", true);
+ AddDEF(configData, "noframe", false);
return configData;
}
@@ -234,8 +236,8 @@ DefaultsData* getBrandingDefaults()
// Init config defaults
AddDEF(brandingData, "wallpapersPath", "");
AddDEF(brandingData, "wallpapersFile", "");
- AddDEF(brandingData, "appName", "Mana");
- AddDEF(brandingData, "appIcon", "icons/mana.png");
+ AddDEF(brandingData, "appName", "ManaPlus");
+ AddDEF(brandingData, "appIcon", "icons/manaplus");
AddDEF(brandingData, "loginMusic", "Magick - Real.ogg");
AddDEF(brandingData, "defaultServer", "");
AddDEF(brandingData, "defaultPort", DEFAULT_PORT);
diff --git a/src/dropshortcut.cpp b/src/dropshortcut.cpp
index 79f895490..5b01f7f4f 100644
--- a/src/dropshortcut.cpp
+++ b/src/dropshortcut.cpp
@@ -133,6 +133,13 @@ void DropShortcut::dropItems(int cnt)
if (!player_node)
return;
+
+ if (player_node->isServerBuggy())
+ {
+ dropItem(player_node->getQuickDropCounter());
+ return;
+ }
+
int n = 0;
for (int f = 0; f < 9; f++)
{
diff --git a/src/emoteshortcut.h b/src/emoteshortcut.h
index cc33f4177..d7f1e7b79 100644
--- a/src/emoteshortcut.h
+++ b/src/emoteshortcut.h
@@ -21,7 +21,7 @@
#ifndef EMOTESHORTCUT_H
#define EMOTESHORTCUT_H
-#define SHORTCUT_EMOTES 44
+#define SHORTCUT_EMOTES 48
/**
* The class which keeps track of the emote shortcuts.
diff --git a/src/equipment.h b/src/equipment.h
index 6e4d04c21..50acd60d3 100644
--- a/src/equipment.h
+++ b/src/equipment.h
@@ -90,7 +90,7 @@ class Equipment
void setBackend(Backend *backend)
{ mBackend = backend; }
- Backend *getBackend()
+ Backend *getBackend() const
{ return mBackend; }
private:
diff --git a/src/flooritem.h b/src/flooritem.h
index 7e7da33a0..95427c252 100644
--- a/src/flooritem.h
+++ b/src/flooritem.h
@@ -83,7 +83,7 @@ class FloorItem : public ActorSprite
unsigned char getColor() const
{ return mColor; }
- bool getShowMsg()
+ bool getShowMsg() const
{ return mShowMsg; }
void setShowMsg(bool n)
diff --git a/src/game.cpp b/src/game.cpp
index 14a988700..0d5c1113e 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -287,6 +287,9 @@ static void createGuiWindows()
if (setupWindow)
setupWindow->externalUpdate();
+ if (player_node)
+ player_node->updateStatus();
+
Mana::Event::trigger(CHANNEL_GAME, Mana::Event(EVENT_GUIWINDOWSLOADED));
}
@@ -373,8 +376,7 @@ Game::Game():
// Create the viewport
viewport = new Viewport;
- viewport->setDimension(gcn::Rectangle(0, 0, mainGraphics->mWidth,
- mainGraphics->mHeight));
+ viewport->setSize(mainGraphics->mWidth, mainGraphics->mHeight);
gcn::Container *top = static_cast<gcn::Container*>(gui->getTop());
top->add(viewport);
@@ -490,7 +492,7 @@ static bool saveScreenshot()
filenameSuffix.str("");
filename.str("");
filename << screenshotDirectory << "/";
- filenameSuffix << branding.getValue("appShort", "ManaPlus")
+ filenameSuffix << branding.getValue("appName", "ManaPlus")
<< "_Screenshot_" << screenshotCount << ".png";
filename << filenameSuffix.str();
testExists.open(filename.str().c_str(), std::ios::in);
@@ -724,10 +726,10 @@ bool Game::handleOutfitsKeys(SDL_Event &event, bool &used)
{
bool wearOutfit = false;
bool copyOutfit = false;
- if (keyboard.isKeyActive(keyboard.KEY_WEAR_OUTFIT))
+ if (keyboard.isActionActive(keyboard.KEY_WEAR_OUTFIT))
wearOutfit = true;
- if (keyboard.isKeyActive(keyboard.KEY_COPY_OUTFIT))
+ if (keyboard.isActionActive(keyboard.KEY_COPY_OUTFIT))
copyOutfit = true;
if (wearOutfit || copyOutfit)
@@ -744,15 +746,15 @@ bool Game::handleOutfitsKeys(SDL_Event &event, bool &used)
}
else
{
- if (keyboard.isKeyActive(keyboard.KEY_MOVE_RIGHT))
+ if (keyboard.isActionActive(keyboard.KEY_MOVE_RIGHT))
outfitWindow->wearNextOutfit();
- else if (keyboard.isKeyActive(keyboard.KEY_MOVE_LEFT))
+ else if (keyboard.isActionActive(keyboard.KEY_MOVE_LEFT))
outfitWindow->wearPreviousOutfit();
}
setValidSpeed();
return true;
}
- else if (keyboard.isKeyActive(keyboard.KEY_MOVE_TO_POINT))
+ else if (keyboard.isActionActive(keyboard.KEY_MOVE_TO_POINT))
{
int num = outfitWindow->keyToNumber(
event.key.keysym.sym);
@@ -773,7 +775,7 @@ bool Game::handleSwitchKeys(SDL_Event &event, bool &used)
&& !player_node->getAway())
{
NpcDialog *dialog = NpcDialog::getActive();
- if (keyboard.isKeyActive(keyboard.KEY_OK)
+ if (keyboard.isActionActive(keyboard.KEY_OK)
&& (!dialog || !dialog->isTextInputFocused()))
{
// Close the Browser if opened
@@ -790,7 +792,7 @@ bool Game::handleSwitchKeys(SDL_Event &event, bool &used)
dialog->action(gcn::ActionEvent(nullptr, "ok"));
}
}
- if (chatWindow && keyboard.isKeyActive(
+ if (chatWindow && keyboard.isActionActive(
keyboard.KEY_TOGGLE_CHAT))
{
if (!InventoryWindow::isAnyInputFocused())
@@ -801,9 +803,9 @@ bool Game::handleSwitchKeys(SDL_Event &event, bool &used)
}
if (dialog)
{
- if (keyboard.isKeyActive(keyboard.KEY_MOVE_UP))
+ if (keyboard.isActionActive(keyboard.KEY_MOVE_UP))
dialog->move(1);
- else if (keyboard.isKeyActive(keyboard.KEY_MOVE_DOWN))
+ else if (keyboard.isActionActive(keyboard.KEY_MOVE_DOWN))
dialog->move(-1);
}
}
@@ -813,27 +815,27 @@ bool Game::handleSwitchKeys(SDL_Event &event, bool &used)
!InventoryWindow::isAnyInputFocused())
|| (event.key.keysym.mod & KMOD_ALT)))
{
- if (keyboard.isKeyActive(keyboard.KEY_PREV_CHAT_TAB))
+ if (keyboard.isActionActive(keyboard.KEY_PREV_CHAT_TAB))
{
chatWindow->prevTab();
return true;
}
- else if (keyboard.isKeyActive(keyboard.KEY_NEXT_CHAT_TAB))
+ else if (keyboard.isActionActive(keyboard.KEY_NEXT_CHAT_TAB))
{
chatWindow->nextTab();
return true;
}
- else if (keyboard.isKeyActive(keyboard.KEY_PREV_SOCIAL_TAB))
+ else if (keyboard.isActionActive(keyboard.KEY_PREV_SOCIAL_TAB))
{
socialWindow->prevTab();
return true;
}
- else if (keyboard.isKeyActive(keyboard.KEY_NEXT_SOCIAL_TAB))
+ else if (keyboard.isActionActive(keyboard.KEY_NEXT_SOCIAL_TAB))
{
socialWindow->nextTab();
return true;
}
- else if (keyboard.isKeyActive(keyboard.KEY_CLOSE_CHAT_TAB))
+ else if (keyboard.isActionActive(keyboard.KEY_CLOSE_CHAT_TAB))
{
chatWindow->closeTab();
return true;
@@ -963,9 +965,9 @@ bool Game::handleSwitchKeys(SDL_Event &event, bool &used)
case KeyboardConfig::KEY_MOVE_TO_TARGET:
if (player_node)
{
- if (!keyboard.isKeyActive(
+ if (!keyboard.isActionActive(
keyboard.KEY_TARGET_ATTACK)
- && !keyboard.isKeyActive(keyboard.KEY_ATTACK))
+ && !keyboard.isActionActive(keyboard.KEY_ATTACK))
{
player_node->moveToTarget();
}
@@ -975,9 +977,9 @@ bool Game::handleSwitchKeys(SDL_Event &event, bool &used)
case KeyboardConfig::KEY_MOVE_TO_HOME:
if (player_node)
{
- if (!keyboard.isKeyActive(
+ if (!keyboard.isActionActive(
keyboard.KEY_TARGET_ATTACK)
- && !keyboard.isKeyActive(keyboard.KEY_ATTACK))
+ && !keyboard.isActionActive(keyboard.KEY_ATTACK))
{
player_node->moveToHome();
}
@@ -1077,6 +1079,7 @@ bool Game::handleSwitchKeys(SDL_Event &event, bool &used)
if (player_node)
{
player_node->changeAwayMode();
+ player_node->updateStatus();
setValidSpeed();
}
break;
@@ -1099,8 +1102,8 @@ bool Game::handleSwitchKeys(SDL_Event &event, bool &used)
if (!NpcDialog::isAnyInputFocused()
&& !InventoryWindow::isAnyInputFocused()
- && !keyboard.isKeyActive(keyboard.KEY_TARGET)
- && !keyboard.isKeyActive(keyboard.KEY_UNTARGET))
+ && !keyboard.isActionActive(keyboard.KEY_TARGET)
+ && !keyboard.isActionActive(keyboard.KEY_UNTARGET))
{
if (setupWindow && setupWindow->isVisible())
{
@@ -1146,7 +1149,7 @@ bool Game::handleSwitchKeys(SDL_Event &event, bool &used)
// Player sit action
if (player_node)
{
- if (keyboard.isKeyActive(keyboard.KEY_EMOTE))
+ if (keyboard.isActionActive(keyboard.KEY_EMOTE))
player_node->updateSit();
else
player_node->toggleSit();
@@ -1319,8 +1322,8 @@ void Game::handleMoveAndAttack(SDL_Event &event, bool wasDown)
// Ignore input if either "ignore" key is pressed
// Stops the character moving about if the user's window manager
// uses "ignore+arrow key" to switch virtual desktops.
- if (keyboard.isKeyActive(keyboard.KEY_IGNORE_INPUT_1) ||
- keyboard.isKeyActive(keyboard.KEY_IGNORE_INPUT_2))
+ if (keyboard.isActionActive(keyboard.KEY_IGNORE_INPUT_1) ||
+ keyboard.isActionActive(keyboard.KEY_IGNORE_INPUT_2))
{
return;
}
@@ -1328,14 +1331,14 @@ void Game::handleMoveAndAttack(SDL_Event &event, bool wasDown)
unsigned char direction = 0;
// Translate pressed keys to movement and direction
- if (keyboard.isKeyActive(keyboard.KEY_MOVE_UP) ||
+ if (keyboard.isActionActive(keyboard.KEY_MOVE_UP) ||
(joystick && joystick->isUp()))
{
direction |= Being::UP;
setValidSpeed();
player_node->cancelFollow();
}
- else if (keyboard.isKeyActive(keyboard.KEY_MOVE_DOWN) ||
+ else if (keyboard.isActionActive(keyboard.KEY_MOVE_DOWN) ||
(joystick && joystick->isDown()))
{
direction |= Being::DOWN;
@@ -1343,23 +1346,23 @@ void Game::handleMoveAndAttack(SDL_Event &event, bool wasDown)
player_node->cancelFollow();
}
- if (keyboard.isKeyActive(keyboard.KEY_MOVE_LEFT) ||
+ if (keyboard.isActionActive(keyboard.KEY_MOVE_LEFT) ||
(joystick && joystick->isLeft()))
{
direction |= Being::LEFT;
setValidSpeed();
player_node->cancelFollow();
}
- else if (keyboard.isKeyActive(keyboard.KEY_MOVE_RIGHT) ||
+ else if (keyboard.isActionActive(keyboard.KEY_MOVE_RIGHT) ||
(joystick && joystick->isRight()))
{
direction |= Being::RIGHT;
setValidSpeed();
player_node->cancelFollow();
}
- else if (!keyboard.isKeyActive(keyboard.KEY_EMOTE))
+ else if (!keyboard.isActionActive(keyboard.KEY_EMOTE))
{
- if (keyboard.isKeyActive(keyboard.KEY_DIRECT_UP))
+ if (keyboard.isActionActive(keyboard.KEY_DIRECT_UP))
{
if (player_node->getDirection() != Being::UP)
{
@@ -1370,7 +1373,7 @@ void Game::handleMoveAndAttack(SDL_Event &event, bool wasDown)
}
}
}
- else if (keyboard.isKeyActive(keyboard.KEY_DIRECT_DOWN))
+ else if (keyboard.isActionActive(keyboard.KEY_DIRECT_DOWN))
{
if (player_node->getDirection() != Being::DOWN)
{
@@ -1381,7 +1384,7 @@ void Game::handleMoveAndAttack(SDL_Event &event, bool wasDown)
}
}
}
- else if (keyboard.isKeyActive(keyboard.KEY_DIRECT_LEFT))
+ else if (keyboard.isActionActive(keyboard.KEY_DIRECT_LEFT))
{
if (player_node->getDirection() != Being::LEFT)
{
@@ -1392,7 +1395,7 @@ void Game::handleMoveAndAttack(SDL_Event &event, bool wasDown)
}
}
}
- else if (keyboard.isKeyActive(keyboard.KEY_DIRECT_RIGHT))
+ else if (keyboard.isActionActive(keyboard.KEY_DIRECT_RIGHT))
{
if (player_node->getDirection() != Being::RIGHT)
{
@@ -1405,7 +1408,7 @@ void Game::handleMoveAndAttack(SDL_Event &event, bool wasDown)
}
}
- if (keyboard.isKeyActive(keyboard.KEY_EMOTE) && direction != 0)
+ if (keyboard.isActionActive(keyboard.KEY_EMOTE) && direction != 0)
{
if (player_node->getDirection() != direction)
{
@@ -1449,18 +1452,19 @@ void Game::handleMoveAndAttack(SDL_Event &event, bool wasDown)
|| joyAttack) && mValidSpeed)
{
// Attacking monsters
- if (keyboard.isKeyActive(keyboard.KEY_ATTACK))
+ if (keyboard.isActionActive(keyboard.KEY_ATTACK))
{
if (player_node->getTarget())
player_node->attack(player_node->getTarget(), true);
}
- if ((keyboard.isKeyActive(keyboard.KEY_TARGET_ATTACK) || joyAttack)
- && !keyboard.isKeyActive(keyboard.KEY_MOVE_TO_TARGET))
+ if ((keyboard.isActionActive(keyboard.KEY_TARGET_ATTACK)
+ || joyAttack)
+ && !keyboard.isActionActive(keyboard.KEY_MOVE_TO_TARGET))
{
Being *target = nullptr;
- bool newTarget = !keyboard.isKeyActive(keyboard.KEY_TARGET);
+ bool newTarget = !keyboard.isActionActive(keyboard.KEY_TARGET);
// A set target has highest priority
if (!player_node->getTarget())
{
@@ -1477,27 +1481,27 @@ void Game::handleMoveAndAttack(SDL_Event &event, bool wasDown)
}
}
- if (!keyboard.isKeyActive(keyboard.KEY_EMOTE))
+ if (!keyboard.isActionActive(keyboard.KEY_EMOTE))
{
// Target the nearest player/monster/npc
- if ((keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER) ||
- keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) ||
- keyboard.isKeyActive(keyboard.KEY_TARGET_NPC) ||
+ if ((keyboard.isActionActive(keyboard.KEY_TARGET_PLAYER) ||
+ keyboard.isActionActive(keyboard.KEY_TARGET_CLOSEST) ||
+ keyboard.isActionActive(keyboard.KEY_TARGET_NPC) ||
(joystick && joystick->buttonPressed(3))) &&
- !keyboard.isKeyActive(keyboard.KEY_TARGET) &&
- !keyboard.isKeyActive(keyboard.KEY_UNTARGET))
+ !keyboard.isActionActive(keyboard.KEY_TARGET) &&
+ !keyboard.isActionActive(keyboard.KEY_UNTARGET))
{
ActorSprite::Type currentTarget = ActorSprite::UNKNOWN;
- if (keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) ||
+ if (keyboard.isActionActive(keyboard.KEY_TARGET_CLOSEST) ||
(joystick && joystick->buttonPressed(3)))
{
currentTarget = ActorSprite::MONSTER;
}
- else if (keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER))
+ else if (keyboard.isActionActive(keyboard.KEY_TARGET_PLAYER))
{
currentTarget = ActorSprite::PLAYER;
}
- else if (keyboard.isKeyActive(keyboard.KEY_TARGET_NPC))
+ else if (keyboard.isActionActive(keyboard.KEY_TARGET_NPC))
{
currentTarget = ActorSprite::NPC;
}
@@ -1521,7 +1525,7 @@ void Game::handleMoveAndAttack(SDL_Event &event, bool wasDown)
// Talk to the nearest NPC if 't' pressed
if (wasDown && keyboard.getKeyIndex(event.key.keysym.sym)
== KeyboardConfig::KEY_TALK &&
- !keyboard.isKeyActive(keyboard.KEY_EMOTE))
+ !keyboard.isActionActive(keyboard.KEY_EMOTE))
{
Being *target = player_node->getTarget();
@@ -1535,15 +1539,15 @@ void Game::handleMoveAndAttack(SDL_Event &event, bool wasDown)
}
// Stop attacking if the right key is pressed
- if (!keyboard.isKeyActive(keyboard.KEY_ATTACK)
- && !keyboard.isKeyActive(keyboard.KEY_EMOTE))
+ if (!keyboard.isActionActive(keyboard.KEY_ATTACK)
+ && !keyboard.isActionActive(keyboard.KEY_EMOTE))
{
- if (keyboard.isKeyActive(keyboard.KEY_TARGET)
+ if (keyboard.isActionActive(keyboard.KEY_TARGET)
|| (joystick && joystick->buttonPressed(4)))
{
player_node->stopAttack();
}
- else if (keyboard.isKeyActive(keyboard.KEY_UNTARGET))
+ else if (keyboard.isActionActive(keyboard.KEY_UNTARGET))
{
player_node->untarget();
}
@@ -1585,6 +1589,8 @@ void Game::handleActive(SDL_Event &event)
player_node->setHalfAway(true);
}
}
+ if (player_node)
+ player_node->updateStatus();
}
if (player_node)
player_node->updateName();
@@ -1630,8 +1636,13 @@ void Game::handleInput()
updateHistory(event);
checkKeys();
+ if (event.type == SDL_VIDEORESIZE)
+ {
+ // Let the client deal with this one (it'll pass down from there)
+ Client::resize(event.resize.w, event.resize.h);
+ }
// Keyboard events (for discontinuous keys)
- if (event.type == SDL_KEYDOWN)
+ else if (event.type == SDL_KEYDOWN)
{
wasDown = true;
@@ -1661,7 +1672,7 @@ void Game::handleInput()
}
if (chatWindow && !chatWindow->isInputFocused()
- && keyboard.isKeyActive(keyboard.KEY_RIGHT_CLICK))
+ && keyboard.isActionActive(keyboard.KEY_RIGHT_CLICK))
{
int mouseX, mouseY;
SDL_GetMouseState(&mouseX, &mouseY);
@@ -1674,7 +1685,7 @@ void Game::handleInput()
}
// Mode switch to emotes
- if (keyboard.isKeyActive(keyboard.KEY_EMOTE))
+ if (keyboard.isActionActive(keyboard.KEY_EMOTE))
{
// Emotions
int emotion = keyboard.getKeyEmoteOffset(event.key.keysym.sym);
@@ -1728,8 +1739,8 @@ void Game::handleInput()
return;
// If pressed outfits keys, stop processing keys.
- if (keyboard.isKeyActive(keyboard.KEY_WEAR_OUTFIT)
- || keyboard.isKeyActive(keyboard.KEY_COPY_OUTFIT)
+ if (keyboard.isActionActive(keyboard.KEY_WEAR_OUTFIT)
+ || keyboard.isActionActive(keyboard.KEY_COPY_OUTFIT)
|| (setupWindow && setupWindow->isVisible()))
{
return;
@@ -1934,3 +1945,11 @@ void Game::closeDialogs()
deathNotice = nullptr;
}
}
+
+void Game::videoResized(int width, int height)
+{
+ if (viewport)
+ viewport->setSize(width, height);
+ if (windowMenu)
+ windowMenu->setPosition(width - 3 - windowMenu->getWidth(), 3);
+}
diff --git a/src/game.h b/src/game.h
index c6d942fe1..4469d3774 100644
--- a/src/game.h
+++ b/src/game.h
@@ -91,7 +91,7 @@ class Game
/**
* Returns the currently active map.
*/
- Map *getCurrentMap()
+ Map *getCurrentMap() const
{ return mCurrentMap; }
const std::string &getCurrentMapName() const
@@ -108,6 +108,8 @@ class Game
static void closeDialogs();
+ void videoResized(int width, int height);
+
private:
void updateHistory(SDL_Event &event);
diff --git a/src/graphics.cpp b/src/graphics.cpp
index bbd398aa5..5848d8c14 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -47,13 +47,15 @@ Graphics::Graphics():
mBlitMode(BLIT_NORMAL),
mRedraw(false),
mDoubleBuffer(false),
- mSecure(false)
+ mSecure(false),
+ mOpenGL(0),
+ mEnableResize(false),
+ mNoFrame(false)
{
mRect.x = 0;
mRect.y = 0;
mRect.w = 0;
mRect.h = 0;
- mOpenGL = 0;
}
Graphics::~Graphics()
@@ -61,7 +63,8 @@ Graphics::~Graphics()
_endDraw();
}
-bool Graphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
+bool Graphics::setVideoMode(int w, int h, int bpp, bool fs,
+ bool hwaccel, bool resize, bool noFrame)
{
logger->log("Setting video mode %dx%d %s",
w, h, fs ? "fullscreen" : "windowed");
@@ -73,15 +76,22 @@ bool Graphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
mBpp = bpp;
mFullscreen = fs;
mHWAccel = hwaccel;
+ mEnableResize = resize;
+ mNoFrame = noFrame;
if (fs)
displayFlags |= SDL_FULLSCREEN;
+ else if (resize)
+ displayFlags |= SDL_RESIZABLE;
if (hwaccel)
displayFlags |= SDL_HWSURFACE | SDL_DOUBLEBUF;
else
displayFlags |= SDL_SWSURFACE;
+ if (noFrame)
+ displayFlags |= SDL_NOFRAME;
+
setTarget(SDL_SetVideoMode(w, h, bpp, displayFlags));
if (!mTarget)
@@ -138,7 +148,37 @@ bool Graphics::setFullscreen(bool fs)
if (mFullscreen == fs)
return true;
- return setVideoMode(mWidth, mHeight, mBpp, fs, mHWAccel);
+ return setVideoMode(mWidth, mHeight, mBpp, fs, mHWAccel,
+ mEnableResize, mNoFrame);
+}
+
+bool Graphics::resizeScreen(int width, int height)
+{
+ if (mWidth == width && mHeight == height)
+ return true;
+
+ const int prevWidth = mWidth;
+ const int prevHeight = mHeight;
+
+ _endDraw();
+
+ bool success = setVideoMode(width, height, mBpp,
+ mFullscreen, mHWAccel, mEnableResize, mNoFrame);
+
+ // If it didn't work, try to restore the previous size. If that didn't
+ // work either, bail out (but then we're in deep trouble).
+ if (!success)
+ {
+ if (!setVideoMode(prevWidth, prevHeight, mBpp,
+ mFullscreen, mHWAccel, mEnableResize, mNoFrame))
+ {
+ return false;
+ }
+ }
+
+ _beginDraw();
+
+ return success;
}
int Graphics::getWidth() const
diff --git a/src/graphics.h b/src/graphics.h
index 4c47e690d..5d496d654 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -96,8 +96,8 @@ class Graphics : public gcn::SDLGraphics
/**
* Try to create a window with the given settings.
*/
- virtual bool setVideoMode(int w, int h, int bpp,
- bool fs, bool hwaccel);
+ virtual bool setVideoMode(int w, int h, int bpp, bool fs,
+ bool hwaccel, bool resize, bool noFrame);
/**
* Set fullscreen mode.
@@ -105,6 +105,11 @@ class Graphics : public gcn::SDLGraphics
bool setFullscreen(bool fs);
/**
+ * Resize the window to the specified size.
+ */
+ bool resizeScreen(int width, int height);
+
+ /**
* Blits an image onto the screen.
*
* @return <code>true</code> if the image was blitted properly
@@ -220,7 +225,7 @@ class Graphics : public gcn::SDLGraphics
void setBlitMode(BlitMode mode)
{ mBlitMode = mode; }
- BlitMode getBlitMode()
+ BlitMode getBlitMode() const
{ return mBlitMode; }
void fillRectangle(const gcn::Rectangle& rectangle);
@@ -258,30 +263,33 @@ class Graphics : public gcn::SDLGraphics
void setRedraw(bool n)
{ mRedraw = n; }
- bool getRedraw()
+ bool getRedraw() const
{ return mRedraw; }
void setSecure(bool n)
{ mSecure = n; }
- bool getSecure()
+ bool getSecure() const
{ return mSecure; }
- int getBpp()
+ int getBpp() const
{ return mBpp; }
- bool getFullScreen()
+ bool getFullScreen() const
{ return mFullscreen; }
- bool getHWAccel()
+ bool getHWAccel() const
{ return mHWAccel; }
- bool getDoubleBuffer()
+ bool getDoubleBuffer() const
{ return mDoubleBuffer; }
int getOpenGL()
{ return mOpenGL; }
+ void setNoFrame(bool n)
+ { mNoFrame = n; }
+
int mWidth;
int mHeight;
@@ -298,6 +306,8 @@ class Graphics : public gcn::SDLGraphics
SDL_Rect mRect;
bool mSecure;
int mOpenGL;
+ bool mEnableResize;
+ bool mNoFrame;
};
extern Graphics *mainGraphics;
diff --git a/src/graphicsvertexes.h b/src/graphicsvertexes.h
index 046bf90ce..4245e8bf5 100644
--- a/src/graphicsvertexes.h
+++ b/src/graphicsvertexes.h
@@ -153,7 +153,7 @@ class GraphicsVertexes
SDLGraphicsVertexes sdl[5];
#ifdef USE_OPENGL
- OpenGL1GraphicsVertexes ogl1[5];
+// OpenGL1GraphicsVertexes ogl1[5];
OpenGLGraphicsVertexes ogl[5];
#endif
diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp
index a1233fdcc..8d4767a15 100644
--- a/src/gui/charcreatedialog.cpp
+++ b/src/gui/charcreatedialog.cpp
@@ -47,6 +47,7 @@
#include "resources/chardb.h"
#include "resources/colordb.h"
#include "resources/itemdb.h"
+#include "resources/iteminfo.h"
#include "utils/gettext.h"
#include "utils/stringutils.h"
@@ -55,14 +56,27 @@
#include "debug.h"
+const static Being::Action actions[] =
+{
+ Being::STAND, Being::SIT, Being::MOVE, Being::ATTACK, Being::DEAD
+};
+
+const static int directions[] =
+{
+ Being::DOWN, Being::RIGHT, Being::UP, Being::LEFT
+};
+
CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot):
- Window(_("Create Character"), true, parent, "charcreate.xml"),
+ Window(_("New Character"), true, parent, "charcreate.xml"),
mCharSelectDialog(parent),
mRace(0),
- mSlot(slot)
+ mSlot(slot),
+ mAction(0),
+ mDirection(0)
{
setStickyButtonLock(true);
setSticky(true);
+ setWindowName("NewCharacter");
mPlayer = new Being(0, ActorSprite::PLAYER, mRace, nullptr);
mPlayer->setGender(GENDER_MALE);
@@ -79,9 +93,9 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot):
mHairStyle = (rand() % maxHairStyle) + minHairStyle;
mHairColor = (rand() % maxHairColor) + minHairColor;
- updateHair();
mNameField = new TextField("");
+ mNameField->setMaximum(24);
mNameLabel = new Label(_("Name:"));
// TRANSLATORS: This is a narrow symbol used to denote 'next'.
// You may change this symbol if your language uses another.
@@ -90,15 +104,20 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot):
// You may change this symbol if your language uses another.
mPrevHairColorButton = new Button(_("<"), "prevcolor", this);
mHairColorLabel = new Label(_("Hair color:"));
+ mHairColorNameLabel = new Label("");
mNextHairStyleButton = new Button(_(">"), "nextstyle", this);
mPrevHairStyleButton = new Button(_("<"), "prevstyle", this);
mHairStyleLabel = new Label(_("Hair style:"));
+ mHairStyleNameLabel = new Label("");
+ mActionButton = new Button(_("^"), "action", this);
+ mRotateButton = new Button(_(">"), "rotate", this);
if (serverVersion >= 2)
{
mNextRaceButton = new Button(_(">"), "nextrace", this);
mPrevRaceButton = new Button(_("<"), "prevrace", this);
mRaceLabel = new Label(_("Race:"));
+ mRaceNameLabel = new Label("");
}
mCreateButton = new Button(_("Create"), "create", this);
@@ -124,31 +143,42 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot):
mAttributesLeft = new Label(
strprintf(_("Please distribute %d points"), 99));
- int w = 280;
- int h = 330;
+ int w = 480;
+ int h = 350;
setContentSize(w, h);
- mPlayerBox->setDimension(gcn::Rectangle(145, 35, 110, 87));
- mNameLabel->setPosition(5, 5);
+ mPlayerBox->setDimension(gcn::Rectangle(350, 40, 110, 90));
+ mActionButton->setPosition(375, 140);
+ mRotateButton->setPosition(405, 140);
+
+ mNameLabel->setPosition(5, 10);
mNameField->setDimension(
- gcn::Rectangle(60, 5, w - 60 - 7, mNameField->getHeight()));
- mPrevHairColorButton->setPosition(155, 35);
- mNextHairColorButton->setPosition(230, 35);
- mHairColorLabel->setPosition(5, 40);
- mPrevHairStyleButton->setPosition(155, 64);
- mNextHairStyleButton->setPosition(230, 64);
- mHairStyleLabel->setPosition(5, 70);
+ gcn::Rectangle(60, 10, 300, mNameField->getHeight()));
+
+ int leftX = 120;
+ int rightX = 300;
+ int labelX = 5;
+ int nameX = 145;
+ mPrevHairColorButton->setPosition(leftX, 40);
+ mNextHairColorButton->setPosition(rightX, 40);
+ mHairColorLabel->setPosition(labelX, 45);
+ mHairColorNameLabel->setPosition(nameX, 45);
+ mPrevHairStyleButton->setPosition(leftX, 69);
+ mNextHairStyleButton->setPosition(rightX, 69);
+ mHairStyleLabel->setPosition(labelX, 74);
+ mHairStyleNameLabel->setPosition(nameX, 74);
if (serverVersion >= 2)
{
- mPrevRaceButton->setPosition(155, 93);
- mNextRaceButton->setPosition(230, 93);
- mRaceLabel->setPosition(5, 100);
+ mPrevRaceButton->setPosition(leftX, 103);
+ mNextRaceButton->setPosition(rightX, 103);
+ mRaceLabel->setPosition(labelX, 108);
+ mRaceNameLabel->setPosition(nameX, 108);
}
mAttributesLeft->setPosition(15, 280);
updateSliders();
mCancelButton->setPosition(
- w - 5 - mCancelButton->getWidth(),
+ w / 2,
h - 5 - mCancelButton->getHeight());
mCreateButton->setPosition(
mCancelButton->getX() - 5 - mCreateButton->getWidth(),
@@ -163,15 +193,20 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot):
add(mNextHairColorButton);
add(mPrevHairColorButton);
add(mHairColorLabel);
+ add(mHairColorNameLabel);
add(mNextHairStyleButton);
add(mPrevHairStyleButton);
add(mHairStyleLabel);
+ add(mHairStyleNameLabel);
+ add(mActionButton);
+ add(mRotateButton);
if (serverVersion >= 2)
{
add(mNextRaceButton);
add(mPrevRaceButton);
add(mRaceLabel);
+ add(mRaceNameLabel);
}
add(mAttributesLeft);
@@ -184,6 +219,12 @@ CharCreateDialog::CharCreateDialog(CharSelectDialog *parent, int slot):
center();
setVisible(true);
mNameField->requestFocus();
+
+ updateHair();
+ if (serverVersion >= 2)
+ updateRace();
+
+ updatePlayer();
}
CharCreateDialog::~CharCreateDialog()
@@ -197,7 +238,8 @@ CharCreateDialog::~CharCreateDialog()
void CharCreateDialog::action(const gcn::ActionEvent &event)
{
- if (event.getId() == "create")
+ const std::string id = event.getId();
+ if (id == "create")
{
if (
#ifdef MANASERV_SUPPORT
@@ -232,51 +274,65 @@ void CharCreateDialog::action(const gcn::ActionEvent &event)
true, this);
}
}
- else if (event.getId() == "cancel")
+ else if (id == "cancel")
{
scheduleDelete();
}
- else if (event.getId() == "nextcolor")
+ else if (id == "nextcolor")
{
- mHairColor++;
+ mHairColor ++;
updateHair();
}
- else if (event.getId() == "prevcolor")
+ else if (id == "prevcolor")
{
- mHairColor--;
+ mHairColor --;
updateHair();
}
- else if (event.getId() == "nextstyle")
+ else if (id == "nextstyle")
{
- mHairStyle++;
+ mHairStyle ++;
updateHair();
}
- else if (event.getId() == "prevstyle")
+ else if (id == "prevstyle")
{
- mHairStyle--;
+ mHairStyle --;
updateHair();
}
- else if (event.getId() == "nextrace")
+ else if (id == "nextrace")
{
- mRace++;
+ mRace ++;
updateRace();
}
- else if (event.getId() == "prevrace")
+ else if (id == "prevrace")
{
- mRace--;
+ mRace --;
updateRace();
}
- else if (event.getId() == "statslider")
+ else if (id == "statslider")
{
updateSliders();
}
- else if (event.getId() == "gender")
+ else if (id == "gender")
{
if (mMale->isSelected())
mPlayer->setGender(GENDER_MALE);
else
mPlayer->setGender(GENDER_FEMALE);
}
+ else if (id == "action")
+ {
+ mAction ++;
+ if (mAction >= 5)
+ mAction = 0;
+ updatePlayer();
+ }
+ else if (id == "rotate")
+ {
+ mDirection ++;
+ if (mDirection >= 4)
+ mDirection = 0;
+ updatePlayer();
+ }
}
std::string CharCreateDialog::getName() const
@@ -357,34 +413,34 @@ void CharCreateDialog::setAttributes(const std::vector<std::string> &labels,
mAttributeSlider.resize(labels.size());
mAttributeValue.resize(labels.size());
- int w = 200;
- int h = 330;
+ int w = 480;
+ int h = 350;
for (unsigned i = 0; i < labels.size(); i++)
{
mAttributeLabel[i] = new Label(labels[i]);
mAttributeLabel[i]->setWidth(70);
- mAttributeLabel[i]->setPosition(5, 140 + i*20);
+ mAttributeLabel[i]->setPosition(5, 145 + i * 24);
mAttributeLabel[i]->adjustSize();
add(mAttributeLabel[i]);
mAttributeSlider[i] = new Slider(min, max);
- mAttributeSlider[i]->setDimension(gcn::Rectangle(140, 140 + i * 20,
- 100, 10));
+ mAttributeSlider[i]->setDimension(gcn::Rectangle(140, 145 + i * 24,
+ 150, 12));
mAttributeSlider[i]->setActionEventId("statslider");
mAttributeSlider[i]->addActionListener(this);
add(mAttributeSlider[i]);
mAttributeValue[i] = new Label(toString(min));
- mAttributeValue[i]->setPosition(245, 140 + i*20);
+ mAttributeValue[i]->setPosition(295, 145 + i * 24);
add(mAttributeValue[i]);
}
- mAttributesLeft->setPosition(15, 280);
+ mAttributesLeft->setPosition(15, 300);
updateSliders();
mCancelButton->setPosition(
- w - 5 - mCancelButton->getWidth(),
+ w / 2,
h - 5 - mCancelButton->getHeight());
mCreateButton->setPosition(
mCancelButton->getX() - 5 - mCreateButton->getWidth(),
@@ -420,12 +476,17 @@ void CharCreateDialog::updateHair()
mHairStyle += Being::getNumOfHairstyles();
if (mHairStyle < (signed)minHairStyle || mHairStyle > (signed)maxHairStyle)
mHairStyle = minHairStyle;
+ const ItemInfo &item = ItemDB::get(-mHairStyle);
+ mHairStyleNameLabel->setCaption(item.getName());
+ mHairStyleNameLabel->adjustSize();
mHairColor %= ColorDB::getHairSize();
if (mHairColor < 0)
mHairColor += ColorDB::getHairSize();
if (mHairColor < (signed)minHairColor || mHairColor > (signed)maxHairColor)
mHairColor = minHairColor;
+ mHairColorNameLabel->setCaption(ColorDB::getHairColorName(mHairColor));
+ mHairColorNameLabel->adjustSize();
mPlayer->setSprite(Net::getCharHandler()->hairSprite(),
mHairStyle * -1, ColorDB::getHairColor(mHairColor));
@@ -448,4 +509,22 @@ void CharCreateDialog::updateRace()
}
mPlayer->setSubtype(mRace);
+ const ItemInfo &item = ItemDB::get(id);
+ mRaceNameLabel->setCaption(item.getName());
+ mRaceNameLabel->adjustSize();
+}
+
+void CharCreateDialog::logic()
+{
+ if (mPlayer)
+ mPlayer->logic();
+}
+
+void CharCreateDialog::updatePlayer()
+{
+ if (mPlayer)
+ {
+ mPlayer->setDirection(directions[mDirection]);
+ mPlayer->setAction(actions[mAction]);
+ }
}
diff --git a/src/gui/charcreatedialog.h b/src/gui/charcreatedialog.h
index e369f1777..ceafcc08e 100644
--- a/src/gui/charcreatedialog.h
+++ b/src/gui/charcreatedialog.h
@@ -37,6 +37,7 @@
class LocalPlayer;
class PlayerBox;
+class TextField;
/**
* Character creation dialog.
@@ -69,6 +70,10 @@ class CharCreateDialog : public Window, public gcn::ActionListener
void setFixedGender(bool fixed, Gender gender = GENDER_FEMALE);
+ void logic();
+
+ void updatePlayer();
+
private:
int getDistributedPoints() const;
@@ -90,17 +95,23 @@ class CharCreateDialog : public Window, public gcn::ActionListener
CharSelectDialog *mCharSelectDialog;
- gcn::TextField *mNameField;
+ TextField *mNameField;
gcn::Label *mNameLabel;
gcn::Button *mNextHairColorButton;
gcn::Button *mPrevHairColorButton;
gcn::Label *mHairColorLabel;
+ gcn::Label *mHairColorNameLabel;
gcn::Button *mNextHairStyleButton;
gcn::Button *mPrevHairStyleButton;
gcn::Label *mHairStyleLabel;
+ gcn::Label *mHairStyleNameLabel;
gcn::Button *mNextRaceButton;
gcn::Button *mPrevRaceButton;
gcn::Label *mRaceLabel;
+ gcn::Label *mRaceNameLabel;
+
+ gcn::Button *mActionButton;
+ gcn::Button *mRotateButton;
gcn::RadioButton *mMale;
gcn::RadioButton *mFemale;
@@ -129,6 +140,9 @@ class CharCreateDialog : public Window, public gcn::ActionListener
unsigned minHairColor;
unsigned maxHairStyle;
unsigned minHairStyle;
+
+ unsigned mAction;
+ unsigned mDirection;
};
#endif // CHAR_CREATE_DIALOG_H
diff --git a/src/gui/charselectdialog.cpp b/src/gui/charselectdialog.cpp
index 638691bab..d2b74a632 100644
--- a/src/gui/charselectdialog.cpp
+++ b/src/gui/charselectdialog.cpp
@@ -386,7 +386,7 @@ bool CharSelectDialog::selectByName(const std::string &name,
Net::Character *character = mCharacterEntries[i]->getCharacter();
if (mCharacterEntries[i] && character)
{
- if (character->dummy->getName() == name)
+ if ( character->dummy && character->dummy->getName() == name)
{
if (mCharacterEntries[i])
mCharacterEntries[i]->requestFocus();
diff --git a/src/gui/chatwindow.cpp b/src/gui/chatwindow.cpp
index 899bbdc36..6831ad5b6 100644
--- a/src/gui/chatwindow.cpp
+++ b/src/gui/chatwindow.cpp
@@ -548,6 +548,9 @@ void ChatWindow::removeTab(ChatTab *tab)
void ChatWindow::addTab(ChatTab *tab)
{
+ if (!tab)
+ return;
+
mChatTabs->addTab(tab, tab->mScrollArea);
// Update UI
@@ -764,18 +767,18 @@ void ChatWindow::keyPressed(gcn::KeyEvent &event)
mCurHist = mHistory.end();
mChatInput->setText("");
}
- else if (keyboard.isKeyActive(keyboard.KEY_AUTOCOMPLETE_CHAT) &&
+ else if (keyboard.isActionActive(keyboard.KEY_AUTOCOMPLETE_CHAT) &&
mChatInput->getText() != "")
{
autoComplete();
return;
}
- else if (keyboard.isKeyActive(keyboard.KEY_DEACTIVATE_CHAT) &&
+ else if (keyboard.isActionActive(keyboard.KEY_DEACTIVATE_CHAT) &&
mChatInput->isVisible())
{
mChatInput->processVisible(false);
}
- else if (keyboard.isKeyActive(keyboard.KEY_CHAT_PREV_HISTORY) &&
+ else if (keyboard.isActionActive(keyboard.KEY_CHAT_PREV_HISTORY) &&
mChatInput->isVisible())
{
ChatTab *tab = getFocused();
@@ -807,7 +810,7 @@ void ChatWindow::keyPressed(gcn::KeyEvent &event)
mChatInput->getText().length()));
}
}
- else if (keyboard.isKeyActive(keyboard.KEY_CHAT_NEXT_HISTORY) &&
+ else if (keyboard.isActionActive(keyboard.KEY_CHAT_NEXT_HISTORY) &&
mChatInput->isVisible())
{
ChatTab *tab = getFocused();
diff --git a/src/gui/editdialog.h b/src/gui/editdialog.h
index 69f86edca..ef260acfb 100644
--- a/src/gui/editdialog.h
+++ b/src/gui/editdialog.h
@@ -57,7 +57,7 @@ class EditDialog : public Window, public gcn::ActionListener
*/
void action(const gcn::ActionEvent &event);
- std::string getMsg()
+ std::string getMsg() const
{ return mTextField->getText(); }
private:
diff --git a/src/gui/editserverdialog.cpp b/src/gui/editserverdialog.cpp
new file mode 100644
index 000000000..8a4a9579d
--- /dev/null
+++ b/src/gui/editserverdialog.cpp
@@ -0,0 +1,239 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2011-2012 The Mana Developers
+ * Copyright (C) 2012 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gui/editserverdialog.h"
+
+#include "configuration.h"
+
+#include "gui/okdialog.h"
+#include "gui/sdlinput.h"
+#include "gui/serverdialog.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/dropdown.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/layout.h"
+#include "gui/widgets/textfield.h"
+
+#include "utils/gettext.h"
+
+std::string TypeListModel::getElementAt(int elementIndex)
+{
+ if (elementIndex == 0)
+ return "TmwAthena";
+ else if (elementIndex == 1)
+ return "Evol";
+#ifdef MANASERV_SUPPORT
+ else if (elementIndex == 2)
+ return "ManaServ";
+#endif
+ else
+ return "Unknown";
+}
+
+EditServerDialog::EditServerDialog(ServerDialog *parent, ServerInfo server,
+ int index) :
+ Window(_("Edit Server"), true, parent),
+ mServerDialog(parent),
+ mServer(server),
+ mIndex(index)
+{
+ setWindowName("EditServerDialog");
+
+ Label *nameLabel = new Label(_("Name:"));
+ Label *serverAdressLabel = new Label(_("Address:"));
+ Label *portLabel = new Label(_("Port:"));
+ Label *typeLabel = new Label(_("Server type:"));
+ Label *descriptionLabel = new Label(_("Description:"));
+ mServerAddressField = new TextField(std::string());
+ mPortField = new TextField(std::string());
+ mPortField->setNumeric(true);
+ mPortField->setRange(1, 65535);
+
+ mTypeListModel = new TypeListModel();
+ mTypeField = new DropDown(mTypeListModel);
+ mTypeField->setSelected(0); // TmwAthena by default for now.
+
+ mNameField = new TextField(std::string());
+ mDescriptionField = new TextField(std::string());
+
+ mOkButton = new Button(_("OK"), "addServer", this);
+ mCancelButton = new Button(_("Cancel"), "cancel", this);
+
+ mServerAddressField->addActionListener(this);
+ mPortField->addActionListener(this);
+
+ place(0, 0, nameLabel);
+ place(1, 0, mNameField, 4).setPadding(3);
+ place(0, 1, serverAdressLabel);
+ place(1, 1, mServerAddressField, 4).setPadding(3);
+ place(0, 2, portLabel);
+ place(1, 2, mPortField, 4).setPadding(3);
+ place(0, 3, typeLabel);
+ place(1, 3, mTypeField).setPadding(3);
+ place(0, 4, descriptionLabel);
+ place(1, 4, mDescriptionField, 4).setPadding(3);
+ place(4, 5, mOkButton);
+ place(3, 5, mCancelButton);
+
+ // Do this manually instead of calling reflowLayout so we can enforce a
+ // minimum width.
+ int width = 0, height = 0;
+ getLayout().reflow(width, height);
+ if (width < 300)
+ {
+ width = 300;
+ getLayout().reflow(width, height);
+ }
+ if (height < 120)
+ {
+ height = 120;
+ getLayout().reflow(width, height);
+ }
+
+ setContentSize(width, height);
+
+ setMinWidth(getWidth());
+ setMinHeight(getHeight());
+ setDefaultSize(getWidth(), getHeight(), ImageRect::CENTER);
+
+ setResizable(false);
+ addKeyListener(this);
+
+ loadWindowState();
+
+ mNameField->setText(mServer.name);
+ mDescriptionField->setText(mServer.description);
+ mServerAddressField->setText(mServer.hostname);
+ mPortField->setText(toString(mServer.port));
+
+ switch (mServer.type)
+ {
+ case ServerInfo::MANASERV:
+#ifdef MANASERV_SUPPORT
+ mTypeField->setSelected(2);
+ break;
+#endif
+ default:
+ case ServerInfo::UNKNOWN:
+ case ServerInfo::TMWATHENA:
+ mTypeField->setSelected(0);
+ break;
+ case ServerInfo::EVOL:
+ mTypeField->setSelected(1);
+ break;
+ }
+
+ setLocationRelativeTo(getParentWindow());
+ setVisible(true);
+
+ mNameField->requestFocus();
+}
+
+EditServerDialog::~EditServerDialog()
+{
+ delete mTypeListModel;
+}
+
+void EditServerDialog::logic()
+{
+ Window::logic();
+}
+
+void EditServerDialog::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok")
+ {
+ // Give focus back to the server dialog.
+ mServerAddressField->requestFocus();
+ }
+ if (event.getId() == "addServer")
+ {
+ // Check the given information
+ if (mServerAddressField->getText().empty()
+ || mPortField->getText().empty())
+ {
+ OkDialog *dlg = new OkDialog(_("Error"),
+ _("Please at least type both the address and the port "
+ "of the server."));
+ dlg->addActionListener(this);
+ }
+ else
+ {
+ mCancelButton->setEnabled(false);
+ mOkButton->setEnabled(false);
+
+ mServer.name = mNameField->getText();
+ mServer.description = mDescriptionField->getText();
+ mServer.hostname = mServerAddressField->getText();
+ mServer.port = (short) atoi(mPortField->getText().c_str());
+
+ if (mTypeField)
+ {
+ switch (mTypeField->getSelected())
+ {
+ case 0:
+ mServer.type = ServerInfo::TMWATHENA;
+ break;
+ case 1:
+ mServer.type = ServerInfo::EVOL;
+ break;
+#ifdef MANASERV_SUPPORT
+ case 2:
+ mServer.type = ServerInfo::MANASERV;
+ break;
+#endif
+ default:
+ mServer.type = ServerInfo::UNKNOWN;
+ }
+ }
+ else
+ {
+ mServer.type = ServerInfo::TMWATHENA;
+ }
+
+ // Tell the server has to be saved
+ mServer.save = true;
+
+ //Add server
+ mServerDialog->updateServer(mServer, mIndex);
+ scheduleDelete();
+ }
+ }
+ else if (event.getId() == "cancel")
+ {
+ scheduleDelete();
+ }
+}
+
+void EditServerDialog::keyPressed(gcn::KeyEvent &keyEvent)
+{
+ gcn::Key key = keyEvent.getKey();
+
+ if (key.getValue() == Key::ESCAPE)
+ {
+ scheduleDelete();
+ }
+ else if (key.getValue() == Key::ENTER)
+ {
+ action(gcn::ActionEvent(nullptr, mOkButton->getActionEventId()));
+ }
+}
diff --git a/src/gui/editserverdialog.h b/src/gui/editserverdialog.h
new file mode 100644
index 000000000..6035b0e50
--- /dev/null
+++ b/src/gui/editserverdialog.h
@@ -0,0 +1,104 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2011-2012 The Mana Developers
+ * Copyright (C) 2012 The ManaPlus Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef EDITSERVERDIALOG_H
+#define EDITSERVERDIALOG_H
+
+class Button;
+class Label;
+class TextField;
+class DropDown;
+class ServerDialog;
+class TypeListModel;
+
+#include "gui/widgets/window.h"
+
+#include "net/serverinfo.h"
+
+#include <guichan/actionlistener.hpp>
+#include <guichan/keylistener.hpp>
+#include <guichan/listmodel.hpp>
+
+
+/**
+ * Server Type List Model
+ */
+class TypeListModel : public gcn::ListModel
+{
+ public:
+ TypeListModel() {}
+
+ /**
+ * Used to get number of line in the list
+ */
+ int getNumberOfElements()
+#ifdef MANASERV_SUPPORT
+ { return 3; }
+#else
+ { return 2; }
+#endif
+
+ /**
+ * Used to get an element from the list
+ */
+ std::string getElementAt(int elementIndex);
+};
+
+/**
+ * The custom server addition dialog.
+ *
+ * \ingroup Interface
+ */
+class EditServerDialog : public Window,
+ public gcn::ActionListener,
+ public gcn::KeyListener
+{
+ public:
+ EditServerDialog(ServerDialog *parent, ServerInfo server, int index);
+
+ ~EditServerDialog();
+
+ /**
+ * Called when receiving actions from the widgets.
+ */
+ void action(const gcn::ActionEvent &event);
+
+ void keyPressed(gcn::KeyEvent &keyEvent);
+
+ void logic();
+
+ private:
+ TextField *mServerAddressField;
+ TextField *mPortField;
+ TextField *mNameField;
+ TextField *mDescriptionField;
+ Button *mOkButton;
+ Button *mCancelButton;
+
+ DropDown *mTypeField;
+ TypeListModel *mTypeListModel;
+
+ ServerDialog *mServerDialog;
+ ServerInfo mServer;
+ int mIndex;
+};
+
+#endif // EDITSERVERDIALOG_H
diff --git a/src/gui/equipmentwindow.h b/src/gui/equipmentwindow.h
index daeaeb3d7..1e7b84533 100644
--- a/src/gui/equipmentwindow.h
+++ b/src/gui/equipmentwindow.h
@@ -84,7 +84,7 @@ class EquipmentWindow : public Window, public gcn::ActionListener
void mousePressed(gcn::MouseEvent& mouseEvent);
- Item* getEquipment(int i)
+ Item* getEquipment(int i) const
{ return mEquipment ? mEquipment->getEquipment(i) : nullptr; }
void setBeing(Being *being);
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index bd855a598..1d8b45872 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -99,20 +99,19 @@ Gui::Gui(Graphics *graphics):
// Initialize top GUI widget
WindowContainer *guiTop = new WindowContainer;
guiTop->setFocusable(true);
- guiTop->setDimension(gcn::Rectangle(0, 0,
- graphics->mWidth, graphics->mHeight));
+ guiTop->setSize(graphics->mWidth, graphics->mHeight);
guiTop->setOpaque(false);
Window::setWindowContainer(guiTop);
setTop(guiTop);
+ const std::vector<std::string> langs = getLang();
+ const bool isJapan = (!langs.empty() && langs[0].size() > 3
+ && langs[0].substr(0, 3) == "ja_");
+
// Set global font
const int fontSize = config.getIntValue("fontSize");
-
std::string fontFile = config.getValue("font", "");
-
- std::vector<std::string> langs = getLang();
- if (!langs.empty() && langs[0].size() > 3
- && langs[0].substr(0, 3) == "ja_")
+ if (isJapan)
{
fontFile = config.getValue("japanFont", "");
if (fontFile.empty())
@@ -134,6 +133,15 @@ Gui::Gui(Graphics *graphics):
// Set particle font
fontFile = config.getValue("particleFont", "");
+
+ if (isJapan)
+ {
+ fontFile = config.getValue("japanFont", "");
+ if (fontFile.empty())
+ fontFile = branding.getStringValue("japanFont");
+ }
+
+
if (fontFile.empty())
fontFile = branding.getStringValue("particleFont");
@@ -278,6 +286,20 @@ void Gui::draw()
mGraphics->popClipArea();
}
+void Gui::videoResized()
+{
+ WindowContainer *top = static_cast<WindowContainer*>(getTop());
+
+ if (top)
+ {
+ int oldWidth = top->getWidth();
+ int oldHeight = top->getHeight();
+
+ top->setSize(mainGraphics->mWidth, mainGraphics->mHeight);
+ top->adjustAfterResize(oldWidth, oldHeight);
+ }
+}
+
void Gui::setUseCustomCursor(bool customCursor)
{
if (customCursor != mCustomCursor)
diff --git a/src/gui/gui.h b/src/gui/gui.h
index cadcc89ac..5ace42323 100644
--- a/src/gui/gui.h
+++ b/src/gui/gui.h
@@ -70,6 +70,11 @@ class Gui : public gcn::Gui
*/
void draw();
+ /**
+ * Called when the application window has been resized.
+ */
+ void videoResized();
+
gcn::FocusHandler *getFocusHandler() const
{ return mFocusHandler; }
diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp
index 01e2bdd17..23f1e6fcf 100644
--- a/src/gui/inventorywindow.cpp
+++ b/src/gui/inventorywindow.cpp
@@ -340,13 +340,13 @@ void InventoryWindow::action(const gcn::ActionEvent &event)
{
if (isStorageActive())
{
- Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
+ Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY,
item->getInvIndex(), item->getQuantity(),
Inventory::STORAGE);
}
else
{
- if (keyboard.isKeyActive(keyboard.KEY_MOD))
+ if (keyboard.isActionActive(keyboard.KEY_MOD))
{
Net::getInventoryHandler()->dropItem(
item, item->getQuantity());
@@ -386,11 +386,11 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event)
{
Window::mouseClicked(event);
- const bool mod = (isStorageActive() && keyboard.isKeyActive(
+ const bool mod = (isStorageActive() && keyboard.isActionActive(
keyboard.KEY_MOD));
const bool mod2 = (tradeWindow && tradeWindow->isVisible()
- && keyboard.isKeyActive(keyboard.KEY_MOD));
+ && keyboard.isActionActive(keyboard.KEY_MOD));
if (!mod && !mod2 && event.getButton() == gcn::MouseEvent::RIGHT)
{
@@ -431,7 +431,7 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event)
}
else
{
- Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
+ Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY,
item->getInvIndex(), item->getQuantity(),
Inventory::STORAGE);
}
@@ -445,7 +445,7 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event)
}
else
{
- Net::getInventoryHandler()->moveItem(Inventory::STORAGE,
+ Net::getInventoryHandler()->moveItem2(Inventory::STORAGE,
item->getInvIndex(), item->getQuantity(),
Inventory::INVENTORY);
}
diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h
index 2b35ec9c4..9d4be5afc 100644
--- a/src/gui/inventorywindow.h
+++ b/src/gui/inventorywindow.h
@@ -115,7 +115,7 @@ class InventoryWindow : public Window,
void slotsChanged(Inventory* inventory);
- bool isMainInventory()
+ bool isMainInventory() const
{ return mInventory->isMainInventory(); }
/**
diff --git a/src/gui/itemamountwindow.cpp b/src/gui/itemamountwindow.cpp
index 9e2a97681..3b01b559f 100644
--- a/src/gui/itemamountwindow.cpp
+++ b/src/gui/itemamountwindow.cpp
@@ -113,14 +113,12 @@ void ItemAmountWindow::finish(Item *item, int amount, int price, Usage usage)
Net::getInventoryHandler()->splitItem(item, amount);
break;
case StoreAdd:
- Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
- item->getInvIndex(), amount,
- Inventory::STORAGE);
+ Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY,
+ item->getInvIndex(), amount, Inventory::STORAGE);
break;
case StoreRemove:
- Net::getInventoryHandler()->moveItem(Inventory::STORAGE,
- item->getInvIndex(), amount,
- Inventory::INVENTORY);
+ Net::getInventoryHandler()->moveItem2(Inventory::STORAGE,
+ item->getInvIndex(), amount, Inventory::INVENTORY);
break;
case ShopBuyAdd:
if (shopWindow)
diff --git a/src/gui/logindialog.cpp b/src/gui/logindialog.cpp
index b1c80b102..ef8fd6bf0 100644
--- a/src/gui/logindialog.cpp
+++ b/src/gui/logindialog.cpp
@@ -88,6 +88,7 @@ LoginDialog::LoginDialog(LoginData *data, std::string serverName,
mUpdateHost(updateHost),
mServerName(serverName)
{
+
gcn::Label *serverLabel1 = new Label(_("Server:"));
gcn::Label *serverLabel2 = new Label(serverName);
serverLabel2->adjustSize();
@@ -131,12 +132,11 @@ LoginDialog::LoginDialog(LoginData *data, std::string serverName,
mPassField->addActionListener(this);
place(0, 0, serverLabel1);
- place(1, 0, serverLabel2, 8).setPadding(1);
-
+ place(1, 0, serverLabel2, 8);
place(0, 1, userLabel);
place(0, 2, passLabel);
- place(1, 1, mUserField, 8).setPadding(1);
- place(1, 2, mPassField, 8).setPadding(1);
+ place(1, 1, mUserField, 8);
+ place(1, 2, mPassField, 8);
place(0, 6, mUpdateTypeLabel, 1);
place(1, 6, mUpdateTypeDropDown, 8);
place(0, 7, mCustomUpdateHost, 9);
@@ -146,9 +146,8 @@ LoginDialog::LoginDialog(LoginData *data, std::string serverName,
place(2, 10, mServerButton);
place(3, 10, mLoginButton);
- reflowLayout();
-
addKeyListener(this);
+ setContentSize(300, 200);
center();
setVisible(true);
@@ -178,7 +177,8 @@ void LoginDialog::action(const gcn::ActionEvent &event)
mLoginData->remember = mKeepCheck->isSelected();
int updateType = mUpdateTypeDropDown->getSelected();
- if (mCustomUpdateHost->isSelected())
+ if (mCustomUpdateHost->isSelected()
+ && mUpdateHostText->getText().empty())
{
updateType |= LoginData::Upd_Custom;
serverConfig.setValue("customUpdateHost",
diff --git a/src/gui/npcdialog.cpp b/src/gui/npcdialog.cpp
index 265748b6f..3e5b30a9c 100644
--- a/src/gui/npcdialog.cpp
+++ b/src/gui/npcdialog.cpp
@@ -26,6 +26,7 @@
#include "client.h"
#include "gui/setup.h"
+#include "gui/viewport.h"
#include "gui/widgets/browserbox.h"
#include "gui/widgets/button.h"
@@ -62,7 +63,10 @@ NpcDialog::NpcDialog(int npcId) :
mDefaultInt(0),
mInputState(NPC_INPUT_NONE),
mActionState(NPC_ACTION_WAIT),
- mLastNextTime(0)
+ mLastNextTime(0),
+ mCameraMode(-1),
+ mCameraX(0),
+ mCameraY(0)
{
// Basic Window Setup
setWindowName("NpcText");
@@ -220,6 +224,7 @@ void NpcDialog::action(const gcn::ActionEvent &event)
return;
nextDialog();
+ addText(std::string(), false);
}
else if (mActionState == NPC_ACTION_CLOSE
|| mActionState == NPC_ACTION_WAIT)
@@ -301,6 +306,7 @@ void NpcDialog::nextDialog()
void NpcDialog::closeDialog()
{
+ restoreCamera();
Net::getNpcHandler()->closeDialog(mNpcId);
}
@@ -504,4 +510,34 @@ void NpcDialog::buildLayout()
redraw();
mScrollArea->setVerticalScrollAmount(mScrollArea->getVerticalMaxScroll());
-} \ No newline at end of file
+}
+
+void NpcDialog::saveCamera()
+{
+ if (!viewport || mCameraMode >= 0)
+ return;
+
+ mCameraMode = viewport->getCameraMode();
+ mCameraX = viewport->getCameraRelativeX();
+ mCameraY = viewport->getCameraRelativeY();
+}
+
+void NpcDialog::restoreCamera()
+{
+ if (!viewport || mCameraMode == -1)
+ return;
+
+ if (!mCameraMode)
+ {
+ if (viewport->getCameraMode() != mCameraMode)
+ viewport->toggleCameraMode();
+ }
+ else
+ {
+ if (viewport->getCameraMode() != mCameraMode)
+ viewport->toggleCameraMode();
+ viewport->setCameraRelativeX(mCameraX);
+ viewport->setCameraRelativeY(mCameraY);
+ }
+ mCameraMode = -1;
+}
diff --git a/src/gui/npcdialog.h b/src/gui/npcdialog.h
index e76897499..d4288d5c9 100644
--- a/src/gui/npcdialog.h
+++ b/src/gui/npcdialog.h
@@ -154,7 +154,8 @@ class NpcDialog : public Window, public gcn::ActionListener,
/**
* Returns true if any instances exist.
*/
- static bool isActive() { return !instances.empty(); }
+ static bool isActive()
+ { return !instances.empty(); }
/**
* Returns the first active instance. Useful for pushing user
@@ -172,6 +173,10 @@ class NpcDialog : public Window, public gcn::ActionListener,
*/
static void destroyAll();
+ void saveCamera();
+
+ void restoreCamera();
+
private:
typedef std::list<NpcDialog*> DialogList;
static DialogList instances;
@@ -230,6 +235,9 @@ class NpcDialog : public Window, public gcn::ActionListener,
NpcInputState mInputState;
NpcActionState mActionState;
int mLastNextTime;
+ int mCameraMode;
+ int mCameraX;
+ int mCameraY;
};
#endif // NPCDIALOG_H
diff --git a/src/gui/outfitwindow.cpp b/src/gui/outfitwindow.cpp
index 74e8dbe46..73484f1d5 100644
--- a/src/gui/outfitwindow.cpp
+++ b/src/gui/outfitwindow.cpp
@@ -491,375 +491,32 @@ void OutfitWindow::unequipNotInOutfit(int outfit)
}
}
+static const SDLKey numsTbl[] =
+{
+ SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, SDLK_7, SDLK_8, SDLK_9,
+ SDLK_0, SDLK_MINUS, SDLK_EQUALS, SDLK_BACKSPACE, SDLK_INSERT, SDLK_HOME,
+ SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, SDLK_i, SDLK_o,
+ SDLK_p, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, SDLK_BACKSLASH, SDLK_a,
+ SDLK_s, SDLK_d, SDLK_f, SDLK_g, SDLK_h, SDLK_j, SDLK_k, SDLK_l,
+ SDLK_SEMICOLON, SDLK_QUOTE, SDLK_z, SDLK_x, SDLK_c, SDLK_v, SDLK_b, SDLK_n,
+ SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH
+};
+
int OutfitWindow::keyToNumber(SDLKey key) const
{
- int outfitNum = -1;
- switch (key)
+ for (unsigned f = 0; f < sizeof(numsTbl) / sizeof(SDLKey); f ++)
{
- case SDLK_1:
- case SDLK_2:
- case SDLK_3:
- case SDLK_4:
- case SDLK_5:
- case SDLK_6:
- case SDLK_7:
- case SDLK_8:
- case SDLK_9:
- outfitNum = key - SDLK_1;
- break;
-
- case SDLK_0:
- outfitNum = 9;
- break;
-
- case SDLK_MINUS:
- outfitNum = 10;
- break;
-
- case SDLK_EQUALS:
- outfitNum = 11;
- break;
-
- case SDLK_BACKSPACE:
- outfitNum = 12;
- break;
-
- case SDLK_INSERT:
- outfitNum = 13;
- break;
-
- case SDLK_HOME:
- outfitNum = 14;
- break;
-
- case SDLK_q:
- outfitNum = 15;
- break;
-
- case SDLK_w:
- outfitNum = 16;
- break;
-
- case SDLK_e:
- outfitNum = 17;
- break;
-
- case SDLK_r:
- outfitNum = 18;
- break;
-
- case SDLK_t:
- outfitNum = 19;
- break;
-
- case SDLK_y:
- outfitNum = 20;
- break;
-
- case SDLK_u:
- outfitNum = 21;
- break;
-
- case SDLK_i:
- outfitNum = 22;
- break;
-
- case SDLK_o:
- outfitNum = 23;
- break;
-
- case SDLK_p:
- outfitNum = 24;
- break;
-
- case SDLK_LEFTBRACKET:
- outfitNum = 25;
- break;
-
- case SDLK_RIGHTBRACKET:
- outfitNum = 26;
- break;
-
- case SDLK_BACKSLASH:
- outfitNum = 27;
- break;
-
- case SDLK_a:
- outfitNum = 28;
- break;
-
- case SDLK_s:
- outfitNum = 29;
- break;
-
- case SDLK_d:
- outfitNum = 30;
- break;
-
- case SDLK_f:
- outfitNum = 31;
- break;
-
- case SDLK_g:
- outfitNum = 32;
- break;
-
- case SDLK_h:
- outfitNum = 33;
- break;
-
- case SDLK_j:
- outfitNum = 34;
- break;
-
- case SDLK_k:
- outfitNum = 35;
- break;
-
- case SDLK_l:
- outfitNum = 36;
- break;
-
- case SDLK_SEMICOLON:
- outfitNum = 37;
- break;
-
- case SDLK_QUOTE:
- outfitNum = 38;
- break;
-
- case SDLK_z:
- outfitNum = 39;
- break;
-
-
- case SDLK_x:
- outfitNum = 40;
- break;
-
- case SDLK_c:
- outfitNum = 41;
- break;
-
- case SDLK_v:
- outfitNum = 42;
- break;
-
- case SDLK_b:
- outfitNum = 43;
- break;
-
- case SDLK_n:
- outfitNum = 44;
- break;
-
- case SDLK_m:
- outfitNum = 45;
- break;
-
- case SDLK_COMMA:
- outfitNum = 46;
- break;
-
- case SDLK_PERIOD:
- outfitNum = 47;
- break;
-
- case SDLK_SLASH:
- outfitNum = 48;
- break;
-
- default:
- break;
+ if (numsTbl[f] == key)
+ return f;
}
-
- return outfitNum;
+ return -1;
}
-SDLKey OutfitWindow::numberToKey(int number) const
+SDLKey OutfitWindow::numberToKey(unsigned number) const
{
- SDLKey key = SDLK_UNKNOWN;
- switch (number)
- {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- key = static_cast<SDLKey>(
- static_cast<unsigned int>(SDLK_1) + number);
- break;
-
- case 9:
- key = SDLK_0;
- break;
-
- case 10:
- key = SDLK_MINUS;
- break;
-
- case 11:
- key = SDLK_EQUALS;
- break;
-
- case 12:
- key = SDLK_BACKSPACE;
- break;
-
- case 13:
- key = SDLK_INSERT;
- break;
-
- case 14:
- key = SDLK_HOME;
- break;
-
- case 15:
- key = SDLK_q;
- break;
-
- case 16:
- key = SDLK_w;
- break;
-
- case 17:
- key = SDLK_e;
- break;
-
- case 18:
- key = SDLK_r;
- break;
-
- case 19:
- key = SDLK_t;
- break;
-
- case 20:
- key = SDLK_y;
- break;
-
- case 21:
- key = SDLK_u;
- break;
-
- case 22:
- key = SDLK_i;
- break;
-
- case 23:
- key = SDLK_o;
- break;
-
- case 24:
- key = SDLK_p;
- break;
-
- case 25:
- key = SDLK_LEFTBRACKET;
- break;
-
- case 26:
- key = SDLK_RIGHTBRACKET;
- break;
-
- case 27:
- key = SDLK_BACKSLASH;
- break;
-
- case 28:
- key = SDLK_a;
- break;
-
- case 29:
- key = SDLK_s;
- break;
-
- case 30:
- key = SDLK_d;
- break;
-
- case 31:
- key = SDLK_f;
- break;
-
- case 32:
- key = SDLK_g;
- break;
-
- case 33:
- key = SDLK_h;
- break;
-
- case 34:
- key = SDLK_j;
- break;
-
- case 35:
- key = SDLK_k;
- break;
-
- case 36:
- key = SDLK_l;
- break;
-
- case 37:
- key = SDLK_SEMICOLON;
- break;
-
- case 38:
- key = SDLK_QUOTE;
- break;
-
- case 39:
- key = SDLK_z;
- break;
-
-
- case 40:
- key = SDLK_x;
- break;
-
- case 41:
- key = SDLK_c;
- break;
-
- case 42:
- key = SDLK_v;
- break;
-
- case 43:
- key = SDLK_b;
- break;
-
- case 44:
- key = SDLK_n;
- break;
-
- case 45:
- key = SDLK_m;
- break;
-
- case 46:
- key = SDLK_COMMA;
- break;
-
- case 47:
- key = SDLK_PERIOD;
- break;
-
- case 48:
- key = SDLK_SLASH;
- break;
-
- default:
- break;
- }
-
- return key;
+ if (number >= sizeof(numsTbl) / sizeof(SDLKey))
+ return SDLK_UNKNOWN;
+ return numsTbl[number];
}
std::string OutfitWindow::keyName(int number)
diff --git a/src/gui/outfitwindow.h b/src/gui/outfitwindow.h
index b2b46c7e7..6f67c472d 100644
--- a/src/gui/outfitwindow.h
+++ b/src/gui/outfitwindow.h
@@ -72,7 +72,7 @@ class OutfitWindow : public Window, gcn::ActionListener
void setItemSelected(Item *item);
- bool isItemSelected()
+ bool isItemSelected() const
{ return mItemSelected > 0; }
void wearOutfit(int outfit, bool unwearEmpty = true,
@@ -90,7 +90,7 @@ class OutfitWindow : public Window, gcn::ActionListener
int keyToNumber(SDLKey key) const A_PURE;
- SDLKey numberToKey(int number) const A_PURE;
+ SDLKey numberToKey(unsigned number) const A_PURE;
void next();
diff --git a/src/gui/palette.h b/src/gui/palette.h
index 36d87e305..7d5d93830 100644
--- a/src/gui/palette.h
+++ b/src/gui/palette.h
@@ -98,9 +98,7 @@ class Palette
* @return the gradient type of the color with the given index
*/
inline GradientType getGradientType(int type) const
- {
- return mColors[type].grad;
- }
+ { return mColors[type].grad; }
/**
* Get the character used by the specified color.
@@ -110,9 +108,7 @@ class Palette
* @return the color char of the color with the given index
*/
inline char getColorChar(int type) const
- {
- return mColors[type].ch;
- }
+ { return mColors[type].ch; }
/**
* Gets the gradient delay for the specified type.
@@ -122,7 +118,7 @@ class Palette
* @return the gradient delay of the color with the given index
*/
inline int getGradientDelay(int type) const
- { return mColors[type].delay; }
+ { return mColors[type].delay; }
/**
* Updates all colors, that are non-static.
diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp
index cd3a4c5ad..142acc69c 100644
--- a/src/gui/popupmenu.cpp
+++ b/src/gui/popupmenu.cpp
@@ -1184,19 +1184,19 @@ void PopupMenu::handleLink(const std::string &link,
int cnt = 10;
if (cnt > mItem->getQuantity())
cnt = mItem->getQuantity();
- Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
+ Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY,
mItem->getInvIndex(), cnt,
Inventory::STORAGE);
}
else if (link == "store half" && mItem)
{
- Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
+ Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY,
mItem->getInvIndex(), mItem->getQuantity() / 2,
Inventory::STORAGE);
}
else if (link == "store all" && mItem)
{
- Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
+ Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY,
mItem->getInvIndex(), mItem->getQuantity(),
Inventory::STORAGE);
}
@@ -1235,19 +1235,19 @@ void PopupMenu::handleLink(const std::string &link,
int cnt = 10;
if (cnt > mItem->getQuantity())
cnt = mItem->getQuantity();
- Net::getInventoryHandler()->moveItem(Inventory::STORAGE,
+ Net::getInventoryHandler()->moveItem2(Inventory::STORAGE,
mItem->getInvIndex(), cnt,
Inventory::INVENTORY);
}
else if (link == "retrieve half" && mItem)
{
- Net::getInventoryHandler()->moveItem(Inventory::STORAGE,
+ Net::getInventoryHandler()->moveItem2(Inventory::STORAGE,
mItem->getInvIndex(), mItem->getQuantity() / 2,
Inventory::INVENTORY);
}
else if (link == "retrieve all" && mItem)
{
- Net::getInventoryHandler()->moveItem(Inventory::STORAGE,
+ Net::getInventoryHandler()->moveItem2(Inventory::STORAGE,
mItem->getInvIndex(), mItem->getQuantity(),
Inventory::INVENTORY);
}
diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp
index 39ff19a89..59bdf9660 100644
--- a/src/gui/serverdialog.cpp
+++ b/src/gui/serverdialog.cpp
@@ -28,6 +28,7 @@
#include "logger.h"
#include "main.h"
+#include "gui/editserverdialog.h"
#include "gui/gui.h"
#include "gui/logindialog.h"
#include "gui/okdialog.h"
@@ -117,8 +118,8 @@ std::string ServersListModel::getElementAt(int elementIndex)
const ServerInfo &server = mServers->at(elementIndex);
std::string myServer;
myServer += server.hostname;
- myServer += ":";
- myServer += toString(server.port);
+// myServer += ":";
+// myServer += toString(server.port);
return myServer;
}
@@ -138,20 +139,6 @@ void ServersListModel::setVersionString(int index, const std::string &version)
}
}
-std::string TypeListModel::getElementAt(int elementIndex)
-{
- if (elementIndex == 0)
- return "TmwAthena";
- else if (elementIndex == 1)
- return "Evol";
-#ifdef MANASERV_SUPPORT
- else if (elementIndex == 2)
- return "ManaServ";
-#endif
- else
- return "Unknown";
-}
-
class ServersListBox : public ListBox
{
public:
@@ -196,20 +183,24 @@ public:
graphics->setColor(mTextColor);
int top;
+ int x = 2;
if (!info.name.empty())
{
graphics->setFont(boldFont);
+ x += boldFont->getWidth(info.name) + 15;
graphics->drawText(info.name, 2, y);
- top = y + height / 2;
+ top = y + boldFont->getHeight() + 2;
}
else
{
- top = y + height / 4;
+ top = y + height / 4 + 2;
}
graphics->setFont(getFont());
+ if (!info.description.empty())
+ graphics->drawText(info.description, x, y);
graphics->drawText(model->getElementAt(i), 2, top);
if (info.version.first > 0)
@@ -224,7 +215,7 @@ public:
unsigned int getRowHeight() const
{
- return 2 * getFont()->getHeight();
+ return 2 * getFont()->getHeight() + 5;
}
private:
gcn::Color mHighlightColor;
@@ -249,11 +240,6 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir):
setWindowName("ServerDialog");
- Label *serverLabel = new Label(_("Server:"));
- Label *portLabel = new Label(_("Port:"));
-
- mServerNameField = new TextField(mServerInfo->hostname);
- mPortField = new TextField(toString(mServerInfo->port));
mPersistentIPCheckBox = new CheckBox(_("Use same ip for game sub servers"),
config.getBoolValue("usePersistentIP"),
this, "persitent ip");
@@ -268,66 +254,33 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir):
ScrollArea *usedScroll = new ScrollArea(mServersList);
usedScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
- Label *typeLabel = new Label(_("Server type:"));
- mTypeListModel = new TypeListModel();
- mTypeField = new DropDown(mTypeListModel);
- switch (serverInfo->type)
- {
- case ServerInfo::MANASERV:
-#ifdef MANASERV_SUPPORT
- mTypeField->setSelected(2);
- break;
-#endif
- default:
- case ServerInfo::UNKNOWN:
- case ServerInfo::TMWATHENA:
- mTypeField->setSelected(0);
- break;
- case ServerInfo::EVOL:
- mTypeField->setSelected(1);
- break;
- }
- int n = 1;
+ int n = 0;
mDescription = new Label(std::string());
mQuitButton = new Button(_("Quit"), "quit", this);
mLoadButton = new Button(_("Load"), "load", this);
mConnectButton = new Button(_("Connect"), "connect", this);
- mManualEntryButton = new Button(_("Custom Server"), "addEntry", this);
+ mAddEntryButton = new Button(_("Add"), "addEntry", this);
+ mEditEntryButton = new Button(_("Edit"), "editEntry", this);
mDeleteButton = new Button(_("Delete"), "remove", this);
- mServerNameField->setActionEventId("connect");
- mPortField->setActionEventId("connect");
-
- mServerNameField->addActionListener(this);
- mPortField->addActionListener(this);
- mManualEntryButton->addActionListener(this);
mServersList->addSelectionListener(this);
usedScroll->setVerticalScrollAmount(0);
- place(0, 0, serverLabel);
- place(1, 0, mServerNameField, 5).setPadding(3);
- place(0, 1, portLabel);
- place(1, 1, mPortField, 5).setPadding(3);
- place(0, 2, typeLabel);
- place(1, 2, mTypeField, 5).setPadding(3);
- place(0, 2 + n, usedScroll, 6, 5).setPadding(3);
- place(0, 7 + n, mDescription, 6);
- place(0, 8 + n, mPersistentIPCheckBox, 6);
- place(0, 9 + n, mManualEntryButton);
- place(1, 9 + n, mDeleteButton);
- place(2, 9 + n, mLoadButton);
- place(4, 9 + n, mQuitButton);
- place(5, 9 + n, mConnectButton);
+ place(0, 0 + n, usedScroll, 7, 5).setPadding(3);
+ place(0, 5 + n, mDescription, 7);
+ place(0, 6 + n, mPersistentIPCheckBox, 7);
+ place(0, 7 + n, mAddEntryButton);
+ place(1, 7 + n, mEditEntryButton);
+ place(2, 7 + n, mLoadButton);
+ place(3, 7 + n, mDeleteButton);
+ place(5, 7 + n, mQuitButton);
+ place(6, 7 + n, mConnectButton);
// Make sure the list has enough height
- getLayout().setRowHeight(3, 80);
+ getLayout().setRowHeight(0, 80);
-/*
- reflowLayout(400, 300);
- setDefaultSize(400, 300, ImageRect::CENTER);
-*/
// Do this manually instead of calling reflowLayout so we can enforce a
// minimum width.
int width = 0, height = 0;
@@ -349,21 +302,10 @@ ServerDialog::ServerDialog(ServerInfo *serverInfo, const std::string &dir):
loadWindowState();
- setFieldsReadOnly(true);
mServersList->setSelected(0); // Do this after for the Delete button
setVisible(true);
- if (mServerNameField->getText().empty())
- {
- mServerNameField->requestFocus();
- }
- else
- {
- if (mPortField->getText().empty())
- mPortField->requestFocus();
- else
- mConnectButton->requestFocus();
- }
+ mConnectButton->requestFocus();
loadServers(true);
@@ -381,82 +323,48 @@ ServerDialog::~ServerDialog()
}
delete mServersListModel;
mServersListModel = nullptr;
- delete mTypeListModel;
- mTypeListModel = nullptr;
}
void ServerDialog::action(const gcn::ActionEvent &event)
{
- if (event.getId() == "ok")
- {
- // Give focus back to the server dialog.
- mServerNameField->requestFocus();
- }
- else if (event.getId() == "connect")
+ if (event.getId() == "connect")
{
- // Check login
- if (mServerNameField->getText().empty()
- || mPortField->getText().empty())
- {
- OkDialog *dlg = new OkDialog(_("Error"),
- _("Please type both the address and the port of a server."));
- dlg->addActionListener(this);
- }
- else
- {
- if (mDownload)
- mDownload->cancel();
-
- mQuitButton->setEnabled(false);
- mConnectButton->setEnabled(false);
- mLoadButton->setEnabled(false);
+ if (Client::getState() == STATE_CONNECT_SERVER)
+ return;
- mServerInfo->hostname = mServerNameField->getText();
- mServerInfo->port = static_cast<short>(
- atoi(mPortField->getText().c_str()));
+ if (mDownload)
+ mDownload->cancel();
- if (mTypeField)
- {
- switch (mTypeField->getSelected())
- {
- case 0:
- mServerInfo->type = ServerInfo::TMWATHENA;
- break;
- case 1:
- mServerInfo->type = ServerInfo::EVOL;
- break;
-#ifdef MANASERV_SUPPORT
- case 2:
- mServerInfo->type = ServerInfo::MANASERV;
- break;
-#endif
- default:
- mServerInfo->type = ServerInfo::UNKNOWN;
- }
- }
- else
- {
- mServerInfo->type = ServerInfo::TMWATHENA;
- }
+ mQuitButton->setEnabled(false);
+ mConnectButton->setEnabled(false);
+ mLoadButton->setEnabled(false);
- // Save the selected server
- mServerInfo->save = true;
+ int index = mServersList->getSelected();
+ if (index < 0)
+ return;
- if (chatLogger)
- chatLogger->setServerName(mServerInfo->hostname);
+ ServerInfo server = mServers.at(index);
+ mServerInfo->hostname = server.hostname;
+ mServerInfo->port = server.port;
+ mServerInfo->type = server.type;
+ mServerInfo->name = server.name;
+ mServerInfo->description = server.description;
+ mServerInfo->save = true;
- saveCustomServers(*mServerInfo);
+ if (chatLogger)
+ chatLogger->setServerName(mServerInfo->hostname);
- if (!LoginDialog::savedPasswordKey.empty())
- {
- if (mServerInfo->hostname != LoginDialog::savedPasswordKey)
- LoginDialog::savedPassword = "";
- }
+ saveCustomServers(*mServerInfo);
- config.setValue("usePersistentIP",
- mPersistentIPCheckBox->isSelected());
- Client::setState(STATE_CONNECT_SERVER);
+ if (!LoginDialog::savedPasswordKey.empty())
+ {
+ if (mServerInfo->hostname != LoginDialog::savedPasswordKey)
+ LoginDialog::savedPassword = "";
}
+
+ config.setValue("usePersistentIP",
+ mPersistentIPCheckBox->isSelected());
+ Client::setState(STATE_CONNECT_SERVER);
}
else if (event.getId() == "quit")
{
@@ -470,15 +378,23 @@ void ServerDialog::action(const gcn::ActionEvent &event)
}
else if (event.getId() == "addEntry")
{
- setFieldsReadOnly(false);
+ new EditServerDialog(this, ServerInfo(), -1);
+ }
+ else if (event.getId() == "editEntry")
+ {
+ int index = mServersList->getSelected();
+ if (index >= 0)
+ new EditServerDialog(this, mServers.at(index), index);
}
else if (event.getId() == "remove")
{
int index = mServersList->getSelected();
- mServersList->setSelected(0);
- mServers.erase(mServers.begin() + index);
-
- saveCustomServers();
+ if (index >= 0)
+ {
+ mServersList->setSelected(0);
+ mServers.erase(mServers.begin() + index);
+ saveCustomServers();
+ }
}
}
@@ -503,34 +419,6 @@ void ServerDialog::valueChanged(const gcn::SelectionEvent &)
// Update the server and post fields according to the new selection
const ServerInfo &myServer = mServersListModel->getServer(index);
- mDescription->setCaption(myServer.description);
- mServerNameField->setText(myServer.hostname);
- mPortField->setText(toString(myServer.port));
- if (mTypeField)
- {
- switch (myServer.type)
- {
- case ServerInfo::TMWATHENA:
- case ServerInfo::UNKNOWN:
-#ifdef MANASERV_SUPPORT
- default:
- mTypeField->setSelected(0);
- break;
- case ServerInfo::MANASERV:
- mTypeField->setSelected(2);
- break;
-#else
- case ServerInfo::MANASERV:
- default:
- mTypeField->setSelected(0);
- break;
-#endif
- case ServerInfo::EVOL:
- mTypeField->setSelected(1);
- break;
- }
- }
- setFieldsReadOnly(true);
mDeleteButton->setEnabled(myServer.save);
}
@@ -577,30 +465,6 @@ void ServerDialog::logic()
Window::logic();
}
-void ServerDialog::setFieldsReadOnly(bool readOnly)
-{
- if (!readOnly)
- {
- mDescription->setCaption(std::string());
- mServersList->setSelected(-1);
-
- mServerNameField->setText(std::string());
- mPortField->setText(std::string("6901"));
-
- mServerNameField->requestFocus();
- }
-
- mManualEntryButton->setEnabled(readOnly);
- mDeleteButton->setEnabled(false);
- mLoadButton->setEnabled(readOnly);
- mDescription->setVisible(readOnly);
-
- mServerNameField->setEnabled(!readOnly);
- mPortField->setEnabled(!readOnly);
- if (mTypeField)
- mTypeField->setEnabled(!readOnly);
-}
-
void ServerDialog::downloadServerList()
{
// Try to load the configuration value for the onlineServerList
@@ -647,6 +511,9 @@ void ServerDialog::loadServers(bool addNew)
return;
}
+ const std::string lang = getLangShort();
+ const std::string description2 = "description_" + lang;
+
for_each_xml_child_node(serverNode, rootNode)
{
if (!xmlNameEqual(serverNode, "server"))
@@ -696,7 +563,9 @@ void ServerDialog::loadServers(bool addNew)
server.port = defaultPortForServerType(server.type);
}
}
- else if (xmlNameEqual(subNode, "description"))
+ else if ((xmlNameEqual(subNode, "description")
+ && server.description.empty()) || (!lang.empty()
+ && xmlNameEqual(subNode, description2.c_str())))
{
server.description = reinterpret_cast<const char*>(
subNode->xmlChildrenNode->content);
@@ -716,6 +585,7 @@ void ServerDialog::loadServers(bool addNew)
// Use the name listed in the server list
mServers[i].name = server.name;
mServers[i].version = server.version;
+ mServers[i].description = server.description;
mServersListModel->setVersionString(i, version);
found = true;
break;
@@ -731,12 +601,16 @@ void ServerDialog::loadCustomServers()
for (int i = 0; i < MAX_SERVERLIST; ++i)
{
const std::string index = toString(i);
- const std::string nameKey = "MostUsedServerName" + index;
+ const std::string nameKey = "MostUsedServerDescName" + index;
+ const std::string descKey = "MostUsedServerDescription" + index;
+ const std::string hostKey = "MostUsedServerName" + index;
const std::string typeKey = "MostUsedServerType" + index;
const std::string portKey = "MostUsedServerPort" + index;
ServerInfo server;
- server.hostname = config.getValue(nameKey, "");
+ server.name = config.getValue(nameKey, "");
+ server.description = config.getValue(descKey, "");
+ server.hostname = config.getValue(hostKey, "");
server.type = ServerInfo::parseType(config.getValue(typeKey, ""));
const int defaultPort = defaultPortForServerType(server.type);
@@ -752,21 +626,29 @@ void ServerDialog::loadCustomServers()
}
}
-void ServerDialog::saveCustomServers(const ServerInfo &currentServer)
+void ServerDialog::saveCustomServers(const ServerInfo &currentServer,
+ int index)
{
// Make sure the current server is mentioned first
if (currentServer.isValid())
{
- ServerInfos::iterator i, i_end = mServers.end();
- for (i = mServers.begin(); i != i_end; ++i)
+ if (index >= 0 && (unsigned)index < mServers.size())
{
- if (*i == currentServer)
+ mServers[index] = currentServer;
+ }
+ else
+ {
+ ServerInfos::iterator i, i_end = mServers.end();
+ for (i = mServers.begin(); i != i_end; ++i)
{
- mServers.erase(i);
- break;
+ if (*i == currentServer)
+ {
+ mServers.erase(i);
+ break;
+ }
}
+ mServers.insert(mServers.begin(), currentServer);
}
- mServers.insert(mServers.begin(), currentServer);
}
int savedServerCount = 0;
@@ -780,15 +662,19 @@ void ServerDialog::saveCustomServers(const ServerInfo &currentServer)
if (!(server.save && server.isValid()))
continue;
- const std::string index = toString(savedServerCount);
- const std::string nameKey = "MostUsedServerName" + index;
- const std::string typeKey = "MostUsedServerType" + index;
- const std::string portKey = "MostUsedServerPort" + index;
+ const std::string num = toString(savedServerCount);
+ const std::string nameKey = "MostUsedServerDescName" + num;
+ const std::string descKey = "MostUsedServerDescription" + num;
+ const std::string hostKey = "MostUsedServerName" + num;
+ const std::string typeKey = "MostUsedServerType" + num;
+ const std::string portKey = "MostUsedServerPort" + num;
- config.setValue(nameKey, toString(server.hostname));
+ config.setValue(nameKey, toString(server.name));
+ config.setValue(descKey, toString(server.description));
+ config.setValue(hostKey, toString(server.hostname));
config.setValue(typeKey, serverTypeToString(server.type));
config.setValue(portKey, toString(server.port));
- ++savedServerCount;
+ ++ savedServerCount;
}
// Insert an invalid entry at the end to make the loading stop there
@@ -799,7 +685,7 @@ void ServerDialog::saveCustomServers(const ServerInfo &currentServer)
int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status,
size_t total, size_t remaining)
{
- if (status == DOWNLOAD_STATUS_CANCELLED)
+ if (!ptr || status == DOWNLOAD_STATUS_CANCELLED)
return -1;
ServerDialog *sd = reinterpret_cast<ServerDialog*>(ptr);
@@ -853,3 +739,8 @@ int ServerDialog::downloadUpdate(void *ptr, DownloadStatus status,
return 0;
}
+
+void ServerDialog::updateServer(ServerInfo server, int index)
+{
+ saveCustomServers(server, index);
+}
diff --git a/src/gui/serverdialog.h b/src/gui/serverdialog.h
index d2fe0d25b..c23fb8776 100644
--- a/src/gui/serverdialog.h
+++ b/src/gui/serverdialog.h
@@ -83,30 +83,6 @@ class ServersListModel : public gcn::ListModel
ServerDialog *mParent;
};
-/**
- * Server Type List Model
- */
-class TypeListModel : public gcn::ListModel
-{
- public:
- TypeListModel() {}
-
- /**
- * Used to get number of line in the list
- */
- int getNumberOfElements()
-#ifdef MANASERV_SUPPORT
- { return 3; }
-#else
- { return 2; }
-#endif
-
- /**
- * Used to get an element from the list
- */
- std::string getElementAt(int elementIndex);
-};
-
/**
* The server choice dialog.
@@ -147,12 +123,17 @@ class ServerDialog : public Window,
void logic();
+ void updateServer(ServerInfo server, int index);
+
protected:
friend class ServersListModel;
+
MutexLocker lock()
{ return MutexLocker(&mMutex); }
private:
+ friend class EditServerDialog;
+
/**
* Called to load a list of available server from an online xml file.
*/
@@ -160,28 +141,23 @@ class ServerDialog : public Window,
void loadServers(bool addNew = true);
void loadCustomServers();
- void saveCustomServers(const ServerInfo &currentServer = ServerInfo());
+ void saveCustomServers(const ServerInfo &currentServer = ServerInfo(),
+ int index = -1);
static int downloadUpdate(void *ptr, DownloadStatus status,
size_t total, size_t remaining);
- void setFieldsReadOnly(bool readOnly);
-
- TextField *mServerNameField;
- TextField *mPortField;
Label *mDescription;
Button *mQuitButton;
Button *mConnectButton;
- Button *mManualEntryButton;
+ Button *mAddEntryButton;
+ Button *mEditEntryButton;
Button *mDeleteButton;
Button *mLoadButton;
ListBox *mServersList;
ServersListModel *mServersListModel;
- DropDown *mTypeField;
- TypeListModel *mTypeListModel;
-
const std::string &mDir;
enum ServerDialogDownloadStatus
diff --git a/src/gui/setup.cpp b/src/gui/setup.cpp
index bac474950..3408fba33 100644
--- a/src/gui/setup.cpp
+++ b/src/gui/setup.cpp
@@ -75,7 +75,7 @@ Setup::Setup():
nullptr
};
int x = width;
- for (const char **curBtn = buttonNames; *curBtn; ++curBtn)
+ for (const char **curBtn = buttonNames; *curBtn; ++ curBtn)
{
Button *btn = new Button(gettext(*curBtn), *curBtn, this);
x -= btn->getWidth() + 5;
diff --git a/src/gui/setup_relations.cpp b/src/gui/setup_relations.cpp
index 9ddef9e1a..571856a14 100644
--- a/src/gui/setup_relations.cpp
+++ b/src/gui/setup_relations.cpp
@@ -193,6 +193,8 @@ public:
std::string getPlayerAt(int index) const
{
+ if (index < 0 || index >= (signed)mPlayers->size())
+ return "";
return (*mPlayers)[index];
}
@@ -257,10 +259,7 @@ Setup_Relations::Setup_Relations():
mIgnoreActionChoicesBox = new DropDown(mIgnoreActionChoicesModel);
for (int i = 0; i < COLUMNS_NR; i++)
- {
- mPlayerTableTitleModel->set(0, i,
- new Label(gettext(table_titles[i])));
- }
+ mPlayerTableTitleModel->set(0, i, new Label(gettext(table_titles[i])));
mPlayerTitleTable->setLinewiseSelection(true);
diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp
index 259388fd0..9a5b30ea7 100644
--- a/src/gui/setup_video.cpp
+++ b/src/gui/setup_video.cpp
@@ -143,11 +143,11 @@ ModeListModel::ModeListModel()
}
else
{
- for (int i = 0; modes[i]; ++i)
+ for (int i = 0; modes[i]; ++ i)
{
const std::string modeString =
toString(static_cast<int>(modes[i]->w)) + "x"
- + toString(static_cast<int>(modes[i]->h));
+ + toString(static_cast<int>(modes[i]->h));
mVideoModes.push_back(modeString);
}
}
@@ -281,6 +281,8 @@ Setup_Video::Setup_Video():
mOpacity(config.getFloatValue("guialpha")),
mFps(config.getIntValue("fpslimit")),
mAltFps(config.getIntValue("altfpslimit")),
+ mEnableResize(config.getBoolValue("enableresize")),
+ mNoFrame(config.getBoolValue("noframe")),
mSpeechMode(static_cast<Being::Speech>(
config.getIntValue("speech"))),
mModeListModel(new ModeListModel),
@@ -296,6 +298,8 @@ Setup_Video::Setup_Video():
// TRANSLATORS: Refers to "Show own name"
mPickupParticleCheckBox(new CheckBox(_("as particle"),
mPickupParticleEnabled)),
+ mEnableResizeCheckBox(new CheckBox(_("Enable resize"), mEnableResize)),
+ mNoFrameCheckBox(new CheckBox(_("No frame"), mNoFrame)),
mSpeechSlider(new Slider(0, 3)),
mSpeechLabel(new Label("")),
mAlphaSlider(new Slider(0.1, 1.0)),
@@ -367,6 +371,8 @@ Setup_Video::Setup_Video():
mParticleDetailSlider->setActionEventId("particledetailslider");
mParticleDetailField->setActionEventId("particledetailfield");
mOpenGLDropDown->setActionEventId("opengl");
+ mEnableResizeCheckBox->setActionEventId("enableresize");
+ mNoFrameCheckBox->setActionEventId("noframe");
mModeList->addActionListener(this);
mCustomCursorCheckBox->addActionListener(this);
@@ -383,6 +389,8 @@ Setup_Video::Setup_Video():
mParticleDetailSlider->addActionListener(this);
mParticleDetailField->addKeyListener(this);
mOpenGLDropDown->addActionListener(this);
+ mEnableResizeCheckBox->addActionListener(this);
+ mNoFrameCheckBox->addActionListener(this);
mSpeechLabel->setCaption(speechModeToString(mSpeechMode));
mSpeechSlider->setValue(mSpeechMode);
@@ -397,8 +405,8 @@ Setup_Video::Setup_Video():
LayoutHelper h(this);
ContainerPlacer place = h.getPlacer(0, 0);
- place(0, 0, scrollArea, 1, 5).setPadding(2);
- place(0, 5, mOpenGLDropDown, 1);
+ place(0, 0, scrollArea, 1, 6).setPadding(2);
+ place(0, 6, mOpenGLDropDown, 1);
// place(0, 6, mHwAccelCheckBox, 6);
@@ -406,34 +414,36 @@ Setup_Video::Setup_Video():
place(1, 1, mCustomCursorCheckBox, 3);
- place(1, 2, mParticleEffectsCheckBox, 2);
+ place(1, 2, mEnableResizeCheckBox, 2);
+ place(1, 3, mNoFrameCheckBox, 2);
- place(1, 3, mPickupNotifyLabel, 4);
+ place(1, 4, mParticleEffectsCheckBox, 2);
- place(1, 4, mPickupChatCheckBox, 1);
- place(2, 4, mPickupParticleCheckBox, 2);
+ place(1, 5, mPickupNotifyLabel, 4);
+ place(1, 6, mPickupChatCheckBox, 1);
+ place(2, 6, mPickupParticleCheckBox, 2);
- place(0, 6, mAlphaSlider);
- place(1, 6, alphaLabel, 3);
+ place(0, 7, mAlphaSlider);
+ place(1, 7, alphaLabel, 3);
- place(0, 7, mFpsSlider);
- place(1, 7, mFpsCheckBox).setPadding(3);
- place(2, 7, mFpsLabel).setPadding(1);
+ place(0, 9, mFpsSlider);
+ place(1, 9, mFpsCheckBox).setPadding(3);
+ place(2, 9, mFpsLabel).setPadding(1);
- place(0, 8, mAltFpsSlider);
- place(1, 8, mAltFpsLabel).setPadding(3);
+ place(0, 10, mAltFpsSlider);
+ place(1, 10, mAltFpsLabel).setPadding(3);
- place(0, 9, mSpeechSlider);
- place(1, 9, speechLabel);
- place(2, 9, mSpeechLabel, 3).setPadding(2);
+ place(0, 11, mSpeechSlider);
+ place(1, 11, speechLabel);
+ place(2, 11, mSpeechLabel, 3).setPadding(2);
- place(0, 10, mOverlayDetailSlider);
- place(1, 10, overlayDetailLabel);
- place(2, 10, mOverlayDetailField, 3).setPadding(2);
+ place(0, 12, mOverlayDetailSlider);
+ place(1, 12, overlayDetailLabel);
+ place(2, 12, mOverlayDetailField, 3).setPadding(2);
- place(0, 11, mParticleDetailSlider);
- place(1, 11, particleDetailLabel);
- place(2, 11, mParticleDetailField, 3).setPadding(2);
+ place(0, 13, mParticleDetailSlider);
+ place(1, 13, particleDetailLabel);
+ place(2, 13, mParticleDetailField, 3).setPadding(2);
int width = 600;
@@ -540,6 +550,8 @@ void Setup_Video::apply()
mOpenGLEnabled = config.getIntValue("opengl");
mPickupChatEnabled = config.getBoolValue("showpickupchat");
mPickupParticleEnabled = config.getBoolValue("showpickupparticle");
+ mEnableResize = config.getBoolValue("enableresize");
+ mNoFrame = config.getBoolValue("noframe");
}
void Setup_Video::cancel()
@@ -560,6 +572,8 @@ void Setup_Video::cancel()
mFpsLabel->setCaption(mFpsCheckBox->isSelected()
? toString(mFps) : _("None"));
mAltFpsLabel->setCaption(_("Alt FPS limit: ") + toString(mAltFps));
+ mEnableResizeCheckBox->setSelected(mEnableResize);
+ mNoFrameCheckBox->setSelected(mNoFrame);
config.setValue("screen", mFullScreenEnabled);
@@ -578,6 +592,8 @@ void Setup_Video::cancel()
config.setValue("opengl", mOpenGLEnabled);
config.setValue("showpickupchat", mPickupChatEnabled);
config.setValue("showpickupparticle", mPickupParticleEnabled);
+ config.setValue("enableresize", mEnableResize);
+ config.setValue("noframe", mNoFrame);
}
void Setup_Video::action(const gcn::ActionEvent &event)
@@ -614,6 +630,7 @@ void Setup_Video::action(const gcn::ActionEvent &event)
// TODO: Find out why the drawing area doesn't resize without a restart.
if (width != mainGraphics->mWidth || height != mainGraphics->mHeight)
{
+#if defined(_WIN32)
if (width < mainGraphics->mWidth || height < mainGraphics->mHeight)
new OkDialog(_("Screen Resolution Changed"),
_("Restart your client for the change to take effect.")
@@ -622,6 +639,9 @@ void Setup_Video::action(const gcn::ActionEvent &event)
else
new OkDialog(_("Screen Resolution Changed"),
_("Restart your client for the change to take effect."));
+#else
+ Client::resize(width, height);
+#endif
}
config.setValue("oldscreen", config.getBoolValue("screen"));
@@ -711,6 +731,14 @@ void Setup_Video::action(const gcn::ActionEvent &event)
mAltFpsSlider->setValue(mAltFps);
mAltFpsSlider->setEnabled(mAltFps > 0);
}
+ else if (id == "enableresize")
+ {
+ config.setValue("enableresize", mEnableResizeCheckBox->isSelected());
+ }
+ else if (id == "noframe")
+ {
+ config.setValue("noframe", mNoFrameCheckBox->isSelected());
+ }
}
void Setup_Video::externalUpdated()
diff --git a/src/gui/setup_video.h b/src/gui/setup_video.h
index 0c82ab272..31d45d93d 100644
--- a/src/gui/setup_video.h
+++ b/src/gui/setup_video.h
@@ -62,6 +62,8 @@ class Setup_Video : public SetupTab, public gcn::KeyListener
float mOpacity;
int mFps;
int mAltFps;
+ bool mEnableResize;
+ bool mNoFrame;
Being::Speech mSpeechMode;
ModeListModel *mModeListModel;
@@ -85,6 +87,9 @@ class Setup_Video : public SetupTab, public gcn::KeyListener
gcn::CheckBox *mPickupChatCheckBox;
gcn::CheckBox *mPickupParticleCheckBox;
+ gcn::CheckBox *mEnableResizeCheckBox;
+ gcn::CheckBox *mNoFrameCheckBox;
+
gcn::Slider *mSpeechSlider;
gcn::Label *mSpeechLabel;
gcn::Slider *mAlphaSlider;
diff --git a/src/gui/shopwindow.cpp b/src/gui/shopwindow.cpp
index b6b87edb7..1a27b8b0c 100644
--- a/src/gui/shopwindow.cpp
+++ b/src/gui/shopwindow.cpp
@@ -55,6 +55,7 @@
#include "net/net.h"
#include "net/chathandler.h"
#include "net/npchandler.h"
+#include "net/playerhandler.h"
#include "net/tradehandler.h"
#include "resources/iteminfo.h"
@@ -206,11 +207,15 @@ void ShopWindow::action(const gcn::ActionEvent &event)
&& mBuyShopItemList->getSelected() >= 0)
{
mBuyShopItems->del(mBuyShopItemList->getSelected());
+ if (isShopEmpty() && player_node)
+ player_node->updateStatus();
}
else if (event.getId() == "delete sell" && mSellShopItemList
&& mSellShopItemList->getSelected() >= 0)
{
mSellShopItems->del(mSellShopItemList->getSelected());
+ if (isShopEmpty() && player_node)
+ player_node->updateStatus();
}
else if (event.getId() == "announce buy" && mBuyShopItems
&& mBuyShopItems->getNumberOfElements() > 0)
@@ -306,8 +311,12 @@ void ShopWindow::addBuyItem(Item *item, int amount, int price)
{
if (!mBuyShopItems || !item)
return;
+ bool emp = isShopEmpty();
mBuyShopItems->addItemNoDup(item->getId(),
item->getColor(), amount, price);
+ if (emp && player_node)
+ player_node->updateStatus();
+
updateButtonsAndLabels();
}
@@ -315,8 +324,12 @@ void ShopWindow::addSellItem(Item *item, int amount, int price)
{
if (!mBuyShopItems || !item)
return;
+ bool emp = isShopEmpty();
mSellShopItems->addItemNoDup(item->getId(),
item->getColor(), amount, price);
+ if (emp && player_node)
+ player_node->updateStatus();
+
updateButtonsAndLabels();
}
diff --git a/src/gui/shopwindow.h b/src/gui/shopwindow.h
index 53ed7690c..a8d131acb 100644
--- a/src/gui/shopwindow.h
+++ b/src/gui/shopwindow.h
@@ -109,7 +109,7 @@ class ShopWindow : public Window, public gcn::ActionListener,
void setAcceptPlayer(std::string name)
{ mAcceptPlayer = name; }
- const std::string &getAcceptPlayer()
+ const std::string &getAcceptPlayer() const
{ return mAcceptPlayer; }
void sendMessage(const std::string &nick, std::string data,
diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h
index dcb40927a..9032f82ef 100644
--- a/src/gui/skilldialog.h
+++ b/src/gui/skilldialog.h
@@ -77,7 +77,7 @@ class SkillDialog : public Window, public gcn::ActionListener
SkillInfo* getSkill(int id);
- bool hasSkills()
+ bool hasSkills() const
{ return !mSkills.empty(); }
void widgetResized(const gcn::Event &event);
diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp
index 3988c819c..59ace1685 100644
--- a/src/gui/socialwindow.cpp
+++ b/src/gui/socialwindow.cpp
@@ -1143,7 +1143,7 @@ public:
std::vector<std::string> *players
= player_relations.getPlayersByRelation(PlayerRelation::FRIEND);
- std::set<std::string> players2 = whoIsOnline->getOnlinePlayers();
+ const std::set<std::string> &players2 = whoIsOnline->getOnlineNicks();
if (!players)
return;
@@ -1273,10 +1273,12 @@ SocialWindow::SocialWindow() :
loadWindowState();
- mPlayers = new SocialPlayersTab("P");
+ // TRANSLATORS: here P is title for visible players tab in social window
+ mPlayers = new SocialPlayersTab(_("P"));
mTabs->addTab(mPlayers, mPlayers->mScroll);
- mFriends = new SocialFriendsTab("F");
+ // TRANSLATORS: here F is title for friends tab in social window
+ mFriends = new SocialFriendsTab(_("F"));
mTabs->addTab(mFriends, mFriends->mScroll);
mNavigation = new SocialNavigationTab();
diff --git a/src/gui/socialwindow.h b/src/gui/socialwindow.h
index 1429866ee..9da78562b 100644
--- a/src/gui/socialwindow.h
+++ b/src/gui/socialwindow.h
@@ -101,13 +101,13 @@ public:
void prevTab();
- Map* getMap()
+ Map* getMap() const
{ return mMap; }
void setMap(Map *map)
{ mMap = map; mProcessedPortals = false; }
- bool getProcessedPortals()
+ bool getProcessedPortals() const
{ return mProcessedPortals; }
void setProcessedPortals(int n)
diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp
index 410ee08e2..86964383a 100644
--- a/src/gui/statuswindow.cpp
+++ b/src/gui/statuswindow.cpp
@@ -69,7 +69,7 @@ class AttrDisplay : public Container
virtual std::string update();
- virtual Type getType()
+ virtual Type getType() const
{ return UNKNOWN; }
std::string getValue()
@@ -96,7 +96,7 @@ class DerDisplay : public AttrDisplay
public:
DerDisplay(int id, const std::string &name);
- virtual Type getType()
+ virtual Type getType() const
{ return DERIVED; }
};
@@ -107,7 +107,7 @@ class ChangeDisplay : public AttrDisplay, gcn::ActionListener
std::string update();
- virtual Type getType()
+ virtual Type getType() const
{ return CHANGEABLE; }
void setPointsNeeded(int needed);
@@ -424,12 +424,12 @@ void StatusWindow::addAttribute(int id, const std::string &name,
if (modifiable)
{
disp = new ChangeDisplay(id, name);
- mAttrCont->add(disp);
+ mAttrCont->add1(disp);
}
else
{
disp = new DerDisplay(id, name);
- mDAttrCont->add(disp);
+ mDAttrCont->add1(disp);
}
mAttrs[id] = disp;
}
@@ -522,9 +522,14 @@ void StatusWindow::updateProgressBar(ProgressBar *bar, int value, int max,
/ static_cast<float>(max);
if (percent)
- bar->setText(strprintf("%2.5f%%", static_cast<double>(100 * progress)));
+ {
+ bar->setText(strprintf("%2.5f%%",
+ static_cast<double>(100 * progress)));
+ }
else
+ {
bar->setText(toString(value) + "/" + toString(max));
+ }
bar->setProgress(progress);
}
diff --git a/src/gui/theme.h b/src/gui/theme.h
index 3be6882a3..9cb8f6180 100644
--- a/src/gui/theme.h
+++ b/src/gui/theme.h
@@ -95,7 +95,7 @@ class Skin
*/
void updateAlpha(float minimumOpacityAllowed = 0.0f);
- int getPadding()
+ int getPadding() const
{ return mPadding; }
int instances;
diff --git a/src/gui/tradewindow.h b/src/gui/tradewindow.h
index b055c90ce..268d2f108 100644
--- a/src/gui/tradewindow.h
+++ b/src/gui/tradewindow.h
@@ -128,7 +128,7 @@ class TradeWindow : public Window, gcn::ActionListener, gcn::SelectionListener
void initTrade(std::string nick);
- std::string getAutoTradeNick()
+ std::string getAutoTradeNick() const
{ return mAutoAddToNick; }
bool checkItem(Item *item);
diff --git a/src/gui/updaterwindow.cpp b/src/gui/updaterwindow.cpp
index 39dde65c3..28bd8467c 100644
--- a/src/gui/updaterwindow.cpp
+++ b/src/gui/updaterwindow.cpp
@@ -155,6 +155,12 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost,
mLoadUpdates(applyUpdates),
mUpdateType(updateType)
{
+ setWindowName("UpdaterWindow");
+ setResizable(true);
+ setDefaultSize(450, 400, ImageRect::CENTER);
+ setMinWidth(320);
+ setMinHeight(240);
+
mBrowserBox = new BrowserBox;
mScrollArea = new ScrollArea(mBrowserBox);
mLabel = new Label(_("Connecting..."));
@@ -175,14 +181,12 @@ UpdaterWindow::UpdaterWindow(const std::string &updateHost,
placer(3, 5, mCancelButton);
placer(4, 5, mPlayButton);
- reflowLayout(450, 400);
-
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
addKeyListener(this);
- center();
+ loadWindowState();
setVisible(true);
mCancelButton->requestFocus();
diff --git a/src/gui/userpalette.h b/src/gui/userpalette.h
index cb0593fa7..6fba30abc 100644
--- a/src/gui/userpalette.h
+++ b/src/gui/userpalette.h
@@ -107,7 +107,7 @@ class UserPalette : public Palette, public gcn::ListModel
*
* @return the requested test color
*/
- inline const gcn::Color &getTestColor(int type)
+ inline const gcn::Color &getTestColor(int type) const
{ return mColors[type].testColor; }
/**
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index 1407415fd..7ff2c8850 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -497,16 +497,16 @@ void Viewport::mousePressed(gcn::MouseEvent &event)
}
}
else if (player_node->withinAttackRange(mHoverBeing) ||
- keyboard.isKeyActive(keyboard.KEY_ATTACK))
+ keyboard.isActionActive(keyboard.KEY_ATTACK))
{
if (player_node != mHoverBeing)
{
player_node->attack(mHoverBeing,
- !keyboard.isKeyActive(keyboard.KEY_TARGET));
+ !keyboard.isActionActive(keyboard.KEY_TARGET));
return;
}
}
- else if (!keyboard.isKeyActive(keyboard.KEY_ATTACK))
+ else if (!keyboard.isActionActive(keyboard.KEY_ATTACK))
{
if (player_node != mHoverBeing)
{
@@ -522,7 +522,7 @@ void Viewport::mousePressed(gcn::MouseEvent &event)
player_node->pickUp(mHoverItem);
}
// Just walk around
- else if (!keyboard.isKeyActive(keyboard.KEY_ATTACK))
+ else if (!keyboard.isActionActive(keyboard.KEY_ATTACK))
{
player_node->stopAttack();
player_node->cancelFollow();
@@ -875,3 +875,44 @@ bool Viewport::isPopupMenuVisible()
{
return mPopupMenu ? mPopupMenu->isVisible() : false;
}
+
+void Viewport::moveCameraToActor(int actorId, int x, int y)
+{
+ if (!player_node)
+ return;
+
+ Actor *actor = actorSpriteManager->findBeing(actorId);
+ if (!actor)
+ return;
+ Vector actorPos = actor->getPosition();
+ Vector playerPos = player_node->getPosition();
+ mCameraMode = 1;
+ mCameraRelativeX = actorPos.x - playerPos.x + x;
+ mCameraRelativeY = actorPos.y - playerPos.y + y;
+}
+
+void Viewport::moveCameraToPosition(int x, int y)
+{
+ if (!player_node)
+ return;
+
+ Vector playerPos = player_node->getPosition();
+ mCameraMode = 1;
+
+ mCameraRelativeX = x - playerPos.x;
+ mCameraRelativeY = y - playerPos.y;
+}
+
+void Viewport::moveCameraRelative(int x, int y)
+{
+ mCameraMode = 1;
+ mCameraRelativeX += x;
+ mCameraRelativeY += y;
+}
+
+void Viewport::returnCamera()
+{
+ mCameraMode = 0;
+ mCameraRelativeX = 0;
+ mCameraRelativeY = 0;
+}
diff --git a/src/gui/viewport.h b/src/gui/viewport.h
index b25f51242..f3035b5df 100644
--- a/src/gui/viewport.h
+++ b/src/gui/viewport.h
@@ -218,13 +218,13 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
Map *getCurrentMap() const
{ return mMap; }
- int getDebugPath()
+ int getDebugPath() const
{ return mShowDebugPath; }
void setDebugPath(int n)
{ mShowDebugPath = n; }
- int getCameraMode()
+ int getCameraMode() const
{ return mCameraMode; }
/**
@@ -237,19 +237,33 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
*/
void cleanHoverItems();
- Map *getMap()
+ Map *getMap() const
{ return mMap; }
void moveCamera(int dx, int dy);
- int getCameraRelativeX()
+ int getCameraRelativeX() const
{ return mCameraRelativeX; }
- int getCameraRelativeY()
+ int getCameraRelativeY() const
{ return mCameraRelativeY; }
+ void setCameraRelativeX(int n)
+ { mCameraRelativeX = n; }
+
+ void setCameraRelativeY(int n)
+ { mCameraRelativeY = n; }
+
bool isPopupMenuVisible();
+ void moveCameraToActor(int actorId, int x = 0, int y = 0);
+
+ void moveCameraToPosition(int x, int y);
+
+ void moveCameraRelative(int x, int y);
+
+ void returnCamera();
+
protected:
friend class ActorSpriteManager;
diff --git a/src/gui/whoisonline.cpp b/src/gui/whoisonline.cpp
index a80fb4c89..205a1aae1 100644
--- a/src/gui/whoisonline.cpp
+++ b/src/gui/whoisonline.cpp
@@ -48,6 +48,7 @@
#include "gui/chatwindow.h"
+#include "utils/dtor.h"
#include "utils/gettext.h"
#include "utils/stringutils.h"
@@ -68,21 +69,10 @@
class NameFunctuator
{
public:
- bool operator()(const std::string &left,
- const std::string &right) const
+ bool operator()(const OnlinePlayer *left,
+ const OnlinePlayer *right) const
{
- for (std::string::const_iterator lit = left.begin(),
- rit = right.begin();
- lit != left.end() && rit != right.end(); ++lit, ++rit)
- {
- if (tolower(*lit) < tolower(*rit))
- return true;
- else if (tolower(*lit) > tolower(*rit))
- return false;
- }
- if (left.size() < right.size())
- return true;
- return false;
+ return (compareStrI(left->getNick(), right->getNick()) < 0);
}
} nameCompare;
@@ -149,6 +139,14 @@ WhoIsOnline::~WhoIsOnline()
// Remove possibly leftover temporary download
delete[] mCurlError;
+
+ std::set<OnlinePlayer*>::iterator itd = mOnlinePlayers.begin();
+ std::set<OnlinePlayer*>::iterator itd_end = mOnlinePlayers.end();
+
+ for (; itd != itd_end; ++ itd)
+ delete *itd;
+ mOnlinePlayers.clear();
+ mOnlineNicks.clear();
}
void WhoIsOnline::handleLink(const std::string& link, gcn::MouseEvent *event)
@@ -186,10 +184,10 @@ void WhoIsOnline::handleLink(const std::string& link, gcn::MouseEvent *event)
}
}
-void WhoIsOnline::updateWindow(std::vector<std::string> &friends,
- std::vector<std::string> &neutral,
- std::vector<std::string> &disregard,
- std::vector<std::string> enemy,
+void WhoIsOnline::updateWindow(std::vector<OnlinePlayer*> &friends,
+ std::vector<OnlinePlayer*> &neutral,
+ std::vector<OnlinePlayer*> &disregard,
+ std::vector<OnlinePlayer*> enemy,
int numOnline)
{
//Set window caption
@@ -202,7 +200,7 @@ void WhoIsOnline::updateWindow(std::vector<std::string> &friends,
bool addedFromSection(false);
for (int i = 0; i < static_cast<int>(friends.size()); i++)
{
- mBrowserBox->addRow(friends.at(i));
+ mBrowserBox->addRow(friends.at(i)->getText());
addedFromSection = true;
}
if (addedFromSection == true)
@@ -212,7 +210,7 @@ void WhoIsOnline::updateWindow(std::vector<std::string> &friends,
}
for (int i = 0; i < static_cast<int>(enemy.size()); i++)
{
- mBrowserBox->addRow(enemy.at(i));
+ mBrowserBox->addRow(enemy.at(i)->getText());
addedFromSection = true;
}
if (addedFromSection == true)
@@ -222,7 +220,7 @@ void WhoIsOnline::updateWindow(std::vector<std::string> &friends,
}
for (int i = 0; i < static_cast<int>(neutral.size()); i++)
{
- mBrowserBox->addRow(neutral.at(i));
+ mBrowserBox->addRow(neutral.at(i)->getText());
addedFromSection = true;
}
if (addedFromSection == true && !disregard.empty())
@@ -232,7 +230,7 @@ void WhoIsOnline::updateWindow(std::vector<std::string> &friends,
}
for (int i = 0; i < static_cast<int>(disregard.size()); i++)
{
- mBrowserBox->addRow(disregard.at(i));
+ mBrowserBox->addRow(disregard.at(i)->getText());
}
if (mScrollArea->getVerticalMaxScroll() <
@@ -243,43 +241,59 @@ void WhoIsOnline::updateWindow(std::vector<std::string> &friends,
}
}
-void WhoIsOnline::loadList(std::vector<std::string> &list)
+void WhoIsOnline::loadList(std::vector<OnlinePlayer*> &list)
{
mBrowserBox->clearRows();
int numOnline = list.size();
- std::vector<std::string> friends;
- std::vector<std::string> neutral;
- std::vector<std::string> disregard;
- std::vector<std::string> enemy;
+ std::vector<OnlinePlayer*> friends;
+ std::vector<OnlinePlayer*> neutral;
+ std::vector<OnlinePlayer*> disregard;
+ std::vector<OnlinePlayer*> enemy;
+
+ std::set<OnlinePlayer*>::iterator itd = mOnlinePlayers.begin();
+ std::set<OnlinePlayer*>::iterator itd_end = mOnlinePlayers.end();
+ for (; itd != itd_end; ++ itd)
+ delete *itd;
mOnlinePlayers.clear();
+ mOnlineNicks.clear();
+
mShowLevel = config.getBoolValue("showlevel");
- std::vector<std::string>::const_iterator it = list.begin();
- std::vector<std::string>::const_iterator it_end = list.end();
+ std::vector<OnlinePlayer*>::iterator it = list.begin();
+ std::vector<OnlinePlayer*>::iterator it_end = list.end();
for (; it != it_end; ++ it)
{
- std::string nick = *it;
- mOnlinePlayers.insert(nick);
+ OnlinePlayer *player = *it;
+ std::string nick = player->getNick();
+ mOnlinePlayers.insert(player);
+ mOnlineNicks.insert(nick);
+
+ if (!mShowLevel)
+ player->setLevel(0);
switch (player_relations.getRelation(nick))
{
case PlayerRelation::NEUTRAL:
default:
- neutral.push_back(prepareNick(nick, 0, "0"));
+ player->setText("0");
+ neutral.push_back(player);
break;
case PlayerRelation::FRIEND:
- friends.push_back(prepareNick(nick, 0, "2"));
+ player->setText("2");
+ friends.push_back(player);
break;
case PlayerRelation::DISREGARDED:
case PlayerRelation::BLACKLISTED:
- disregard.push_back(prepareNick(nick, 0, "8"));
+ player->setText("8");
+ disregard.push_back(player);
break;
case PlayerRelation::ENEMY2:
- enemy.push_back(prepareNick(nick, 0, "1"));
+ player->setText("1");
+ enemy.push_back(player);
break;
case PlayerRelation::IGNORED:
@@ -290,10 +304,10 @@ void WhoIsOnline::loadList(std::vector<std::string> &list)
}
updateWindow(friends, neutral, disregard, enemy, numOnline);
- if (!mOnlinePlayers.empty())
+ if (!mOnlineNicks.empty())
{
if (chatWindow)
- chatWindow->updateOnline(mOnlinePlayers);
+ chatWindow->updateOnline(mOnlineNicks);
if (socialWindow)
socialWindow->updateActiveList();
}
@@ -313,15 +327,23 @@ void WhoIsOnline::loadWebList()
bool listStarted(false);
std::string lineStr;
int numOnline(0);
- std::vector<std::string> friends;
- std::vector<std::string> neutral;
- std::vector<std::string> disregard;
- std::vector<std::string> enemy;
+ std::vector<OnlinePlayer*> friends;
+ std::vector<OnlinePlayer*> neutral;
+ std::vector<OnlinePlayer*> disregard;
+ std::vector<OnlinePlayer*> enemy;
// Tokenize and add each line separately
char *line = strtok(mMemoryBuffer, "\n");
const std::string gmText = "(GM)";
+
+ std::set<OnlinePlayer*>::iterator itd = mOnlinePlayers.begin();
+ std::set<OnlinePlayer*>::iterator itd_end = mOnlinePlayers.end();
+
+ for (; itd != itd_end; ++ itd)
+ delete *itd;
+
mOnlinePlayers.clear();
+ mOnlineNicks.clear();
mShowLevel = config.getBoolValue("showlevel");
@@ -383,27 +405,38 @@ void WhoIsOnline::loadWebList()
}
}
- mOnlinePlayers.insert(nick);
+
+ if (!mShowLevel)
+ level = 0;
+
+ OnlinePlayer *player = new OnlinePlayer(nick, 255, level,
+ GENDER_UNSPECIFIED, -1);
+ mOnlinePlayers.insert(player);
+ mOnlineNicks.insert(nick);
numOnline++;
switch (player_relations.getRelation(nick))
{
case PlayerRelation::NEUTRAL:
default:
- neutral.push_back(prepareNick(nick, level, "0"));
+ player->setText("0");
+ neutral.push_back(player);
break;
case PlayerRelation::FRIEND:
- friends.push_back(prepareNick(nick, level, "2"));
+ player->setText("2");
+ friends.push_back(player);
break;
case PlayerRelation::DISREGARDED:
case PlayerRelation::BLACKLISTED:
- disregard.push_back(prepareNick(nick, level, "8"));
+ player->setText("8");
+ disregard.push_back(player);
break;
case PlayerRelation::ENEMY2:
- enemy.push_back(prepareNick(nick, level, "1"));
+ player->setText("1");
+ enemy.push_back(player);
break;
case PlayerRelation::IGNORED:
@@ -431,6 +464,9 @@ void WhoIsOnline::loadWebList()
size_t WhoIsOnline::memoryWrite(void *ptr, size_t size,
size_t nmemb, FILE *stream)
{
+ if (!stream)
+ return 0;
+
WhoIsOnline *wio = reinterpret_cast<WhoIsOnline *>(stream);
size_t totalMem = size * nmemb;
wio->mMemoryBuffer = static_cast<char*>(realloc(wio->mMemoryBuffer,
@@ -472,8 +508,8 @@ int WhoIsOnline::downloadThread(void *ptr)
curl_easy_setopt(curl, CURLOPT_WRITEDATA, ptr);
curl_easy_setopt(curl, CURLOPT_USERAGENT,
- strprintf(PACKAGE_EXTENDED_VERSION, branding
- .getValue("appShort", "mana").c_str()).c_str());
+ strprintf(PACKAGE_EXTENDED_VERSION,
+ branding.getStringValue("appName").c_str()).c_str());
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, wio->mCurlError);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
@@ -596,10 +632,10 @@ void WhoIsOnline::logic()
mUpdateButton->setEnabled(true);
mUpdateTimer = 0;
updateSize();
- if (!mOnlinePlayers.empty())
+ if (!mOnlineNicks.empty())
{
if (chatWindow)
- chatWindow->updateOnline(mOnlinePlayers);
+ chatWindow->updateOnline(mOnlineNicks);
if (socialWindow)
socialWindow->updateActiveList();
}
@@ -681,3 +717,46 @@ void WhoIsOnline::optionChanged(const std::string &name)
if (name == "updateOnlineList")
mUpdateOnlineList = config.getBoolValue("updateOnlineList");
}
+
+void OnlinePlayer::setText(std::string color)
+{
+ mText = strprintf("@@%s|##%s%s ", mNick.c_str(),
+ color.c_str(), mNick.c_str());
+
+ if (mStatus != 255 && actorSpriteManager)
+ {
+ Being *being = actorSpriteManager->findBeingByName(
+ mNick, Being::PLAYER);
+ if (being)
+ being->setState(mStatus);
+ }
+
+ if (mLevel > 0)
+ mText += strprintf("%d", mLevel);
+
+ if (mGender == GENDER_FEMALE)
+ mText += "\u2640";
+ else if (mGender == GENDER_MALE)
+ mText += "\u2642";
+
+ if (mStatus > 0 && mStatus != 255)
+ {
+ if (mStatus & Being::FLAG_SHOP)
+ mText += "$";
+ if (mStatus & Being::FLAG_AWAY)
+ {
+ // TRANSLATORS: this away status writed in player nick
+ mText += _("A");
+ }
+ if (mStatus & Being::FLAG_INACTIVE)
+ {
+ // TRANSLATORS: this inactive status writed in player nick
+ mText += _("I");
+ }
+ }
+
+ if (mVersion > 0)
+ mText += strprintf(" - %d", mVersion);
+
+ mText += strprintf("@@");
+}
diff --git a/src/gui/whoisonline.h b/src/gui/whoisonline.h
index ade391d5a..dad51e857 100644
--- a/src/gui/whoisonline.h
+++ b/src/gui/whoisonline.h
@@ -42,6 +42,54 @@ class ScrollArea;
struct SDL_Thread;
+class OnlinePlayer
+{
+ public:
+ OnlinePlayer(std::string nick, unsigned char status,
+ char level, unsigned char gender, char version) :
+ mNick(nick),
+ mText(""),
+ mStatus(status),
+ mLevel(level),
+ mVersion(version),
+ mGender(gender)
+ {
+ }
+
+ const std::string getNick() const
+ { return mNick; }
+
+ unsigned char getStaus() const
+ { return mStatus; }
+
+ char getVersion() const
+ { return mVersion; }
+
+ char getLevel() const
+ { return mLevel; }
+
+ const std::string getText() const
+ { return mText; }
+
+ void setText(std::string str);
+
+ void setLevel(char level)
+ { mLevel = level; }
+
+ private:
+ std::string mNick;
+
+ std::string mText;
+
+ unsigned char mStatus;
+
+ char mLevel;
+
+ char mVersion;
+
+ unsigned char mGender;
+};
+
/**
* Update progress window GUI
*
@@ -52,7 +100,7 @@ class WhoIsOnline : public Window,
public gcn::ActionListener,
public ConfigListener
{
- public:
+public:
/**
* Constructor.
*/
@@ -68,7 +116,7 @@ class WhoIsOnline : public Window,
*/
void loadWebList();
- void loadList(std::vector<std::string> &list);
+ void loadList(std::vector<OnlinePlayer*> &list);
void handleLink(const std::string& link, gcn::MouseEvent *event);
@@ -78,9 +126,12 @@ class WhoIsOnline : public Window,
void widgetResized(const gcn::Event &event);
- std::set<std::string> &getOnlinePlayers()
+ const std::set<OnlinePlayer*> &getOnlinePlayers()
{ return mOnlinePlayers; }
+ const std::set<std::string> &getOnlineNicks()
+ { return mOnlineNicks; }
+
void setAllowUpdate(bool n)
{ mAllowUpdate = n; }
@@ -109,10 +160,10 @@ private:
const std::string prepareNick(std::string nick, int level,
std::string color) const;
- void updateWindow(std::vector<std::string> &friends,
- std::vector<std::string> &neutral,
- std::vector<std::string> &disregard,
- std::vector<std::string> enemy,
+ void updateWindow(std::vector<OnlinePlayer*> &friends,
+ std::vector<OnlinePlayer*> &neutral,
+ std::vector<OnlinePlayer*> &disregard,
+ std::vector<OnlinePlayer*> enemy,
int numOnline);
enum DownloadStatus
@@ -143,7 +194,8 @@ private:
BrowserBox *mBrowserBox;
ScrollArea *mScrollArea;
time_t mUpdateTimer;
- std::set<std::string> mOnlinePlayers;
+ std::set<OnlinePlayer*> mOnlinePlayers;
+ std::set<std::string> mOnlineNicks;
gcn::Button *mUpdateButton;
bool mAllowUpdate;
diff --git a/src/gui/widgets/browserbox.h b/src/gui/widgets/browserbox.h
index ab3049c0b..d82ebd758 100644
--- a/src/gui/widgets/browserbox.h
+++ b/src/gui/widgets/browserbox.h
@@ -187,7 +187,7 @@ class BrowserBox : public gcn::Widget,
TextRows &getRows()
{ return mTextRows; }
- bool hasRows()
+ bool hasRows() const
{ return !mTextRows.empty(); }
void setAlwaysUpdate(bool n)
diff --git a/src/gui/widgets/button.h b/src/gui/widgets/button.h
index aed46bb55..560e46377 100644
--- a/src/gui/widgets/button.h
+++ b/src/gui/widgets/button.h
@@ -70,16 +70,16 @@ class Button : public gcn::Button, public gcn::WidgetListener
void setDescription(std::string text)
{ mDescription = text; }
- std::string getDescription()
+ std::string getDescription() const
{ return mDescription; }
- unsigned getClickCount()
+ unsigned getClickCount() const
{ return mClickCount; }
void setTag(int tag)
{ mTag = tag; }
- int getTag()
+ int getTag() const
{ return mTag; }
void widgetResized(const gcn::Event &event);
diff --git a/src/gui/widgets/channeltab.h b/src/gui/widgets/channeltab.h
index 4b56d2e05..39702a696 100644
--- a/src/gui/widgets/channeltab.h
+++ b/src/gui/widgets/channeltab.h
@@ -34,7 +34,8 @@ class ChannelTab : public ChatTab
{
public:
- Channel *getChannel() const { return mChannel; }
+ Channel *getChannel() const
+ { return mChannel; }
void showHelp();
diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp
index aea367482..6d5dfc9dd 100644
--- a/src/gui/widgets/chattab.cpp
+++ b/src/gui/widgets/chattab.cpp
@@ -224,9 +224,17 @@ void ChatTab::chatLog(std::string line, Own own,
{
struct tm *timeInfo;
timeInfo = localtime(&t);
- line = strprintf("%s[%02d:%02d] %s%s", lineColor.c_str(),
- timeInfo->tm_hour, timeInfo->tm_min, tmp.nick.c_str(),
- tmp.text.c_str());
+ if (timeInfo)
+ {
+ line = strprintf("%s[%02d:%02d] %s%s", lineColor.c_str(),
+ timeInfo->tm_hour, timeInfo->tm_min, tmp.nick.c_str(),
+ tmp.text.c_str());
+ }
+ else
+ {
+ line = strprintf("%s %s%s", lineColor.c_str(),
+ tmp.nick.c_str(), tmp.text.c_str());
+ }
}
else
{
diff --git a/src/gui/widgets/chattab.h b/src/gui/widgets/chattab.h
index ddf10bf5e..912305a63 100644
--- a/src/gui/widgets/chattab.h
+++ b/src/gui/widgets/chattab.h
@@ -137,24 +137,24 @@ class ChatTab : public Tab
std::list<std::string> &getRows()
{ return mTextOutput->getRows(); }
- bool hasRows()
+ bool hasRows() const
{ return mTextOutput->hasRows(); }
void loadFromLogFile(std::string name);
- bool getAllowHighlight()
+ bool getAllowHighlight() const
{ return mAllowHightlight; }
void setAllowHighlight(bool n)
{ mAllowHightlight = n; }
- bool getRemoveNames()
+ bool getRemoveNames() const
{ return mRemoveNames; }
void setRemoveNames(bool n)
{ mRemoveNames = n; }
- bool getNoAway()
+ bool getNoAway() const
{ return mNoAway; }
void setNoAway(bool n)
diff --git a/src/gui/widgets/desktop.cpp b/src/gui/widgets/desktop.cpp
index beb232fb2..b40558c78 100644
--- a/src/gui/widgets/desktop.cpp
+++ b/src/gui/widgets/desktop.cpp
@@ -48,10 +48,14 @@ Desktop::Desktop() :
std::string appName = branding.getValue("appName", std::string(""));
if (appName.empty())
+ {
mVersionLabel = new Label(FULL_VERSION);
+ }
else
- mVersionLabel = new Label(strprintf("%s (Mana %s)", appName.c_str(),
- FULL_VERSION));
+ {
+ mVersionLabel = new Label(strprintf("%s (%s)", FULL_VERSION,
+ appName.c_str()));
+ }
mVersionLabel->setBackgroundColor(
Theme::getThemeColor(Theme::BACKGROUND, 128));
diff --git a/src/gui/widgets/emoteshortcutcontainer.cpp b/src/gui/widgets/emoteshortcutcontainer.cpp
index e8d7bb7e3..794357275 100644
--- a/src/gui/widgets/emoteshortcutcontainer.cpp
+++ b/src/gui/widgets/emoteshortcutcontainer.cpp
@@ -43,7 +43,7 @@
#include "debug.h"
-static const int MAX_ITEMS = 44;
+static const int MAX_ITEMS = 48;
EmoteShortcutContainer::EmoteShortcutContainer():
ShortcutContainer(),
diff --git a/src/gui/widgets/guildchattab.h b/src/gui/widgets/guildchattab.h
index bebdaa1f3..be6f4d034 100644
--- a/src/gui/widgets/guildchattab.h
+++ b/src/gui/widgets/guildchattab.h
@@ -41,7 +41,8 @@ class GuildChatTab : public ChatTab
void saveToLogFile(std::string &msg);
- int getType() const { return ChatTab::TAB_GUILD; }
+ int getType() const
+ { return ChatTab::TAB_GUILD; }
protected:
void handleInput(const std::string &msg);
diff --git a/src/gui/widgets/icon.h b/src/gui/widgets/icon.h
index 6f05da3f7..98fee314a 100644
--- a/src/gui/widgets/icon.h
+++ b/src/gui/widgets/icon.h
@@ -48,7 +48,8 @@ class Icon : public gcn::Widget
/**
* Gets the current Image.
*/
- Image *getImage() const { return mImage; }
+ Image *getImage() const
+ { return mImage; }
/**
* Sets the image to display.
diff --git a/src/gui/widgets/layout.h b/src/gui/widgets/layout.h
index 02fed43b5..046d09b59 100644
--- a/src/gui/widgets/layout.h
+++ b/src/gui/widgets/layout.h
@@ -266,10 +266,10 @@ class LayoutCell
void setType(int t)
{ mType = t; }
- int getWidth()
+ int getWidth() const
{ return mExtent[0]; }
- int getHeight()
+ int getHeight() const
{ return mExtent[1]; }
void setWidth(int w)
diff --git a/src/gui/widgets/popup.h b/src/gui/widgets/popup.h
index 8ff21149a..5572abd03 100644
--- a/src/gui/widgets/popup.h
+++ b/src/gui/widgets/popup.h
@@ -94,28 +94,32 @@ class Popup : public Container, public gcn::MouseListener,
*/
void setMinWidth(int width);
- int getMinWidth() const { return mMinWidth; }
+ int getMinWidth() const
+ { return mMinWidth; }
/**
* Sets the minimum height of the popup.
*/
void setMinHeight(int height);
- int getMinHeight() const { return mMinHeight; }
+ int getMinHeight() const
+ { return mMinHeight; }
/**
* Sets the maximum width of the popup.
*/
void setMaxWidth(int width);
- int getMaxWidth() const { return mMaxWidth; }
+ int getMaxWidth() const
+ { return mMaxWidth; }
/**
* Sets the minimum height of the popup.
*/
void setMaxHeight(int height);
- int getMaxHeight() const { return mMaxHeight; }
+ int getMaxHeight() const
+ { return mMaxHeight; }
/**
* Gets the padding of the popup. The padding is the distance between
@@ -124,9 +128,11 @@ class Popup : public Container, public gcn::MouseListener,
* @return The padding of the popup.
* @see setPadding
*/
- int getPadding() const { return mPadding; }
+ int getPadding() const
+ { return mPadding; }
- void setPadding(int padding) { mPadding = padding; }
+ void setPadding(int padding)
+ { mPadding = padding; }
/**
* Sets the name of the popup. This is only useful for debug purposes.
diff --git a/src/gui/widgets/progressbar.h b/src/gui/widgets/progressbar.h
index 163310245..603df6157 100644
--- a/src/gui/widgets/progressbar.h
+++ b/src/gui/widgets/progressbar.h
@@ -73,7 +73,8 @@ class ProgressBar : public gcn::Widget, public gcn::WidgetListener
/**
* Returns the current progress.
*/
- float getProgress() const { return mProgress; }
+ float getProgress() const
+ { return mProgress; }
/**
* Change the ProgressPalette for this ProgressBar to follow or -1 to
@@ -89,7 +90,8 @@ class ProgressBar : public gcn::Widget, public gcn::WidgetListener
/**
* Returns the color of the progress bar.
*/
- const gcn::Color &getColor() const { return mColor; }
+ const gcn::Color &getColor() const
+ { return mColor; }
/**
* Sets the text shown on the progress bar.
diff --git a/src/gui/widgets/scrollarea.h b/src/gui/widgets/scrollarea.h
index 86902b5c9..582033071 100644
--- a/src/gui/widgets/scrollarea.h
+++ b/src/gui/widgets/scrollarea.h
@@ -89,7 +89,8 @@ class ScrollArea : public gcn::ScrollArea, public gcn::WidgetListener
/**
* Returns whether the widget draws its background or not.
*/
- bool isOpaque() const { return mOpaque; }
+ bool isOpaque() const
+ { return mOpaque; }
/**
* Called when the mouse moves in the widget area.
diff --git a/src/gui/widgets/setupitem.cpp b/src/gui/widgets/setupitem.cpp
index 92ff625c2..059b05ba2 100644
--- a/src/gui/widgets/setupitem.cpp
+++ b/src/gui/widgets/setupitem.cpp
@@ -192,7 +192,7 @@ void SetupItemCheckBox::createControls()
load();
mCheckBox = new CheckBox(mText, mValue != "0", mParent, mEventName);
mWidget = mCheckBox;
- mParent->getContainer()->add(mWidget);
+ mParent->getContainer()->add1(mWidget);
mParent->addControl(this);
mParent->addActionListener(this);
mWidget->addActionListener(this);
@@ -275,7 +275,7 @@ void SetupItemTextField::createControls()
mHorizont->add(mTextField);
mHorizont->add(mButton);
- mParent->getContainer()->add(mHorizont, true, 4);
+ mParent->getContainer()->add2(mHorizont, true, 4);
mParent->addControl(this);
mParent->addControl(this, mEventName + "_EDIT");
mParent->addControl(this, mEventName + "_EDIT_OK");
@@ -398,7 +398,7 @@ void SetupItemIntTextField::createControls()
mHorizont->add(mTextField);
mHorizont->add(mButton);
- mParent->getContainer()->add(mHorizont, true, 4);
+ mParent->getContainer()->add2(mHorizont, true, 4);
mParent->addControl(this);
mParent->addControl(this, mEventName + "_EDIT");
mParent->addControl(this, mEventName + "_EDIT_OK");
@@ -486,7 +486,7 @@ void SetupItemLabel::createControls()
}
mWidget = mLabel;
- mParent->getContainer()->add(mWidget);
+ mParent->getContainer()->add1(mWidget);
mParent->addControl(this);
mParent->addActionListener(this);
mWidget->addActionListener(this);
@@ -568,7 +568,7 @@ void SetupItemDropDown::createControls()
mHorizont->add(mLabel);
mHorizont->add(mDropDown);
- mParent->getContainer()->add(mHorizont, true, 4);
+ mParent->getContainer()->add2(mHorizont, true, 4);
mParent->addControl(this);
mParent->addActionListener(this);
mWidget->addActionListener(this);
diff --git a/src/gui/widgets/setupitem.h b/src/gui/widgets/setupitem.h
index eb2680ede..71856d6e2 100644
--- a/src/gui/widgets/setupitem.h
+++ b/src/gui/widgets/setupitem.h
@@ -75,7 +75,7 @@ class SetupItem : public gcn::ActionListener
void setWidget(gcn::Widget *widget)
{ mWidget = widget; }
- gcn::Widget *getWidget()
+ gcn::Widget *getWidget() const
{ return mWidget; }
Configuration *getConfig();
@@ -93,7 +93,7 @@ class SetupItem : public gcn::ActionListener
virtual void externalUpdated(std::string eventName);
// virtual int add(ContainerPlacer &place, int x, int y, int width);
- bool isMainConfig()
+ bool isMainConfig() const
{ return mMainConfig; }
protected:
diff --git a/src/gui/widgets/setuptabscroll.h b/src/gui/widgets/setuptabscroll.h
index 4ad1f464b..d471ecfbc 100644
--- a/src/gui/widgets/setuptabscroll.h
+++ b/src/gui/widgets/setuptabscroll.h
@@ -43,7 +43,7 @@ class SetupTabScroll : public SetupTab
void addControl(SetupItem *widget, std::string event);
- VertContainer *getContainer()
+ VertContainer *getContainer() const
{ return mContainer; }
virtual void apply();
diff --git a/src/gui/widgets/shoplistbox.h b/src/gui/widgets/shoplistbox.h
index 9b416d3a3..694fdb92e 100644
--- a/src/gui/widgets/shoplistbox.h
+++ b/src/gui/widgets/shoplistbox.h
@@ -56,7 +56,8 @@ class ShopListBox : public ListBox
/**
* Returns the height of a row.
*/
- unsigned int getRowHeight() const { return mRowHeight; }
+ unsigned int getRowHeight() const
+ { return mRowHeight; }
/**
* gives information about the current player's money
diff --git a/src/gui/widgets/tab.h b/src/gui/widgets/tab.h
index 40b46ede5..829689543 100644
--- a/src/gui/widgets/tab.h
+++ b/src/gui/widgets/tab.h
@@ -61,7 +61,7 @@ class Tab : public gcn::Tab, public gcn::WidgetListener
*/
void setFlash(int flash);
- int getFlash()
+ int getFlash() const
{ return mFlash; }
void widgetResized(const gcn::Event &event);
@@ -70,7 +70,7 @@ class Tab : public gcn::Tab, public gcn::WidgetListener
void setLabelFont(gcn::Font *font);
- gcn::Label *getLabel()
+ gcn::Label *getLabel() const
{ return mLabel; }
protected:
diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h
index b202dfc9d..cceaf56b7 100644
--- a/src/gui/widgets/tabbedarea.h
+++ b/src/gui/widgets/tabbedarea.h
@@ -136,13 +136,13 @@ class TabbedArea : public gcn::TabbedArea, public gcn::WidgetListener
void setRightMargin(int n)
{ mRightMargin = n; }
- int getRightMargin()
+ int getRightMargin() const
{ return mRightMargin; }
void setFollowDownScroll(bool n)
{ mFollowDownScroll = n; }
- bool getFollowDownScroll()
+ bool getFollowDownScroll() const
{ return mFollowDownScroll; }
void fixSize()
diff --git a/src/gui/widgets/textbox.h b/src/gui/widgets/textbox.h
index 6d2467b38..a052247c4 100644
--- a/src/gui/widgets/textbox.h
+++ b/src/gui/widgets/textbox.h
@@ -59,7 +59,8 @@ class TextBox : public gcn::TextBox
*/
inline void draw(gcn::Graphics *graphics)
{
- setForegroundColor(*mTextColor);
+ if (mTextColor)
+ setForegroundColor(*mTextColor);
gcn::TextBox::draw(graphics);
}
diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp
index 03fdb5378..4dba2eb57 100644
--- a/src/gui/widgets/textfield.cpp
+++ b/src/gui/widgets/textfield.cpp
@@ -183,7 +183,7 @@ int TextField::getValue() const
if (value < mMinimum)
return mMinimum;
- if (value > mMaximum)
+ if (value > (signed)mMaximum)
return mMaximum;
return value;
@@ -195,29 +195,43 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent)
if (val >= 32)
{
- int l;
- if (val < 128)
- l = 1; // 0xxxxxxx
- else if (val < 0x800)
- l = 2; // 110xxxxx 10xxxxxx
- else if (val < 0x10000)
- l = 3; // 1110xxxx 10xxxxxx 10xxxxxx
- else
- l = 4; // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
-
- char buf[4];
- for (int i = 0; i < l; ++i)
+ if (mNumeric)
{
- buf[i] = static_cast<char>(val >> (6 * (l - i - 1)));
- if (i > 0)
- buf[i] = static_cast<char>((buf[i] & 63) | 128);
+ if ((val >= '0' && val <= '9') || (val == '-' && !mCaretPosition))
+ {
+ char buf[2];
+ buf[0] = val;
+ buf[1] = 0;
+ mText.insert(mCaretPosition, std::string(buf));
+ mCaretPosition += 1;
+ }
}
+ else if (!mMaximum || mText.size() < mMaximum)
+ {
+ int l;
+ if (val < 128)
+ l = 1; // 0xxxxxxx
+ else if (val < 0x800)
+ l = 2; // 110xxxxx 10xxxxxx
+ else if (val < 0x10000)
+ l = 3; // 1110xxxx 10xxxxxx 10xxxxxx
+ else
+ l = 4; // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+
+ char buf[4];
+ for (int i = 0; i < l; ++i)
+ {
+ buf[i] = static_cast<char>(val >> (6 * (l - i - 1)));
+ if (i > 0)
+ buf[i] = static_cast<char>((buf[i] & 63) | 128);
+ }
- if (l > 1)
- buf[0] |= static_cast<char>(255 << (8 - l));
+ if (l > 1)
+ buf[0] |= static_cast<char>(255 << (8 - l));
- mText.insert(mCaretPosition, std::string(buf, buf + l));
- mCaretPosition += l;
+ mText.insert(mCaretPosition, std::string(buf, buf + l));
+ mCaretPosition += l;
+ }
}
/* In UTF-8, 10xxxxxx is only used for inner parts of characters. So skip
diff --git a/src/gui/widgets/textfield.h b/src/gui/widgets/textfield.h
index bc1123f19..fef606526 100644
--- a/src/gui/widgets/textfield.h
+++ b/src/gui/widgets/textfield.h
@@ -114,7 +114,7 @@ class TextField : public gcn::TextField
static ImageRect skin;
bool mNumeric;
int mMinimum;
- int mMaximum;
+ unsigned mMaximum;
bool mLoseFocusOnTab;
int mLastEventPaste;
};
diff --git a/src/gui/widgets/vertcontainer.cpp b/src/gui/widgets/vertcontainer.cpp
index 305343d1a..0eb59c8f9 100644
--- a/src/gui/widgets/vertcontainer.cpp
+++ b/src/gui/widgets/vertcontainer.cpp
@@ -35,12 +35,12 @@ VertContainer::VertContainer(int verticalItemSize, bool resizable,
addWidgetListener(this);
}
-void VertContainer::add(gcn::Widget *widget, int spacing)
+void VertContainer::add1(gcn::Widget *widget, int spacing)
{
- add(widget, mResizable, spacing);
+ add2(widget, mResizable, spacing);
}
-void VertContainer::add(gcn::Widget *widget, bool resizable, int spacing)
+void VertContainer::add2(gcn::Widget *widget, bool resizable, int spacing)
{
if (!widget)
return;
@@ -70,6 +70,7 @@ void VertContainer::clear()
mCount = 0;
mNextY = 0;
+ mResizableWidgets.clear();
}
void VertContainer::widgetResized(const gcn::Event &event A_UNUSED)
diff --git a/src/gui/widgets/vertcontainer.h b/src/gui/widgets/vertcontainer.h
index 6e1305a06..b4e43d31d 100644
--- a/src/gui/widgets/vertcontainer.h
+++ b/src/gui/widgets/vertcontainer.h
@@ -39,10 +39,10 @@ class VertContainer : public Container, public gcn::WidgetListener
VertContainer(int verticalItemSize, bool resizable = true,
int leftSpacing = 0);
- virtual void add(gcn::Widget *widget, bool resizable,
- int spacing = -1);
+ virtual void add2(gcn::Widget *widget, bool resizable,
+ int spacing = -1);
- virtual void add(gcn::Widget *widget, int spacing = -1);
+ virtual void add1(gcn::Widget *widget, int spacing = -1);
virtual void clear();
diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp
index 3858b0d81..6e6918694 100644
--- a/src/gui/widgets/window.cpp
+++ b/src/gui/widgets/window.cpp
@@ -433,7 +433,7 @@ void Window::setVisible(bool visible, bool forceSticky)
// Check if the window is off screen...
if (visible)
- checkIfIsOffScreen();
+ ensureOnScreen();
if (isStickyButtonLock())
gcn::Window::setVisible(visible);
@@ -713,7 +713,7 @@ void Window::loadWindowState()
}
// Check if the window is off screen...
- checkIfIsOffScreen();
+ ensureOnScreen();
if (viewport)
{
@@ -848,6 +848,22 @@ void Window::resetToDefaultSize()
saveWindowState();
}
+void Window::adjustPositionAfterResize(int oldScreenWidth, int oldScreenHeight)
+{
+ gcn::Rectangle dimension = getDimension();
+
+ // If window was aligned to the right or bottom, keep it there
+ const int rightMargin = oldScreenWidth - (getX() + getWidth());
+ const int bottomMargin = oldScreenHeight - (getY() + getHeight());
+ if (getX() > 0 && getX() > rightMargin)
+ dimension.x = mainGraphics->mWidth - rightMargin - getWidth();
+ if (getY() > 0 && getY() > bottomMargin)
+ dimension.y = mainGraphics->mHeight - bottomMargin - getHeight();
+
+ setDimension(dimension);
+ ensureOnScreen();
+}
+
int Window::getResizeHandles(gcn::MouseEvent &event)
{
if ((mStickyButtonLock && mSticky) || event.getX() < 0 || event.getY() < 0)
@@ -972,57 +988,27 @@ void Window::centerHorisontally()
setLocationHorisontallyRelativeTo(getParent());
}
-void Window::checkIfIsOffScreen(bool partially, bool entirely)
+void Window::ensureOnScreen()
{
- // 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...
+ // Skip 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 > mainGraphics->mWidth)
- winDimension.x = mainGraphics->mWidth - winDimension.width;
-
- if (winDimension.y + winDimension.height > mainGraphics->mHeight)
- winDimension.y = mainGraphics->mHeight - winDimension.height;
+ gcn::Rectangle dimension = getDimension();
- setDimension(winDimension);
- return;
- }
+ // Check the left and bottom screen boundaries
+ if (dimension.x + dimension.width > mainGraphics->mWidth)
+ dimension.x = mainGraphics->mWidth - dimension.width;
+ if (dimension.y + dimension.height > mainGraphics->mHeight)
+ dimension.y = mainGraphics->mHeight - dimension.height;
- if (entirely)
- {
- if (winDimension.x > mainGraphics->mWidth)
- winDimension.x = mainGraphics->mWidth - winDimension.width;
+ // But never allow the windows to disappear in to the right and top
+ if (dimension.x < 0)
+ dimension.x = 0;
+ if (dimension.y < 0)
+ dimension.y = 0;
- if (winDimension.y > mainGraphics->mHeight)
- winDimension.y = mainGraphics->mHeight - winDimension.height;
- }
- setDimension(winDimension);
+ setDimension(dimension);
}
gcn::Rectangle Window::getWindowArea()
diff --git a/src/gui/widgets/window.h b/src/gui/widgets/window.h
index 65dbf196b..6fa47dedc 100644
--- a/src/gui/widgets/window.h
+++ b/src/gui/widgets/window.h
@@ -329,6 +329,13 @@ class Window : public gcn::Window, gcn::WidgetListener
virtual void resetToDefaultSize();
/**
+ * Adjusts the window position after the application window has been
+ * resized.
+ */
+ void adjustPositionAfterResize(int oldScreenWidth,
+ int oldScreenHeight);
+
+ /**
* Gets the layout handler for this window.
*/
Layout &getLayout();
@@ -406,11 +413,11 @@ 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.
+ * Ensures the window is on the screen, moving it if necessary. This is
+ * used by loadWindowState and setVisible(true), and when the screen
+ * is resized.
*/
- void checkIfIsOffScreen(bool partially = true, bool entirely = true);
+ void ensureOnScreen();
/**
* Determines if the mouse is in a resize area and returns appropriate
diff --git a/src/gui/widgets/windowcontainer.cpp b/src/gui/widgets/windowcontainer.cpp
index 43aaea8a4..9e698ffa6 100644
--- a/src/gui/widgets/windowcontainer.cpp
+++ b/src/gui/widgets/windowcontainer.cpp
@@ -22,6 +22,8 @@
#include "gui/widgets/windowcontainer.h"
+#include "gui/widgets/window.h"
+
#include "utils/dtor.h"
#include "debug.h"
@@ -41,3 +43,13 @@ void WindowContainer::scheduleDelete(gcn::Widget *widget)
if (widget)
mDeathList.push_back(widget);
}
+
+void WindowContainer::adjustAfterResize(int oldScreenWidth,
+ int oldScreenHeight)
+{
+ for (WidgetListIterator i = mWidgets.begin(); i != mWidgets.end(); ++i)
+ {
+ if (Window *window = dynamic_cast<Window*>(*i))
+ window->adjustPositionAfterResize(oldScreenWidth, oldScreenHeight);
+ }
+}
diff --git a/src/gui/widgets/windowcontainer.h b/src/gui/widgets/windowcontainer.h
index 00ef04c19..1cec11861 100644
--- a/src/gui/widgets/windowcontainer.h
+++ b/src/gui/widgets/windowcontainer.h
@@ -48,6 +48,12 @@ class WindowContainer : public Container
*/
void scheduleDelete(gcn::Widget *widget);
+ /**
+ * Ensures that all visible windows are on the screen after the screen
+ * has been resized.
+ */
+ void adjustAfterResize(int oldScreenWidth, int oldScreenHeight);
+
private:
/**
* List of widgets that are scheduled to be deleted.
diff --git a/src/gui/windowmenu.cpp b/src/gui/windowmenu.cpp
index e954340f8..138090075 100644
--- a/src/gui/windowmenu.cpp
+++ b/src/gui/windowmenu.cpp
@@ -299,7 +299,7 @@ void WindowMenu::mouseMoved(gcn::MouseEvent &event)
if (key != KeyboardConfig::KEY_NO_VALUE)
{
mTextPopup->show(x + getX(), y + getY(), btn->getDescription(),
- "Key: " + keyboard.getKeyValueString(key));
+ strprintf(_("Key: %s"), keyboard.getKeyValueString(key).c_str()));
}
else
{
diff --git a/src/guild.cpp b/src/guild.cpp
index e569bed65..238155d32 100644
--- a/src/guild.cpp
+++ b/src/guild.cpp
@@ -166,6 +166,8 @@ void Guild::removeMember(GuildMember *member)
itr_end = mMembers.end();
while (itr != itr_end)
{
+ if (!*itr)
+ continue;
if ((*itr)->mId == member->mId &&
(*itr)->mCharId == member->mCharId &&
(*itr)->getName() == member->getName())
@@ -175,7 +177,7 @@ void Guild::removeMember(GuildMember *member)
delete m;
return;
}
- ++itr;
+ ++ itr;
}
}
@@ -255,6 +257,9 @@ void Guild::setRights(short rights)
bool Guild::isMember(GuildMember *member) const
{
+ if (!member)
+ return false;
+
if (member->mGuild && member->mGuild != this)
return false;
diff --git a/src/guild.h b/src/guild.h
index e95677ec6..8715c2907 100644
--- a/src/guild.h
+++ b/src/guild.h
@@ -43,7 +43,7 @@ public:
Guild *getGuild() const
{ return mGuild; }
- int getPos()
+ int getPos() const
{ return mPos; }
void setPos(int pos)
diff --git a/src/guildmanager.h b/src/guildmanager.h
index 368b2456c..b415d85e8 100644
--- a/src/guildmanager.h
+++ b/src/guildmanager.h
@@ -74,7 +74,7 @@ class GuildManager
bool afterRemove();
- bool havePower()
+ bool havePower() const
{ return mHavePower; }
private:
diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp
index 0079ee2ee..ea04a0e89 100644
--- a/src/keyboardconfig.cpp
+++ b/src/keyboardconfig.cpp
@@ -267,6 +267,14 @@ static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = {
KeyboardConfig::GRP_EMOTION},
{"keyEmoteShortcut44", SDLK_b, strprintf(N_("Emote Shortcut %d"), 44),
KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut45", SDLK_n, strprintf(N_("Emote Shortcut %d"), 45),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut46", SDLK_m, strprintf(N_("Emote Shortcut %d"), 46),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut47", SDLK_COMMA, strprintf(N_("Emote Shortcut %d"), 47),
+ KeyboardConfig::GRP_EMOTION},
+ {"keyEmoteShortcut48", SDLK_PERIOD, strprintf(N_("Emote Shortcut %d"), 48),
+ KeyboardConfig::GRP_EMOTION},
{"", 0, N_("Outfits Keys"), 0},
{"keyWearOutfit", SDLK_RCTRL, N_("Wear Outfit"),
KeyboardConfig::GRP_DEFAULT},
@@ -360,7 +368,7 @@ void KeyboardConfig::init()
mKey[i].value = KEY_NO_VALUE;
mKey[i].grp = keyData[i].grp;
}
- for (int i = KEY_EMOTE_1; i <= KEY_EMOTE_44; i ++)
+ for (int i = KEY_EMOTE_1; i <= KEY_EMOTE_48; i ++)
{
mKey[i].caption = strprintf(
_("Emote Shortcut %d"), i - KEY_EMOTE_1 + 1);
@@ -460,7 +468,7 @@ int KeyboardConfig::getKeyIndex(int keyValue, int grp) const
int KeyboardConfig::getKeyEmoteOffset(int keyValue) const
{
- for (int i = KEY_EMOTE_1; i <= KEY_EMOTE_44; i++)
+ for (int i = KEY_EMOTE_1; i <= KEY_EMOTE_48; i++)
{
if (keyValue == mKey[i].value)
return 1 + i - KEY_EMOTE_1;
@@ -468,7 +476,7 @@ int KeyboardConfig::getKeyEmoteOffset(int keyValue) const
return 0;
}
-bool KeyboardConfig::isKeyActive(int index) const
+bool KeyboardConfig::isActionActive(int index) const
{
if (!mActiveKeys)
return false;
diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h
index 45c5ba65f..1610c1ecd 100644
--- a/src/keyboardconfig.h
+++ b/src/keyboardconfig.h
@@ -136,7 +136,7 @@ class KeyboardConfig
/**
* Checks if the key is active, by providing the key function index.
*/
- bool isKeyActive(int index) const;
+ bool isActionActive(int index) const;
/**
* Takes a snapshot of all the active keys.
@@ -278,6 +278,10 @@ class KeyboardConfig
KEY_EMOTE_42,
KEY_EMOTE_43,
KEY_EMOTE_44,
+ KEY_EMOTE_45,
+ KEY_EMOTE_46,
+ KEY_EMOTE_47,
+ KEY_EMOTE_48,
KEY_SEPARATOR5,
KEY_WEAR_OUTFIT,
KEY_COPY_OUTFIT,
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 0da291711..27897a486 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -354,7 +354,8 @@ void LocalPlayer::logic()
}
}
- if (mEnableAdvert && !mBlockAdvert && mAdvertTime < cur_time)
+ if (serverVersion < 4 && mEnableAdvert && !mBlockAdvert
+ && mAdvertTime < cur_time)
{
Uint8 smile = FLAG_SPECIAL;
if (mTradebot && shopWindow && !shopWindow->isShopEmpty())
@@ -1782,7 +1783,7 @@ void LocalPlayer::moveToTarget(unsigned int dist)
case 6:
case 7:
dist = mAttackRange;
- if (dist == 1)
+ if (dist == 1 && serverVersion < 1)
dist = 2;
default:
break;
@@ -1874,6 +1875,9 @@ void LocalPlayer::changeMode(unsigned *var, unsigned limit, const char *conf,
std::string (LocalPlayer::*func)(), unsigned def,
bool save)
{
+ if (!var)
+ return;
+
(*var) ++;
if (*var >= limit)
*var = def;
@@ -3442,6 +3446,7 @@ void LocalPlayer::setAway(const std::string &message)
if (!message.empty())
config.setValue("afkMessage", message);
changeAwayMode();
+ updateStatus();
}
void LocalPlayer::setPseudoAway(const std::string &message)
@@ -3716,7 +3721,8 @@ void LocalPlayer::attack2(Being *target, bool keep, bool dontChangeEquipment)
changeEquipmentBeforeAttack(target);
if ((!target || getAttackType() == 0 || getAttackType() == 3)
- || (withinAttackRange(target, true, 1)
+ || (withinAttackRange(target, serverVersion < 1,
+ serverVersion < 1 ? 1 : 0)
&& getPathLength(target) <= getAttackRange2()))
{
attack(target, keep);
@@ -4206,11 +4212,30 @@ const char *LocalPlayer::getVarItem(const char **arr, unsigned index,
return arr[sz];
}
+void LocalPlayer::updateStatus()
+{
+ if (serverVersion >= 4 && mEnableAdvert)
+ {
+ Uint8 status = 0;
+ if (mTradebot && shopWindow && !shopWindow->isShopEmpty())
+ status += FLAG_SHOP;
+
+ if (mAwayMode || mPseudoAwayMode)
+ status += FLAG_AWAY;
+
+ if (mInactive)
+ status += FLAG_INACTIVE;
+
+ Net::getPlayerHandler()->updateStatus(status);
+ }
+}
+
void AwayListener::action(const gcn::ActionEvent &event)
{
if (event.getId() == "ok" && player_node && player_node->getAway())
{
player_node->changeAwayMode();
+ player_node->updateStatus();
if (outfitWindow)
outfitWindow->unwearAwayOutfit();
if (miniStatusWindow)
diff --git a/src/localplayer.h b/src/localplayer.h
index ed181e3d0..a7ce3dd7f 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -139,7 +139,7 @@ class LocalPlayer : public Being, public ActorSpriteListener,
void setGMLevel(int level);
- int getGMLevel()
+ int getGMLevel() const
{ return mGMLevel; }
void stopAttack();
@@ -217,7 +217,7 @@ class LocalPlayer : public Being, public ActorSpriteListener,
bool isPathSetByMouse() const
{ return mPathSetByMouse; }
- int getInvertDirection()
+ int getInvertDirection() const
{ return mInvertDirection; }
void setInvertDirection(int n)
@@ -225,16 +225,16 @@ class LocalPlayer : public Being, public ActorSpriteListener,
void invertDirection();
- int getAttackWeaponType()
+ int getAttackWeaponType() const
{ return mAttackWeaponType; }
- int getAttackType()
+ int getAttackType() const
{ return mAttackType; }
- int getFollowMode()
+ int getFollowMode() const
{ return mFollowMode; }
- int getImitationMode()
+ int getImitationMode() const
{ return mImitationMode; }
void changeAttackWeaponType();
@@ -247,41 +247,41 @@ class LocalPlayer : public Being, public ActorSpriteListener,
void changePickUpType();
- int getCrazyMoveType()
- { return mCrazyMoveType ; }
+ int getCrazyMoveType() const
+ { return mCrazyMoveType; }
- int getPickUpType()
- { return mPickUpType ; }
+ int getPickUpType() const
+ { return mPickUpType; }
- int getQuickDropCounter()
- { return mQuickDropCounter ; }
+ int getQuickDropCounter() const
+ { return mQuickDropCounter; }
void changeQuickDropCounter();
- int getMoveState()
- { return mMoveState ; }
+ int getMoveState() const
+ { return mMoveState; }
void setMoveState(int n)
- { mMoveState = n ; }
+ { mMoveState = n; }
void switchMagicAttack();
void switchPvpAttack();
- int getMagicAttackType()
- { return mMagicAttackType ; }
+ int getMagicAttackType() const
+ { return mMagicAttackType; }
- int getPvpAttackType()
- { return mPvpAttackType ; }
+ int getPvpAttackType() const
+ { return mPvpAttackType; }
- int getMoveToTargetType()
- { return mMoveToTargetType ; }
+ int getMoveToTargetType() const
+ { return mMoveToTargetType; }
- int getDisableGameModifiers()
- { return mDisableGameModifiers ; }
+ int getDisableGameModifiers() const
+ { return mDisableGameModifiers; }
- int getPingTime()
- { return mPingTime ; }
+ int getPingTime() const
+ { return mPingTime; }
void tryPingRequest();
@@ -329,16 +329,16 @@ class LocalPlayer : public Being, public ActorSpriteListener,
void setPseudoAway(const std::string &message);
- bool getAway()
+ bool getAway() const
{ return mAwayMode; }
- bool getPseudoAway()
+ bool getPseudoAway() const
{ return mPseudoAwayMode; }
void setHalfAway(bool n)
{ mInactive = n; }
- bool getHalfAway()
+ bool getHalfAway() const
{ return mInactive; }
void afkRespond(ChatTab *tab, const std::string &nick);
@@ -369,7 +369,7 @@ class LocalPlayer : public Being, public ActorSpriteListener,
void setRealPos(int x, int y);
- bool isServerBuggy()
+ bool isServerBuggy() const
{ return mIsServerBuggy; }
void fixPos(int maxDist = 1);
@@ -413,7 +413,7 @@ class LocalPlayer : public Being, public ActorSpriteListener,
void respawn();
- FloorItem *getPickUpTarget()
+ FloorItem *getPickUpTarget() const
{ return mPickUpTarget; }
void unSetPickUpTarget()
@@ -477,6 +477,8 @@ class LocalPlayer : public Being, public ActorSpriteListener,
bool checAttackPermissions(Being *target);
+ void updateStatus();
+
std::string getInvertDirectionString();
std::string getCrazyMoveTypeString();
diff --git a/src/main.h b/src/main.h
index 541296d22..fbc672939 100644
--- a/src/main.h
+++ b/src/main.h
@@ -45,8 +45,8 @@
* different interfaces, which have different implementations for each server.
*/
-#define SMALL_VERSION "1.2.1.22"
-#define CHECK_VERSION "01.02.01.22"
+#define SMALL_VERSION "1.2.2.5"
+#define CHECK_VERSION "01.02.02.05"
#ifdef HAVE_CONFIG_H
#include "../config.h"
diff --git a/src/manaplus.rc b/src/manaplus.rc
index b7720e2cc..b16ca40a7 100644
--- a/src/manaplus.rc
+++ b/src/manaplus.rc
@@ -3,6 +3,7 @@
#include "winver.h"
A ICON MOVEABLE PURE LOADONCALL DISCARDABLE "../data/icons/manaplus.ico"
+evol ICON MOVEABLE PURE LOADONCALL DISCARDABLE "../data/evol/icons/evol-client.ico"
1 VERSIONINFO
FILEVERSION VER_MAJOR,VER_MINOR,VER_RELEASE,VER_BUILD
@@ -11,10 +12,10 @@ PRODUCTVERSION VER_MAJOR,VER_MINOR,VER_RELEASE,VER_BUILD
{
BLOCK "StringFileInfo" {
BLOCK "040904E4" {
- VALUE "CompanyName", "The Mana Development Team"
+ VALUE "CompanyName", "The ManaPlus Development Team"
VALUE "FileVersion", PACKAGE_VERSION "4144"
VALUE "FileDescription", "ManaPlus"
- VALUE "LegalCopyright", "2004-2010 (C)"
+ VALUE "LegalCopyright", "2004-2012 (C)"
VALUE "OriginalFilename", "manaplus.exe"
VALUE "ProductName", "ManaPlus MMORPG Client"
VALUE "ProductVersion", PACKAGE_VERSION "4144"
diff --git a/src/map.cpp b/src/map.cpp
index 211504504..488fb16e9 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -156,7 +156,7 @@ void MapLayer::optionChanged(const std::string &value)
void MapLayer::setTile(int x, int y, Image *img)
{
- setTile(x + y * mWidth, img);
+ mTiles[x + y * mWidth] = img;
}
void MapLayer::draw(Graphics *graphics, int startX, int startY,
@@ -1383,9 +1383,6 @@ Path Map::findPath(int startX, int startY, int destX, int destY,
if (startX >= mWidth || startY >= mHeight)
return path;
- // Declare open list, a list with open tiles sorted on F cost
- std::priority_queue<Location> openList;
-
// Return when destination not walkable
if (!getWalk(destX, destY, walkmask))
return path;
@@ -1397,6 +1394,9 @@ Path Map::findPath(int startX, int startY, int destX, int destY,
startTile->Gcost = 0;
+ // Declare open list, a list with open tiles sorted on F cost
+ std::priority_queue<Location> openList;
+
// Add the start point to the open list
openList.push(Location(startX, startY, startTile));
@@ -1796,6 +1796,9 @@ MapItem *Map::findPortalXY(int x, int y)
for (it = mMapPortals.begin(), it_end = mMapPortals.end();
it != it_end; ++it)
{
+ if (!*it)
+ continue;
+
MapItem *item = *it;
if (item->mX == x && item->mY == y)
return item;
diff --git a/src/map.h b/src/map.h
index db8b092de..e157628cc 100644
--- a/src/map.h
+++ b/src/map.h
@@ -152,7 +152,8 @@ class MapLayer: public ConfigListener
/**
* Set tile image with x + y * width already known.
*/
- void setTile(int index, Image *img) { mTiles[index] = img; }
+ void setTile(int index, Image *img)
+ { mTiles[index] = img; }
/**
* Draws this layer to the given graphics context. The coordinates are
@@ -191,7 +192,7 @@ class MapLayer: public ConfigListener
const Actors *actors,
int mDebugFlags, int yFix) const;
- bool isFringeLayer()
+ bool isFringeLayer() const
{ return mIsFringeLayer; }
void setSpecialLayer(SpecialLayer *val)
@@ -200,10 +201,10 @@ class MapLayer: public ConfigListener
void setTempLayer(SpecialLayer *val)
{ mTempLayer = val; }
- int getWidth()
+ int getWidth() const
{ return mWidth; }
- int getHeight()
+ int getHeight() const
{ return mHeight; }
// void setTileInfo(int x, int y, int width, int cnt);
@@ -355,12 +356,14 @@ class Map : public Properties, public ConfigListener
/**
* Returns the width of this map in tiles.
*/
- int getWidth() const { return mWidth; }
+ int getWidth() const
+ { return mWidth; }
/**
* Returns the height of this map in tiles.
*/
- int getHeight() const { return mHeight; }
+ int getHeight() const
+ { return mHeight; }
/**
* Returns the tile width of this map.
@@ -375,6 +378,7 @@ class Map : public Properties, public ConfigListener
{ return mTileHeight; }
const std::string getMusicFile() const;
+
const std::string getName() const;
/**
@@ -434,16 +438,16 @@ class Map : public Properties, public ConfigListener
void saveExtraLayer();
- SpecialLayer *getTempLayer()
+ SpecialLayer *getTempLayer() const
{ return mTempLayer; }
- SpecialLayer *getSpecialLayer()
+ SpecialLayer *getSpecialLayer() const
{ return mSpecialLayer; }
void setHasWarps(bool n)
{ mHasWarps = n; }
- bool getHasWarps()
+ bool getHasWarps() const
{ return mHasWarps; }
std::string getUserMapDirectory() const;
@@ -476,7 +480,7 @@ class Map : public Properties, public ConfigListener
void setPvpMode(int mode);
- ObjectsLayer* getObjectsLayer()
+ ObjectsLayer* getObjectsLayer() const
{ return mObjects; }
std::string getObjectData(unsigned x, unsigned y, int type);
@@ -488,7 +492,7 @@ class Map : public Properties, public ConfigListener
void setActorsFix(int x, int y)
{ mActorFixX = x; mActorFixY = y; }
- int getVersion()
+ int getVersion() const
{ return mVersion; }
void setVersion(int n)
@@ -498,7 +502,7 @@ class Map : public Properties, public ConfigListener
void redrawMap();
- bool empty()
+ bool empty() const
{ return mLayers.empty(); }
protected:
diff --git a/src/mumblemanager.cpp b/src/mumblemanager.cpp
index 766f4085e..100b600b4 100644
--- a/src/mumblemanager.cpp
+++ b/src/mumblemanager.cpp
@@ -1,5 +1,10 @@
/*
- *Code taken from: http://mumble.sourceforge.net/Link
+ * Code taken from: http://mumble.sourceforge.net/Link
+ *
+ * All code listed below is in the public domain and can be used, shared or
+ * modified freely
+ *
+ * Copyright (C) 2011-2012 The ManaPlus Developers
*/
#include "mumblemanager.h"
@@ -78,7 +83,6 @@ void MumbleManager::init()
#if defined BSD4_4
return;
#endif
-
if (mLinkedMem || !config.getBoolValue("enableMumble"))
return;
diff --git a/src/mumblemanager.h b/src/mumblemanager.h
index f7617233f..480bacfab 100644
--- a/src/mumblemanager.h
+++ b/src/mumblemanager.h
@@ -1,5 +1,10 @@
/*
- * Code taken from: http://mumble.sourceforge.net/Link
+ * Code taken from: http://mumble.sourceforge.net/Link
+ *
+ * All code listed below is in the public domain and can be used, shared or
+ * modified freely
+ *
+ * Copyright (C) 2011-2012 The ManaPlus Developers
*/
#ifndef MUMBLEMANAGER_H
diff --git a/src/net/adminhandler.h b/src/net/adminhandler.h
index f6d8606ce..2ac462834 100644
--- a/src/net/adminhandler.h
+++ b/src/net/adminhandler.h
@@ -42,15 +42,15 @@ class AdminHandler
virtual void kick(int playerId) = 0;
- virtual void kick(const std::string &name) = 0;
+ virtual void kickName(const std::string &name) = 0;
virtual void ban(int playerId) = 0;
- virtual void ban(const std::string &name) = 0;
+ virtual void banName(const std::string &name) = 0;
virtual void unban(int playerId) = 0;
- virtual void unban(const std::string &name) = 0;
+ virtual void unbanName(const std::string &name) = 0;
virtual void mute(int playerId, int type, int limit) = 0;
diff --git a/src/net/download.cpp b/src/net/download.cpp
index 22af389f3..d20713dfa 100644
--- a/src/net/download.cpp
+++ b/src/net/download.cpp
@@ -239,7 +239,7 @@ int Download::downloadThread(void *ptr)
curl_easy_setopt(d->mCurl, CURLOPT_USERAGENT,
strprintf(PACKAGE_EXTENDED_VERSION,
- branding.getStringValue("appShort").c_str()).c_str());
+ branding.getStringValue("appName").c_str()).c_str());
curl_easy_setopt(d->mCurl, CURLOPT_ERRORBUFFER, d->mError);
curl_easy_setopt(d->mCurl, CURLOPT_URL, d->mUrl.c_str());
curl_easy_setopt(d->mCurl, CURLOPT_NOPROGRESS, 0);
diff --git a/src/net/ea/adminhandler.cpp b/src/net/ea/adminhandler.cpp
index 556629458..f70be3cc8 100644
--- a/src/net/ea/adminhandler.cpp
+++ b/src/net/ea/adminhandler.cpp
@@ -32,7 +32,7 @@
namespace Ea
{
-void AdminHandler::kick(const std::string &name)
+void AdminHandler::kickName(const std::string &name)
{
Net::getChatHandler()->talk("@kick " + name);
}
@@ -42,7 +42,7 @@ void AdminHandler::ban(int playerId A_UNUSED)
// Not supported
}
-void AdminHandler::ban(const std::string &name)
+void AdminHandler::banName(const std::string &name)
{
Net::getChatHandler()->talk("@ban " + name);
}
@@ -52,7 +52,7 @@ void AdminHandler::unban(int playerId A_UNUSED)
// Not supported
}
-void AdminHandler::unban(const std::string &name)
+void AdminHandler::unbanName(const std::string &name)
{
Net::getChatHandler()->talk("@unban " + name);
}
diff --git a/src/net/ea/adminhandler.h b/src/net/ea/adminhandler.h
index 70c458514..5b5224174 100644
--- a/src/net/ea/adminhandler.h
+++ b/src/net/ea/adminhandler.h
@@ -35,15 +35,15 @@ class AdminHandler : public Net::AdminHandler
virtual ~AdminHandler()
{ }
- virtual void kick(const std::string &name);
+ virtual void kickName(const std::string &name);
virtual void ban(int playerId);
- virtual void ban(const std::string &name);
+ virtual void banName(const std::string &name);
virtual void unban(int playerId);
- virtual void unban(const std::string &name);
+ virtual void unbanName(const std::string &name);
virtual void mute(int playerId, int type, int limit);
diff --git a/src/net/ea/playerhandler.cpp b/src/net/ea/playerhandler.cpp
index 6a841415f..76a7b0dbc 100644
--- a/src/net/ea/playerhandler.cpp
+++ b/src/net/ea/playerhandler.cpp
@@ -645,4 +645,5 @@ int PlayerHandler::getAttackLocation() const
{
return EA_ATK;
}
+
} // namespace Ea
diff --git a/src/net/inventoryhandler.h b/src/net/inventoryhandler.h
index ec2f3db47..642d6f1c1 100644
--- a/src/net/inventoryhandler.h
+++ b/src/net/inventoryhandler.h
@@ -57,8 +57,8 @@ class InventoryHandler
//void changeCart() = 0;
- virtual void moveItem(int source, int slot, int amount,
- int destination) = 0;
+ virtual void moveItem2(int source, int slot, int amount,
+ int destination) = 0;
// TODO: fix/remove me
virtual size_t getSize(int type) const = 0;
diff --git a/src/net/manaserv/adminhandler.cpp b/src/net/manaserv/adminhandler.cpp
index 609c9e4f1..f44da97ff 100644
--- a/src/net/manaserv/adminhandler.cpp
+++ b/src/net/manaserv/adminhandler.cpp
@@ -62,7 +62,7 @@ void AdminHandler::kick(int playerId A_UNUSED)
// TODO
}
-void AdminHandler::kick(const std::string &name A_UNUSED)
+void AdminHandler::kickName(const std::string &name A_UNUSED)
{
// TODO
}
@@ -72,7 +72,7 @@ void AdminHandler::ban(int playerId A_UNUSED)
// TODO
}
-void AdminHandler::ban(const std::string &name A_UNUSED)
+void AdminHandler::banName(const std::string &name A_UNUSED)
{
// TODO
}
@@ -82,7 +82,7 @@ void AdminHandler::unban(int playerId A_UNUSED)
// TODO
}
-void AdminHandler::unban(const std::string &name A_UNUSED)
+void AdminHandler::unbanName(const std::string &name A_UNUSED)
{
// TODO
}
diff --git a/src/net/manaserv/adminhandler.h b/src/net/manaserv/adminhandler.h
index a4157b3b0..87c536c31 100644
--- a/src/net/manaserv/adminhandler.h
+++ b/src/net/manaserv/adminhandler.h
@@ -42,15 +42,15 @@ class AdminHandler : public Net::AdminHandler
void kick(int playerId);
- void kick(const std::string &name);
+ void kickName(const std::string &name);
void ban(int playerId);
- void ban(const std::string &name);
+ void banName(const std::string &name);
void unban(int playerId);
- void unban(const std::string &name);
+ void unbanName(const std::string &name);
void mute(int playerId, int type, int limit);
diff --git a/src/net/manaserv/attributes.cpp b/src/net/manaserv/attributes.cpp
index 662032e29..c032b6bb8 100644
--- a/src/net/manaserv/attributes.cpp
+++ b/src/net/manaserv/attributes.cpp
@@ -73,16 +73,16 @@ namespace Attributes
static unsigned int attributeMinimum = 0;
static unsigned int attributeMaximum = 0;
- unsigned int getCreationPoints()
+ unsigned int getCreationPoints() const
{ return creationPoints; }
- unsigned int getAttributeMinimum()
+ unsigned int getAttributeMinimum() const
{ return attributeMinimum; }
- unsigned int getAttributeMaximum()
+ unsigned int getAttributeMaximum() const
{ return attributeMaximum; }
- std::vector<std::string>& getLabels()
+ std::vector<std::string>& getLabels() const
{ return attributeLabels; }
/**
diff --git a/src/net/manaserv/connection.h b/src/net/manaserv/connection.h
index 4263ae21f..1d3454c75 100644
--- a/src/net/manaserv/connection.h
+++ b/src/net/manaserv/connection.h
@@ -63,7 +63,7 @@ namespace ManaServ
*/
void disconnect();
- State getState()
+ State getState() const
{ return mState; }
/**
diff --git a/src/net/manaserv/gamehandler.h b/src/net/manaserv/gamehandler.h
index 443533bba..83e636e0e 100644
--- a/src/net/manaserv/gamehandler.h
+++ b/src/net/manaserv/gamehandler.h
@@ -52,14 +52,16 @@ class GameHandler : public MessageHandler, public Net::GameHandler
void ping(int tick);
- bool removeDeadBeings() const { return false; }
+ bool removeDeadBeings() const
+ { return false; }
void clear();
void gameLoading();
/** The ManaServ protocol doesn't use the MP status bar. */
- bool canUseMagicBar() const { return false; }
+ bool canUseMagicBar() const
+ { return false; }
void disconnect2();
};
diff --git a/src/net/manaserv/guildhandler.h b/src/net/manaserv/guildhandler.h
index 893a7157b..47d595bfa 100644
--- a/src/net/manaserv/guildhandler.h
+++ b/src/net/manaserv/guildhandler.h
@@ -35,7 +35,7 @@ class GuildHandler : public Net::GuildHandler, public MessageHandler
public:
GuildHandler();
- bool isSupported()
+ bool isSupported() const
{ return true; }
void handleMessage(Net::MessageIn &msg);
diff --git a/src/net/manaserv/loginhandler.cpp b/src/net/manaserv/loginhandler.cpp
index 8b8ac831f..f1c597c00 100644
--- a/src/net/manaserv/loginhandler.cpp
+++ b/src/net/manaserv/loginhandler.cpp
@@ -339,7 +339,7 @@ void LoginHandler::readServerInfo(Net::MessageIn &msg)
return;
// Set the update host when included in the message
- const std::string updateHost = msg.readString();
+ std::string updateHost = msg.readString();
if (!updateHost.empty())
{
if (!checkPath(updateHost))
diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp
index 5ebf840bc..aa79d4d41 100644
--- a/src/net/manaserv/playerhandler.cpp
+++ b/src/net/manaserv/playerhandler.cpp
@@ -448,4 +448,9 @@ void PlayerHandler::requestOnlineList()
}
+void PlayerHandler::updateStatus(Uint8 status)
+{
+
+}
+
} // namespace ManaServ
diff --git a/src/net/manaserv/playerhandler.h b/src/net/manaserv/playerhandler.h
index 0255406a8..23d2f5e32 100644
--- a/src/net/manaserv/playerhandler.h
+++ b/src/net/manaserv/playerhandler.h
@@ -74,6 +74,8 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
Vector getDefaultWalkSpeed() const;
+ void updateStatus(Uint8 status);
+
private:
void handleMapChangeMessage(Net::MessageIn &msg);
};
diff --git a/src/net/manaserv/specialhandler.cpp b/src/net/manaserv/specialhandler.cpp
index 13c6f7613..c168afd7c 100644
--- a/src/net/manaserv/specialhandler.cpp
+++ b/src/net/manaserv/specialhandler.cpp
@@ -53,19 +53,19 @@ void SpecialHandler::use(int id)
gameServerConnection->send(msg);
}
-void SpecialHandler::use(int id A_UNUSED, int level A_UNUSED,
- int beingId A_UNUSED)
+void SpecialHandler::useBeing(int id A_UNUSED, int level A_UNUSED,
+ int beingId A_UNUSED)
{
// TODO
}
-void SpecialHandler::use(int id A_UNUSED, int level A_UNUSED, int x A_UNUSED,
- int y A_UNUSED)
+void SpecialHandler::usePos(int id A_UNUSED, int level A_UNUSED,
+ int x A_UNUSED, int y A_UNUSED)
{
// TODO
}
-void SpecialHandler::use(int id A_UNUSED, const std::string &map A_UNUSED)
+void SpecialHandler::useMap(int id A_UNUSED, const std::string &map A_UNUSED)
{
// TODO
}
diff --git a/src/net/manaserv/specialhandler.h b/src/net/manaserv/specialhandler.h
index f6a20e4ac..2f1ce4d07 100644
--- a/src/net/manaserv/specialhandler.h
+++ b/src/net/manaserv/specialhandler.h
@@ -39,11 +39,11 @@ class SpecialHandler : public MessageHandler, public Net::SpecialHandler
void use(int id);
- void use(int id, int level, int beingId);
+ void useBeing(int id, int level, int beingId);
- void use(int id, int level, int x, int y);
+ void usePos(int id, int level, int x, int y);
- void use(int id, const std::string &map);
+ void useMap(int id, const std::string &map);
};
} // namespace ManaServ
diff --git a/src/net/messagein.cpp b/src/net/messagein.cpp
index 4fb61dc6a..0547ed337 100644
--- a/src/net/messagein.cpp
+++ b/src/net/messagein.cpp
@@ -241,7 +241,7 @@ std::string MessageIn::readRawString(int length)
return str;
}
-char *MessageIn::readBytes(int length)
+unsigned char *MessageIn::readBytes(int length)
{
// Get string length
if (length < 0)
@@ -255,13 +255,28 @@ char *MessageIn::readBytes(int length)
return nullptr;
}
- char *buf = new char[length + 2];
+ unsigned char *buf = new unsigned char[length + 2];
memcpy (buf, mData + mPos, length);
buf[length] = 0;
buf[length + 1] = 0;
mPos += length;
+#ifdef ENABLEDEBUGLOG
+ std::string str;
+ for (int f = 0; f < length; f ++)
+ str += strprintf ("%02x", (unsigned)buf[f]);
+ str += " ";
+ for (int f = 0; f < length; f ++)
+ {
+ if (buf[f])
+ str += strprintf ("%c", buf[f]);
+ else
+ str += "_";
+ }
+ logger->log("ReadBytes: " + str);
+#endif
+
PacketCounters::incInBytes(length);
return buf;
}
diff --git a/src/net/messagein.h b/src/net/messagein.h
index 8dd43a1a0..1eb5bf232 100644
--- a/src/net/messagein.h
+++ b/src/net/messagein.h
@@ -95,7 +95,7 @@ class MessageIn
virtual std::string readRawString(int length);
- char *readBytes(int length);
+ unsigned char *readBytes(int length);
virtual ~MessageIn()
{ }
diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h
index f62acc0c9..6ae912102 100644
--- a/src/net/playerhandler.h
+++ b/src/net/playerhandler.h
@@ -73,6 +73,8 @@ class PlayerHandler
virtual Vector getDefaultWalkSpeed() const = 0;
virtual void requestOnlineList() = 0;
+
+ virtual void updateStatus(Uint8 status) = 0;
};
} // namespace Net
diff --git a/src/net/serverinfo.h b/src/net/serverinfo.h
index fb6a99a33..b4bb1a2d8 100644
--- a/src/net/serverinfo.h
+++ b/src/net/serverinfo.h
@@ -54,7 +54,7 @@ public:
ServerInfo()
{
type = TMWATHENA;
- port = 0;
+ port = 6901;
save = false;
version.first = 0;
}
diff --git a/src/net/specialhandler.h b/src/net/specialhandler.h
index 7ed3673cf..f385f47f9 100644
--- a/src/net/specialhandler.h
+++ b/src/net/specialhandler.h
@@ -35,11 +35,11 @@ class SpecialHandler
virtual void use(int id) = 0;
- virtual void use(int id, int level, int beingId) = 0;
+ virtual void useBeing(int id, int level, int beingId) = 0;
- virtual void use(int id, int level, int x, int y) = 0;
+ virtual void usePos(int id, int level, int x, int y) = 0;
- virtual void use(int id, const std::string &map) = 0;
+ virtual void useMap(int id, const std::string &map) = 0;
};
}
diff --git a/src/net/tmwa/beinghandler.cpp b/src/net/tmwa/beinghandler.cpp
index 627db1402..8d279fc32 100644
--- a/src/net/tmwa/beinghandler.cpp
+++ b/src/net/tmwa/beinghandler.cpp
@@ -590,7 +590,7 @@ void BeingHandler::processPlayerMoveUpdate(Net::MessageIn &msg, int msgType)
if (gmstatus & 0x80)
dstBeing->setGM(true);
- if (msgType == 1)
+ if (msgType == 1 || msgType == 2)
{
int type = msg.readInt8();
switch (type)
diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp
index 717df1284..1bee91144 100644
--- a/src/net/tmwa/charserverhandler.cpp
+++ b/src/net/tmwa/charserverhandler.cpp
@@ -364,8 +364,11 @@ void CharServerHandler::processCharLogin(Net::MessageIn &msg)
Net::Character *character = new Net::Character;
readPlayerData(msg, character, version);
mCharacters.push_back(character);
- logger->log("CharServer: Player: %s (%d)",
- character->dummy->getName().c_str(), character->slot);
+ if (character && character->dummy)
+ {
+ logger->log("CharServer: Player: %s (%d)",
+ character->dummy->getName().c_str(), character->slot);
+ }
}
Client::setState(STATE_CHAR_SELECT);
diff --git a/src/net/tmwa/inventoryhandler.cpp b/src/net/tmwa/inventoryhandler.cpp
index 7fa26f5ed..db670a17b 100644
--- a/src/net/tmwa/inventoryhandler.cpp
+++ b/src/net/tmwa/inventoryhandler.cpp
@@ -186,8 +186,8 @@ void InventoryHandler::closeStorage(int type A_UNUSED)
MessageOut outMsg(CMSG_CLOSE_STORAGE);
}
-void InventoryHandler::moveItem(int source, int slot, int amount,
- int destination)
+void InventoryHandler::moveItem2(int source, int slot, int amount,
+ int destination)
{
if (source == Inventory::INVENTORY && destination == Inventory::STORAGE)
{
diff --git a/src/net/tmwa/inventoryhandler.h b/src/net/tmwa/inventoryhandler.h
index d2ecc4b6d..c6e000b3a 100644
--- a/src/net/tmwa/inventoryhandler.h
+++ b/src/net/tmwa/inventoryhandler.h
@@ -53,7 +53,7 @@ class InventoryHandler : public MessageHandler, public Ea::InventoryHandler
void closeStorage(int type);
- void moveItem(int source, int slot, int amount, int destination);
+ void moveItem2(int source, int slot, int amount, int destination);
};
} // namespace TmwAthena
diff --git a/src/net/tmwa/network.cpp b/src/net/tmwa/network.cpp
index addc737ee..31329eafb 100644
--- a/src/net/tmwa/network.cpp
+++ b/src/net/tmwa/network.cpp
@@ -83,7 +83,7 @@ short packet_lengths[] =
-1, -1, 20, 10, 32, 9, 34, 14, 2, 6, 48, 56, -1, 4, 5, 10,
// #0x0200
26, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 19, 10, 0, 0, 0,
- 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, -1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-1, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
diff --git a/src/net/tmwa/network.h b/src/net/tmwa/network.h
index 17a4f7370..c0ec6ef3c 100644
--- a/src/net/tmwa/network.h
+++ b/src/net/tmwa/network.h
@@ -39,7 +39,7 @@
* Protocol version, reported to the eAthena char and mapserver who can adjust
* the protocol accordingly.
*/
-#define CLIENT_PROTOCOL_VERSION 4
+#define CLIENT_PROTOCOL_VERSION 5
#define CLIENT_TMW_PROTOCOL_VERSION 1
namespace TmwAthena
diff --git a/src/net/tmwa/npchandler.cpp b/src/net/tmwa/npchandler.cpp
index 574f34d55..d86c64a96 100644
--- a/src/net/tmwa/npchandler.cpp
+++ b/src/net/tmwa/npchandler.cpp
@@ -25,6 +25,7 @@
#include "localplayer.h"
#include "gui/npcdialog.h"
+#include "gui/viewport.h"
#include "net/messagein.h"
#include "net/net.h"
@@ -41,7 +42,8 @@ extern Net::NpcHandler *npcHandler;
namespace TmwAthena
{
-NpcHandler::NpcHandler()
+NpcHandler::NpcHandler() :
+ mRequestLang(false)
{
static const Uint16 _messages[] =
{
@@ -51,6 +53,7 @@ NpcHandler::NpcHandler()
SMSG_NPC_CLOSE,
SMSG_NPC_INT_INPUT,
SMSG_NPC_STR_INPUT,
+ SMSG_NPC_COMMAND,
0
};
handledMessages = _messages;
@@ -59,9 +62,12 @@ NpcHandler::NpcHandler()
void NpcHandler::handleMessage(Net::MessageIn &msg)
{
- getNpc(msg, msg.getId() == SMSG_NPC_CHOICE
+ int npcId = getNpc(msg, msg.getId() == SMSG_NPC_CHOICE
|| msg.getId() == SMSG_NPC_MESSAGE);
+ if (msg.getId() != SMSG_NPC_STR_INPUT)
+ mRequestLang = false;
+
switch (msg.getId())
{
case SMSG_NPC_CHOICE:
@@ -85,7 +91,14 @@ void NpcHandler::handleMessage(Net::MessageIn &msg)
break;
case SMSG_NPC_STR_INPUT:
- processNpcStrInput(msg);
+ if (mRequestLang)
+ processLangReuqest(msg, npcId);
+ else
+ processNpcStrInput(msg);
+ break;
+
+ case SMSG_NPC_COMMAND:
+ processNpcCommand(msg, npcId);
break;
default:
@@ -118,6 +131,8 @@ void NpcHandler::closeDialog(int npcId)
{
if ((*it).second.dialog)
(*it).second.dialog->close();
+ if ((*it).second.dialog == mDialog)
+ mDialog = nullptr;
mNpcDialogs.erase(it);
}
}
@@ -213,6 +228,7 @@ int NpcHandler::getNpc(Net::MessageIn &msg, bool haveLength)
else
{
mDialog = new NpcDialog(npcId);
+ mDialog->saveCamera();
if (player_node)
player_node->stopWalking(false);
Wrapper wrap;
@@ -222,9 +238,70 @@ int NpcHandler::getNpc(Net::MessageIn &msg, bool haveLength)
}
else
{
+ if (mDialog && mDialog != diag->second.dialog)
+ mDialog->restoreCamera();
mDialog = diag->second.dialog;
+ if (mDialog)
+ mDialog->saveCamera();
}
return npcId;
}
+void NpcHandler::processNpcCommand(Net::MessageIn &msg, int npcId)
+{
+ const int cmd = msg.readInt16();
+ switch (cmd)
+ {
+ case 0:
+ mRequestLang = true;
+ break;
+
+ case 1:
+ if (viewport)
+ viewport->moveCameraToActor(npcId);
+ break;
+
+ case 2:
+ if (viewport)
+ {
+ const int id = msg.readInt32();
+ const int x = msg.readInt16();
+ const int y = msg.readInt16();
+ if (!id)
+ viewport->moveCameraToPosition(x, y);
+ else
+ viewport->moveCameraToActor(id, x, y);
+ }
+ break;
+
+ case 3:
+ if (viewport)
+ viewport->returnCamera();
+ break;
+
+ case 4:
+ if (viewport)
+ {
+ msg.readInt32(); // id
+ const int x = msg.readInt16();
+ const int y = msg.readInt16();
+ viewport->moveCameraRelative(x, y);
+ }
+ break;
+ case 5:
+ closeDialog(npcId);
+ break;
+
+ default:
+ logger->log("unknown npc command: %d", cmd);
+ break;
+ }
+}
+
+void NpcHandler::processLangReuqest(Net::MessageIn &msg A_UNUSED, int npcId)
+{
+ mRequestLang = false;
+ stringInput(npcId, getLangSimple());
+}
+
} // namespace TmwAthena
diff --git a/src/net/tmwa/npchandler.h b/src/net/tmwa/npchandler.h
index 967829ddc..1cfcacb20 100644
--- a/src/net/tmwa/npchandler.h
+++ b/src/net/tmwa/npchandler.h
@@ -65,6 +65,13 @@ class NpcHandler : public MessageHandler, public Ea::NpcHandler
void sellItem(int beingId, int itemId, int amount);
int getNpc(Net::MessageIn &msg, bool haveLength);
+
+ void processNpcCommand(Net::MessageIn &msg, int npcId);
+
+ void processLangReuqest(Net::MessageIn &msg, int npcId);
+
+ private:
+ bool mRequestLang;
};
} // namespace TmwAthena
diff --git a/src/net/tmwa/playerhandler.cpp b/src/net/tmwa/playerhandler.cpp
index d5f0641eb..16e833ec9 100644
--- a/src/net/tmwa/playerhandler.cpp
+++ b/src/net/tmwa/playerhandler.cpp
@@ -22,6 +22,7 @@
#include "net/tmwa/playerhandler.h"
+#include "configuration.h"
#include "logger.h"
#include "net/messagein.h"
@@ -218,7 +219,7 @@ void PlayerHandler::processOnlineList(Net::MessageIn &msg)
return;
int size = msg.readInt16() - 4;
- std::vector<std::string> arr;
+ std::vector<OnlinePlayer*> arr;
if (!size)
{
@@ -227,14 +228,44 @@ void PlayerHandler::processOnlineList(Net::MessageIn &msg)
return;
}
- const char *start = msg.readBytes(size);
- const char *buf = start;
+ char *start = (char*)msg.readBytes(size);
+ if (!start)
+ return;
+
+ char *buf = start;
- while (buf - start + 1 < size && *(buf + 1))
+ int addVal = 1;
+ if (serverVersion >= 4)
+ addVal = 3;
+
+ while (buf - start + 1 < size && *(buf + addVal))
{
-// char status = *buf; // now unused
+ unsigned char status = 255;
+ unsigned char ver = 0;
+ unsigned char level = 0;
+ if (serverVersion >= 4)
+ {
+ status = *buf;
+ buf ++;
+ level = *buf;
+ buf ++;
+ ver = *buf;
+ }
buf ++;
- arr.push_back(buf);
+
+ int gender = GENDER_UNSPECIFIED;
+ if (serverVersion >= 4)
+ {
+ if (config.getBoolValue("showgender"))
+ {
+ if (status & Being::FLAG_GENDER)
+ gender = GENDER_MALE;
+ else
+ gender = GENDER_FEMALE;
+ }
+ }
+ arr.push_back(new OnlinePlayer((char*)buf,
+ status, level, gender, ver));
buf += strlen(buf) + 1;
}
@@ -243,4 +274,11 @@ void PlayerHandler::processOnlineList(Net::MessageIn &msg)
delete [] start;
}
+void PlayerHandler::updateStatus(Uint8 status)
+{
+ MessageOut outMsg(CMSG_SET_STATUS);
+ outMsg.writeInt8(status);
+ outMsg.writeInt8(0);
+}
+
} // namespace TmwAthena
diff --git a/src/net/tmwa/playerhandler.h b/src/net/tmwa/playerhandler.h
index 0fa524d51..14aa191f6 100644
--- a/src/net/tmwa/playerhandler.h
+++ b/src/net/tmwa/playerhandler.h
@@ -53,6 +53,7 @@ class PlayerHandler : public MessageHandler, public Ea::PlayerHandler
void changeAction(Being::Action action);
void processOnlineList(Net::MessageIn &msg);
void requestOnlineList();
+ void updateStatus(Uint8 status);
void respawn();
};
diff --git a/src/net/tmwa/protocol.h b/src/net/tmwa/protocol.h
index 0f124cc20..256f1dce4 100644
--- a/src/net/tmwa/protocol.h
+++ b/src/net/tmwa/protocol.h
@@ -335,5 +335,7 @@ enum
#define SMSG_IGNORE_ALL_RESPONSE 0x00d2
#define CMSG_ONLINE_LIST 0x0210
#define SMSG_ONLINE_LIST 0x0211
+#define SMSG_NPC_COMMAND 0x0212
+#define CMSG_SET_STATUS 0x0213
#endif
diff --git a/src/net/tmwa/specialhandler.cpp b/src/net/tmwa/specialhandler.cpp
index 9fa7b6dfa..129f0b47e 100644
--- a/src/net/tmwa/specialhandler.cpp
+++ b/src/net/tmwa/specialhandler.cpp
@@ -69,7 +69,7 @@ void SpecialHandler::handleMessage(Net::MessageIn &msg)
}
}
-void SpecialHandler::use(int id, int level, int beingId)
+void SpecialHandler::useBeing(int id, int level, int beingId)
{
MessageOut outMsg(CMSG_SKILL_USE_BEING);
outMsg.writeInt16(static_cast<Sint16>(level));
@@ -77,7 +77,7 @@ void SpecialHandler::use(int id, int level, int beingId)
outMsg.writeInt16(static_cast<Sint16>(beingId));
}
-void SpecialHandler::use(int id, int level, int x, int y)
+void SpecialHandler::usePos(int id, int level, int x, int y)
{
MessageOut outMsg(CMSG_SKILL_USE_POSITION);
outMsg.writeInt16(static_cast<Sint16>(level));
@@ -86,7 +86,7 @@ void SpecialHandler::use(int id, int level, int x, int y)
outMsg.writeInt16(static_cast<Sint16>(y));
}
-void SpecialHandler::use(int id, const std::string &map)
+void SpecialHandler::useMap(int id, const std::string &map)
{
MessageOut outMsg(CMSG_SKILL_USE_MAP);
outMsg.writeInt16(static_cast<Sint16>(id));
diff --git a/src/net/tmwa/specialhandler.h b/src/net/tmwa/specialhandler.h
index f17ef4c44..216adddc6 100644
--- a/src/net/tmwa/specialhandler.h
+++ b/src/net/tmwa/specialhandler.h
@@ -40,11 +40,11 @@ class SpecialHandler : public MessageHandler, public Ea::SpecialHandler
void handleMessage(Net::MessageIn &msg);
- void use(int id, int level, int beingId);
+ void useBeing(int id, int level, int beingId);
- void use(int id, int level, int x, int y);
+ void usePos(int id, int level, int x, int y);
- void use(int id, const std::string &map);
+ void useMap(int id, const std::string &map);
};
} // namespace TmwAthena
diff --git a/src/opengl1graphics.cpp b/src/opengl1graphics.cpp
index 6f712f698..34e9fcda3 100644
--- a/src/opengl1graphics.cpp
+++ b/src/opengl1graphics.cpp
@@ -61,8 +61,8 @@ void OpenGL1Graphics::setSync(bool sync)
mSync = sync;
}
-bool OpenGL1Graphics::setVideoMode(int w, int h, int bpp,
- bool fs, bool hwaccel)
+bool OpenGL1Graphics::setVideoMode(int w, int h, int bpp, bool fs,
+ bool hwaccel, bool resize, bool noFrame)
{
logger->log("Setting video mode %dx%d %s",
w, h, fs ? "fullscreen" : "windowed");
@@ -74,9 +74,25 @@ bool OpenGL1Graphics::setVideoMode(int w, int h, int bpp,
mBpp = bpp;
mFullscreen = fs;
mHWAccel = hwaccel;
+ mEnableResize = resize;
+ mNoFrame = noFrame;
if (fs)
+ {
displayFlags |= SDL_FULLSCREEN;
+ }
+ else
+ {
+ // Resizing currently not supported on Windows, where it would require
+ // reuploading all textures.
+#if !defined(_WIN32)
+ if (resize)
+ displayFlags |= SDL_RESIZABLE;
+#endif
+ }
+
+ if (noFrame)
+ displayFlags |= SDL_NOFRAME;
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
@@ -472,6 +488,7 @@ void OpenGL1Graphics::_beginDraw()
void OpenGL1Graphics::_endDraw()
{
+ popClipArea();
}
SDL_Surface* OpenGL1Graphics::getScreenshot()
diff --git a/src/opengl1graphics.h b/src/opengl1graphics.h
index 87458d8b9..76dc3ef00 100644
--- a/src/opengl1graphics.h
+++ b/src/opengl1graphics.h
@@ -45,10 +45,12 @@ class OpenGL1Graphics : public Graphics
* the next call to setVideoMode(). Only implemented on MacOS for now.
*/
void setSync(bool sync);
+
bool getSync() const
{ return mSync; }
- bool setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel);
+ bool setVideoMode(int w, int h, int bpp, bool fs,
+ bool hwaccel, bool resize, bool noFrame);
bool drawImage(Image *image,
int srcX, int srcY,
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp
index b744a3caf..2c3d914b0 100644
--- a/src/openglgraphics.cpp
+++ b/src/openglgraphics.cpp
@@ -71,7 +71,8 @@ void OpenGLGraphics::setSync(bool sync)
mSync = sync;
}
-bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
+bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs,
+ bool hwaccel, bool resize, bool noFrame)
{
logger->log("Setting video mode %dx%d %s",
w, h, fs ? "fullscreen" : "windowed");
@@ -83,9 +84,25 @@ bool OpenGLGraphics::setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel)
mBpp = bpp;
mFullscreen = fs;
mHWAccel = hwaccel;
+ mEnableResize = resize;
+ mNoFrame = noFrame;
if (fs)
+ {
displayFlags |= SDL_FULLSCREEN;
+ }
+ else
+ {
+ // Resizing currently not supported on Windows, where it would require
+ // reuploading all textures.
+#if !defined(_WIN32)
+ if (resize)
+ displayFlags |= SDL_RESIZABLE;
+#endif
+ }
+
+ if (noFrame)
+ displayFlags |= SDL_NOFRAME;
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
@@ -1017,6 +1034,7 @@ void OpenGLGraphics::_beginDraw()
void OpenGLGraphics::_endDraw()
{
+ popClipArea();
}
SDL_Surface* OpenGLGraphics::getScreenshot()
diff --git a/src/openglgraphics.h b/src/openglgraphics.h
index 1047223ad..f3bdc4470 100644
--- a/src/openglgraphics.h
+++ b/src/openglgraphics.h
@@ -45,10 +45,12 @@ class OpenGLGraphics : public Graphics
* the next call to setVideoMode(). Only implemented on MacOS for now.
*/
void setSync(bool sync);
+
bool getSync() const
{ return mSync; }
- bool setVideoMode(int w, int h, int bpp, bool fs, bool hwaccel);
+ bool setVideoMode(int w, int h, int bpp, bool fs,
+ bool hwaccel, bool resize, bool noFrame);
bool drawImage(Image *image,
int srcX, int srcY,
diff --git a/src/particle.h b/src/particle.h
index a79181498..7485b118f 100644
--- a/src/particle.h
+++ b/src/particle.h
@@ -219,7 +219,7 @@ class Particle : public Actor
/**
* Gets the flag if the particle is supposed to be moved by its parent
*/
- bool doesFollow()
+ bool doesFollow() const
{ return mFollow; }
/**
diff --git a/src/resources/action.h b/src/resources/action.h
index 1e3965363..3951cc02c 100644
--- a/src/resources/action.h
+++ b/src/resources/action.h
@@ -43,7 +43,7 @@ class Action
Animation *getAnimation(int direction) const;
- unsigned getNumber()
+ unsigned getNumber() const
{ return mNumber; }
void setNumber(unsigned n)
diff --git a/src/resources/colordb.cpp b/src/resources/colordb.cpp
index 1ffe507b2..2ddf27ac3 100644
--- a/src/resources/colordb.cpp
+++ b/src/resources/colordb.cpp
@@ -30,7 +30,7 @@
namespace
{
- ColorDB::Colors mHairColors;
+ int mHairColorsSize = 0;
bool mLoaded = false;
std::string mFail = "#ffffff";
ColorDB::ColorLists mColorLists;
@@ -44,10 +44,22 @@ void ColorDB::load()
loadHair();
if (serverVersion >= 1)
loadColorLists();
+
+ ColorListsIterator it = mColorLists.find("hair");
+ if (it != mColorLists.end())
+ mHairColorsSize = (*it).second.size();
+ else
+ mHairColorsSize = 0;
}
void ColorDB::loadHair()
{
+ std::map <int, ItemColor> colors;
+ ColorListsIterator it = mColorLists.find("hair");
+
+ if (it != mColorLists.end())
+ colors = it->second;
+
XML::Document *doc = new XML::Document("hair.xml");
XmlNodePtr root = doc->rootNode();
bool hairXml = true;
@@ -65,7 +77,7 @@ void ColorDB::loadHair()
if (!root || !xmlNameEqual(root, "colors"))
{
logger->log1("ColorDB: Failed to find any color files.");
- mHairColors[0] = mFail;
+ colors[0] = ItemColor(0, "", "");
mLoaded = true;
delete doc;
@@ -80,17 +92,17 @@ void ColorDB::loadHair()
{
int id = XML::getProperty(node, "id", 0);
- if (mHairColors.find(id) != mHairColors.end())
+ if (colors.find(id) != colors.end())
logger->log("ColorDB: Redefinition of dye ID %d", id);
- mHairColors[id] = hairXml ?
- XML::getProperty(node, "value", "#FFFFFF") :
- XML::getProperty(node, "dye", "#FFFFFF");
+ colors[id] = ItemColor(id, XML::getProperty(node, "name", ""),
+ XML::getProperty(node, hairXml ? "value" : "dye", "#FFFFFF"));
}
}
delete doc;
+ mColorLists["hair"] = colors;
mLoaded = true;
}
@@ -139,7 +151,6 @@ void ColorDB::unload()
{
logger->log1("Unloading color database...");
- mHairColors.clear();
mColorLists.clear();
mLoaded = false;
}
@@ -149,22 +160,54 @@ std::string &ColorDB::getHairColor(int id)
if (!mLoaded)
load();
- ColorIterator i = mHairColors.find(id);
+ ColorListsIterator it = mColorLists.find("hair");
+ if (it == mColorLists.end())
+ {
+ logger->log1("ColorDB: Error, hair colors list empty");
+ return mFail;
+ }
+
+ ColorIterator i = (*it).second.find(id);
+
+ if (i == (*it).second.end())
+ {
+ logger->log("ColorDB: Error, unknown dye ID# %d", id);
+ return mFail;
+ }
+ else
+ {
+ return i->second.color;
+ }
+}
+
+std::string &ColorDB::getHairColorName(int id)
+{
+ if (!mLoaded)
+ load();
+
+ ColorListsIterator it = mColorLists.find("hair");
+ if (it == mColorLists.end())
+ {
+ logger->log1("ColorDB: Error, hair colors list empty");
+ return mFail;
+ }
+
+ ColorIterator i = (*it).second.find(id);
- if (i == mHairColors.end())
+ if (i == (*it).second.end())
{
logger->log("ColorDB: Error, unknown dye ID# %d", id);
return mFail;
}
else
{
- return i->second;
+ return i->second.name;
}
}
int ColorDB::getHairSize()
{
- return static_cast<int>(mHairColors.size());
+ return mHairColorsSize;
}
std::map <int, ColorDB::ItemColor> *ColorDB::getColorsList(std::string name)
diff --git a/src/resources/colordb.h b/src/resources/colordb.h
index 36907095e..ade4227f8 100644
--- a/src/resources/colordb.h
+++ b/src/resources/colordb.h
@@ -70,12 +70,14 @@ namespace ColorDB
std::string &getHairColor(int id);
+ std::string &getHairColorName(int id);
+
int getHairSize();
std::map <int, ItemColor> *getColorsList(std::string name);
// Color DB
- typedef std::map<int, std::string> Colors;
+ typedef std::map<int, ItemColor> Colors;
typedef Colors::iterator ColorIterator;
typedef std::map <std::string, std::map <int, ItemColor> > ColorLists;
typedef ColorLists::iterator ColorListsIterator;
diff --git a/src/resources/emotedb.cpp b/src/resources/emotedb.cpp
index c6126a57b..07e192cd4 100644
--- a/src/resources/emotedb.cpp
+++ b/src/resources/emotedb.cpp
@@ -67,6 +67,10 @@ void EmoteDB::load()
continue;
int id = XML::getProperty(emoteNode, "id", -1);
+ // skip hight images
+ if (id > 19)
+ continue;
+
if (id == -1)
{
logger->log1("Emote Database: Emote with missing ID in "
@@ -104,7 +108,6 @@ void EmoteDB::load()
mLastEmote = id;
}
-
XML::Document doc2("graphics/sprites/manaplus_emotes.xml");
rootNode = doc2.rootNode();
diff --git a/src/resources/image.cpp b/src/resources/image.cpp
index d94967631..6f9042029 100644
--- a/src/resources/image.cpp
+++ b/src/resources/image.cpp
@@ -79,6 +79,8 @@ Image::Image(SDL_Surface *image, bool hasAlphaChannel0, Uint8 *alphaChannel):
{
logger->log(
"Image::Image(SDL_Surface*): Couldn't load invalid Surface!");
+ mBounds.w = 0;
+ mBounds.h = 0;
}
}
@@ -119,10 +121,8 @@ Image::~Image()
unload();
}
-Resource *Image::load(void *buffer, unsigned bufferSize)
+Resource *Image::load(SDL_RWops *rw)
{
- // Load the raw file data from the buffer in an RWops structure
- SDL_RWops *rw = SDL_RWFromMem(buffer, bufferSize);
SDL_Surface *tmpImage = IMG_Load_RW(rw, 1);
if (!tmpImage)
@@ -137,9 +137,8 @@ Resource *Image::load(void *buffer, unsigned bufferSize)
return image;
}
-Resource *Image::load(void *buffer, unsigned bufferSize, Dye const &dye)
+Resource *Image::load(SDL_RWops *rw, Dye const &dye)
{
- SDL_RWops *rw = SDL_RWFromMem(buffer, bufferSize);
SDL_Surface *tmpImage = IMG_Load_RW(rw, 1);
if (!tmpImage)
@@ -162,7 +161,7 @@ Resource *Image::load(void *buffer, unsigned bufferSize, Dye const &dye)
SDL_Surface *surf = SDL_ConvertSurface(tmpImage, &rgba, SDL_SWSURFACE);
SDL_FreeSurface(tmpImage);
- Uint32 *pixels = static_cast< Uint32 * >(surf->pixels);
+ Uint32 *pixels = static_cast<Uint32 *>(surf->pixels);
for (Uint32 *p_end = pixels + surf->w * surf->h; pixels != p_end; ++pixels)
{
const Uint32 p = *pixels;
@@ -210,10 +209,11 @@ Image *Image::createTextSurface(SDL_Surface *tmpImage, float alpha)
bool hasAlpha = false;
bool converted = false;
+ const int sz = tmpImage->w * tmpImage->h;
+
// The alpha channel to be filled with alpha values
- Uint8 *alphaChannel = new Uint8[tmpImage->w * tmpImage->h];
+ Uint8 *alphaChannel = new Uint8[sz];
- const int sz = tmpImage->w * tmpImage->h;
const SDL_PixelFormat * const fmt = tmpImage->format;
if (fmt->Amask)
{
@@ -466,7 +466,7 @@ Image* Image::SDLmerge(Image *image, int x, int y)
SDL_LockSurface(surface);
SDL_LockSurface(mSDLSurface);
- const int x0 = (y * getWidth()) + x;
+ const int x0 = (y * mBounds.w) + x;
const int maxX = std::min(image->mBounds.w,
static_cast<Uint16>(mBounds.w - x));
const int maxY = std::min(image->mBounds.w,
@@ -479,7 +479,7 @@ Image* Image::SDLmerge(Image *image, int x, int y)
for (offset_y = ((y > 0) ? 0 : -y); offset_y < maxY; offset_y++)
{
// Computing offset on both images
- current_offset = (offset_y * getWidth()) + x1;
+ current_offset = (offset_y * mBounds.w) + x1;
surface_offset = offset_y * surface->w + offset_x;
// Retrieving a pixel to merge
@@ -546,7 +546,7 @@ Image* Image::SDLgetScaledImage(int width, int height)
return nullptr;
// No scaling when there is ... no different given size ...
- if (width == getWidth() && height == getHeight())
+ if (width == mBounds.w && height == mBounds.h)
return nullptr;
Image* scaledImage = nullptr;
@@ -555,8 +555,8 @@ Image* Image::SDLgetScaledImage(int width, int height)
if (mSDLSurface)
{
scaledSurface = zoomSurface(mSDLSurface,
- static_cast<double>(width) / getWidth(),
- static_cast<double>(height) / getHeight(),
+ static_cast<double>(width) / mBounds.w,
+ static_cast<double>(height) / mBounds.h,
1);
// The load function takes care of the SDL<->OpenGL implementation
@@ -626,22 +626,20 @@ Image *Image::_SDLload(SDL_Surface *tmpImage)
bool hasAlpha = false;
bool converted = false;
- // The alpha channel to be filled with alpha values
- Uint8 *alphaChannel = new Uint8[tmpImage->w * tmpImage->h];
-
if (tmpImage->format->BitsPerPixel != 32)
{
tmpImage = convertTo32Bit(tmpImage);
if (!tmpImage)
- {
- delete[] alphaChannel;
return nullptr;
- }
converted = true;
}
const int sz = tmpImage->w * tmpImage->h;
+
+ // The alpha channel to be filled with alpha values
+ Uint8 *alphaChannel = new Uint8[sz];
+
// Figure out whether the image uses its alpha layer
if (!tmpImage->format->palette)
{
@@ -663,19 +661,19 @@ Image *Image::_SDLload(SDL_Surface *tmpImage)
else
{
if (SDL_ALPHA_OPAQUE != 255)
+ {
hasAlpha = true;
- memset(alphaChannel, SDL_ALPHA_OPAQUE, sz);
-// for (int i = 0; i < sz; ++ i)
-// alphaChannel[i] = SDL_ALPHA_OPAQUE;
+ memset(alphaChannel, SDL_ALPHA_OPAQUE, sz);
+ }
}
}
else
{
if (SDL_ALPHA_OPAQUE != 255)
+ {
hasAlpha = true;
- memset(alphaChannel, SDL_ALPHA_OPAQUE, sz);
-// for (int i = 0; i < sz; ++ i)
-// alphaChannel[i] = SDL_ALPHA_OPAQUE;
+ memset(alphaChannel, SDL_ALPHA_OPAQUE, sz);
+ }
}
SDL_Surface *image;
@@ -705,7 +703,6 @@ Image *Image::_SDLload(SDL_Surface *tmpImage)
if (converted)
SDL_FreeSurface(tmpImage);
-// SDL_SetColorKey(image, SDL_SRCCOLORKEY | SDL_RLEACCEL, 0);
return new Image(image, hasAlpha, alphaChannel);
}
diff --git a/src/resources/image.h b/src/resources/image.h
index a9f5722cd..68ab09e58 100644
--- a/src/resources/image.h
+++ b/src/resources/image.h
@@ -66,28 +66,25 @@ class Image : public Resource
virtual ~Image();
/**
- * Loads an image from a buffer in memory.
+ * Loads an image from an SDL_RWops structure.
*
- * @param buffer The memory buffer containing the image data.
- * @param bufferSize The size of the memory buffer in bytes.
+ * @param rw The SDL_RWops to load the image from.
*
* @return <code>NULL</code> if an error occurred, a valid pointer
* otherwise.
*/
- static Resource *load(void *buffer, unsigned bufferSize);
+ static Resource *load(SDL_RWops *rw);
/**
- * Loads an image from a buffer in memory and recolors it.
+ * Loads an image from an SDL_RWops structure and recolors it.
*
- * @param buffer The memory buffer containing the image data.
- * @param bufferSize The size of the memory buffer in bytes.
+ * @param rw The SDL_RWops to load the image from.
* @param dye The dye used to recolor the image.
*
* @return <code>NULL</code> if an error occurred, a valid pointer
* otherwise.
*/
- static Resource *load(void *buffer, unsigned bufferSize,
- Dye const &dye);
+ static Resource *load(SDL_RWops *rw, Dye const &dye);
/**
* Loads an image from an SDL surface.
@@ -106,7 +103,7 @@ class Image : public Resource
/**
* Tells is the image is loaded
*/
- bool isLoaded()
+ bool isLoaded() const
{ return mLoaded; }
/**
@@ -220,16 +217,16 @@ class Image : public Resource
static int mTextureType;
#endif
- bool isHasAlphaChannel()
+ bool isHasAlphaChannel() const
{ return mHasAlphaChannel; }
- bool isAlphaVisible()
+ bool isAlphaVisible() const
{ return mIsAlphaVisible; }
void setAlphaVisible(bool b)
{ mIsAlphaVisible = b; }
- bool isAlphaCalculated()
+ bool isAlphaCalculated() const
{ return mIsAlphaCalculated; }
void setAlphaCalculated(bool b)
diff --git a/src/resources/imageset.h b/src/resources/imageset.h
index 69ebebdc0..edfc4b123 100644
--- a/src/resources/imageset.h
+++ b/src/resources/imageset.h
@@ -63,13 +63,13 @@ class ImageSet : public Resource
size_type size() const
{ return mImages.size(); }
- int getOffsetX()
+ int getOffsetX() const
{ return mOffsetX; }
void setOffsetX(int n)
{ mOffsetX = n; }
- int getOffsetY()
+ int getOffsetY() const
{ return mOffsetY; }
void setOffsetY(int n)
diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h
index 8c5e2dd8f..5f789663f 100644
--- a/src/resources/iteminfo.h
+++ b/src/resources/iteminfo.h
@@ -148,7 +148,8 @@ class ItemInfo
void setEffect(const std::string &effect)
{ mEffect = effect; }
- const std::string &getEffect() const { return mEffect; }
+ const std::string &getEffect() const
+ { return mEffect; }
void setType(ItemType type)
{ mType = type; }
@@ -250,7 +251,7 @@ class ItemInfo
void setColorsList(std::string name);
- bool isHaveColors()
+ bool isHaveColors() const
{ return !mColorList.empty(); }
const std::string replaceColors(std::string str,
diff --git a/src/resources/music.cpp b/src/resources/music.cpp
index 6e752ab60..b13812f18 100644
--- a/src/resources/music.cpp
+++ b/src/resources/music.cpp
@@ -26,30 +26,21 @@
#include "debug.h"
-Music::Music(Mix_Chunk *music):
- mChunk(music),
- mChannel(-1)
+Music::Music(Mix_Music *music) :
+ mMusic(music)
{
}
Music::~Music()
{
- //Mix_FreeMusic(music);
- Mix_FreeChunk(mChunk);
+ Mix_FreeMusic(mMusic);
}
-Resource *Music::load(void *buffer, unsigned bufferSize)
+Resource *Music::load(SDL_RWops *rw)
{
- // Load the raw file data from the buffer in an RWops structure
- SDL_RWops *rw = SDL_RWFromMem(buffer, bufferSize);
-
- // Use Mix_LoadMUS to load the raw music data
- //Mix_Music* music = Mix_LoadMUS_RW(rw); Need to be implemeted
- Mix_Chunk *tmpMusic = Mix_LoadWAV_RW(rw, 1);
-
- if (tmpMusic)
+ if (Mix_Music *music = Mix_LoadMUS_RW(rw))
{
- return new Music(tmpMusic);
+ return new Music(music);
}
else
{
@@ -58,30 +49,10 @@ Resource *Music::load(void *buffer, unsigned bufferSize)
}
}
-bool Music::play(int loops)
-{
- /*
- * Warning: loops should be always set to -1 (infinite) with current
- * implementation to avoid halting the playback of other samples
- */
-
- /*if (Mix_PlayMusic(music, loops))
- return true;*/
- Mix_VolumeChunk(mChunk, 120);
- mChannel = Mix_PlayChannel(-1, mChunk, loops);
-
- return mChannel != -1;
-}
-
-void Music::stop()
+bool Music::play(int loops, int fadeIn)
{
- /*
- * Warning: very dungerous trick, it could try to stop channels occupied
- * by samples rather than the current music file
- */
-
- //Mix_HaltMusic();
-
- if (mChannel != -1)
- Mix_HaltChannel(mChannel);
+ if (fadeIn > 0)
+ return Mix_FadeInMusic(mMusic, loops, fadeIn);
+ else
+ return Mix_PlayMusic(mMusic, loops);
}
diff --git a/src/resources/music.h b/src/resources/music.h
index 428c02572..88cc752bc 100644
--- a/src/resources/music.h
+++ b/src/resources/music.h
@@ -41,38 +41,32 @@ class Music : public Resource
/**
* Loads a music from a buffer in memory.
*
- * @param buffer The memory buffer containing the music data.
- * @param bufferSize The size of the memory buffer in bytes.
+ * @param rw The SDL_RWops to load the music data from.
*
* @return <code>NULL</code> if the an error occurred, a valid pointer
* otherwise.
*/
- static Resource *load(void *buffer, unsigned bufferSize);
+ static Resource *load(SDL_RWops *rw);
/**
* Plays the music.
*
- * @param loops Number of times to repeat the playback.
+ * @param loops Number of times to repeat the playback (-1 means
+ * forever).
+ * @param fadeIn Duration in milliseconds to fade in the music.
*
* @return <code>true</code> if the playback started properly
* <code>false</code> otherwise.
*/
- virtual bool play(int loops);
-
- /**
- * Stops the music.
- */
- virtual void stop();
+ bool play(int loops = -1, int fadeIn = 0);
protected:
/**
* Constructor.
*/
- Music(Mix_Chunk *music);
+ Music(Mix_Music *music);
- //Mix_Music *music;
- Mix_Chunk *mChunk;
- int mChannel;
+ Mix_Music *mMusic;
};
#endif
diff --git a/src/resources/resource.h b/src/resources/resource.h
index b8e06aaa7..c0ea7ca23 100644
--- a/src/resources/resource.h
+++ b/src/resources/resource.h
@@ -73,7 +73,7 @@ class Resource
{ return mRefCount; }
#ifdef DEBUG_DUMP_LEAKS
- bool getDumped()
+ bool getDumped() const
{ return mDumped; }
void setDumped(bool n)
diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp
index 3376394bc..c26526b97 100644
--- a/src/resources/resourcemanager.cpp
+++ b/src/resources/resourcemanager.cpp
@@ -35,6 +35,7 @@
#include "resources/spritedef.h"
#include "utils/mkdir.h"
+#include "utils/physfsrwops.h"
#include <physfs.h>
#include <SDL_image.h>
@@ -42,6 +43,7 @@
#include <fstream>
#include <iostream>
#include <sstream>
+#include <zlib.h>
#include <sys/stat.h>
#include <sys/time.h>
@@ -397,19 +399,16 @@ struct ResourceLoader
ResourceManager *manager;
std::string path;
ResourceManager::loader fun;
+
static Resource *load(void *v)
{
if (!v)
return nullptr;
ResourceLoader *l = static_cast< ResourceLoader * >(v);
- int fileSize;
- if (!l->manager)
+ SDL_RWops *rw = PHYSFSRWOPS_openRead(l->path.c_str());
+ if (!rw)
return nullptr;
- void *buffer = l->manager->loadFile(l->path, fileSize);
- if (!buffer)
- return nullptr;
- Resource *res = l->fun(buffer, fileSize);
- free(buffer);
+ Resource *res = l->fun(rw);
return res;
}
};
@@ -451,16 +450,14 @@ struct DyedImageLoader
d = new Dye(path.substr(p + 1));
path = path.substr(0, p);
}
- int fileSize;
- void *buffer = l->manager->loadFile(path, fileSize);
- if (!buffer)
+ SDL_RWops *rw = PHYSFSRWOPS_openRead(path.c_str());
+ if (!rw)
{
delete d;
return nullptr;
}
- Resource *res = d ? Image::load(buffer, fileSize, *d)
- : Image::load(buffer, fileSize);
- free(buffer);
+ Resource *res = d ? Image::load(rw, *d)
+ : Image::load(rw);
delete d;
return res;
}
@@ -695,18 +692,10 @@ void ResourceManager::saveTextFile(std::string path, std::string name,
SDL_Surface *ResourceManager::loadSDLSurface(const std::string &filename)
{
- int fileSize;
- void *buffer = loadFile(filename, fileSize);
- SDL_Surface *tmp = nullptr;
-
- if (buffer)
- {
- SDL_RWops *rw = SDL_RWFromMem(buffer, fileSize);
- tmp = IMG_Load_RW(rw, 1);
- ::free(buffer);
- }
-
- return tmp;
+ SDL_Surface *surface = nullptr;
+ if (SDL_RWops *rw = PHYSFSRWOPS_openRead(filename.c_str()))
+ surface = IMG_Load_RW(rw, 1);
+ return surface;
}
void ResourceManager::scheduleDelete(SDL_Surface* surface)
diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h
index f0146b8b4..9df96d354 100644
--- a/src/resources/resourcemanager.h
+++ b/src/resources/resourcemanager.h
@@ -37,7 +37,9 @@ class Music;
class Resource;
class SoundEffect;
class SpriteDef;
+
struct SDL_Surface;
+struct SDL_RWops;
/**
* A class for loading and managing resources.
@@ -48,7 +50,7 @@ class ResourceManager
public:
- typedef Resource *(*loader)(void *, unsigned);
+ typedef Resource *(*loader)(SDL_RWops *);
typedef Resource *(*generator)(void *);
ResourceManager();
@@ -252,17 +254,17 @@ class ResourceManager
*/
static void deleteInstance();
- int size()
+ int size() const
{ return mResources.size(); }
typedef std::map<std::string, Resource*> Resources;
typedef Resources::iterator ResourceIterator;
#ifdef DEBUG_DUMP_LEAKS
- Resources* getResources()
+ Resources* getResources() const
{ return &mResources; }
- Resources* getOrphanedResources()
+ Resources* getOrphanedResources() const
{ return &mOrphanedResources; }
#endif
diff --git a/src/resources/soundeffect.cpp b/src/resources/soundeffect.cpp
index eaa323bd6..6a3a980a7 100644
--- a/src/resources/soundeffect.cpp
+++ b/src/resources/soundeffect.cpp
@@ -31,14 +31,10 @@ SoundEffect::~SoundEffect()
Mix_FreeChunk(mChunk);
}
-Resource *SoundEffect::load(void *buffer, unsigned bufferSize)
+Resource *SoundEffect::load(SDL_RWops *rw)
{
- if (!buffer)
+ if (!rw)
return nullptr;
-
- // Load the raw file data from the buffer in an RWops structure
- SDL_RWops *rw = SDL_RWFromMem(buffer, bufferSize);
-
// Load the music data and free the RWops structure
Mix_Chunk *tmpSoundEffect = Mix_LoadWAV_RW(rw, 1);
diff --git a/src/resources/soundeffect.h b/src/resources/soundeffect.h
index 91ca3bb59..b8c9e8735 100644
--- a/src/resources/soundeffect.h
+++ b/src/resources/soundeffect.h
@@ -41,13 +41,12 @@ class SoundEffect : public Resource
/**
* Loads a sample from a buffer in memory.
*
- * @param buffer The memory buffer containing the sample data.
- * @param bufferSize The size of the memory buffer in bytes.
+ * @param rw The SDL_RWops to load the sample data from.
*
* @return <code>NULL</code> if the an error occurred, a valid pointer
* otherwise.
*/
- static Resource *load(void *buffer, unsigned bufferSize);
+ static Resource *load(SDL_RWops *rw);
/**
* Plays the sample.
@@ -65,7 +64,8 @@ class SoundEffect : public Resource
/**
* Constructor.
*/
- SoundEffect(Mix_Chunk *soundEffect): mChunk(soundEffect)
+ SoundEffect(Mix_Chunk *soundEffect) :
+ mChunk(soundEffect)
{ }
Mix_Chunk *mChunk;
diff --git a/src/sound.cpp b/src/sound.cpp
index 123a66567..913b55656 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -27,6 +27,7 @@
#include "logger.h"
#include "sound.h"
+#include "resources/music.h"
#include "resources/resourcemanager.h"
#include "resources/soundeffect.h"
@@ -158,10 +159,17 @@ void Sound::info()
compiledVersion.major,
compiledVersion.minor,
compiledVersion.patch);
- logger->log("Sound::info() SDL_mixer: %i.%i.%i (linked)",
+ if (linkedVersion)
+ {
+ logger->log("Sound::info() SDL_mixer: %i.%i.%i (linked)",
linkedVersion->major,
linkedVersion->minor,
linkedVersion->patch);
+ }
+ else
+ {
+ logger->log1("Sound::info() SDL_mixer: unknown");
+ }
logger->log("Sound::info() Driver: %s", driver);
logger->log("Sound::info() Format: %s", format);
logger->log("Sound::info() Rate: %i", rate);
@@ -184,84 +192,49 @@ void Sound::setSfxVolume(int volume)
Mix_Volume(-1, mSfxVolume);
}
-static Mix_Music *loadMusic(const std::string &filename)
+static Music *loadMusic(const std::string &fileName)
{
ResourceManager *resman = ResourceManager::getInstance();
- std::string path = resman->getPath(
- paths.getStringValue("music") + filename);
-
- if (path.find(".zip/") != std::string::npos ||
- path.find(".zip\\") != std::string::npos)
- {
- // Music file is a virtual file inside a zip archive - we have to copy
- // it to a temporary physical file so that SDL_mixer can stream it.
- logger->log("Loading music \"%s\" from temporary file tempMusic.ogg",
- path.c_str());
- bool success = resman->copyFile(paths.getStringValue("music")
- + filename, "tempMusic.ogg");
- if (success)
- path = resman->getPath("tempMusic.ogg");
- else
- return nullptr;
- }
- else
- {
- logger->log("Loading music \"%s\"", path.c_str());
- }
-
- if (path.empty())
- return nullptr;
-
- Mix_Music *music = Mix_LoadMUS(path.c_str());
-
- if (!music)
- {
- logger->log("Mix_LoadMUS() Error loading '%s': %s", path.c_str(),
- Mix_GetError());
- }
-
- return music;
+ return resman->getMusic(paths.getStringValue("music") + fileName);
}
-void Sound::playMusic(const std::string &filename)
+void Sound::playMusic(const std::string &fileName)
{
- mCurrentMusicFile = filename;
+ mCurrentMusicFile = fileName;
if (!mInstalled || !mPlayMusic)
return;
haltMusic();
- if (!filename.empty() && (mMusic = loadMusic(filename)))
- Mix_PlayMusic(mMusic, -1); // Loop forever
+ if (!fileName.empty())
+ {
+ mMusic = loadMusic(fileName);
+ if (mMusic)
+ mMusic->play();
+ }
}
void Sound::stopMusic()
{
- if (!mInstalled)
- return;
-
- logger->log1("Sound::stopMusic()");
-
- if (mMusic)
- {
- Mix_HaltMusic();
- Mix_FreeMusic(mMusic);
- mMusic = nullptr;
- }
+ haltMusic();
}
-void Sound::fadeInMusic(const std::string &path, int ms)
+void Sound::fadeInMusic(const std::string &fileName, int ms)
{
- mCurrentMusicFile = path;
+ mCurrentMusicFile = fileName;
if (!mInstalled || !mPlayMusic)
return;
haltMusic();
- if ((mMusic = loadMusic(path.c_str())))
- Mix_FadeInMusic(mMusic, -1, ms); // Loop forever
+ if (!fileName.empty())
+ {
+ mMusic = loadMusic(fileName);
+ if (mMusic)
+ mMusic->play(-1, ms);
+ }
}
void Sound::fadeOutMusic(int ms)
@@ -285,9 +258,9 @@ void Sound::fadeOutMusic(int ms)
}
}
-void Sound::fadeOutAndPlayMusic(const std::string &path, int ms)
+void Sound::fadeOutAndPlayMusic(const std::string &fileName, int ms)
{
- mNextMusicPath = path;
+ mNextMusicFile = fileName;
fadeOutMusic(ms);
}
@@ -297,15 +270,15 @@ void Sound::logic()
{
if (mMusic)
{
- Mix_FreeMusic(mMusic);
+ mMusic->decRef();
mMusic = nullptr;
}
sFadingOutEnded = false;
- if (!mNextMusicPath.empty())
+ if (!mNextMusicFile.empty())
{
- playMusic(mNextMusicPath);
- mNextMusicPath.clear();
+ playMusic(mNextMusicFile);
+ mNextMusicFile.clear();
}
}
}
@@ -383,8 +356,11 @@ void Sound::haltMusic()
return;
Mix_HaltMusic();
- Mix_FreeMusic(mMusic);
- mMusic = nullptr;
+ if (mMusic)
+ {
+ mMusic->decRef();
+ mMusic = nullptr;
+ }
}
void Sound::changeAudio()
diff --git a/src/sound.h b/src/sound.h
index 6ac361cac..7f9fb64a4 100644
--- a/src/sound.h
+++ b/src/sound.h
@@ -29,6 +29,8 @@
#include <string>
+class Music;
+
/** Sound engine
*
* \ingroup CORE
@@ -54,9 +56,9 @@ class Sound : public ConfigListener
/**
* Starts background music.
*
- * @param path The full path to the music file.
+ * @param fileName The name of the music file.
*/
- void playMusic(const std::string &path);
+ void playMusic(const std::string &fileName);
/**
* Stops currently running background music track.
@@ -66,10 +68,10 @@ class Sound : public ConfigListener
/**
* Fades in background music.
*
- * @param path The full path to the music file.
- * @param ms Duration of fade-in effect (ms)
+ * @param fileName The name of the music file.
+ * @param ms Duration of fade-in effect (ms)
*/
- void fadeInMusic(const std::string &path, int ms = 1000);
+ void fadeInMusic(const std::string &fileName, int ms = 1000);
/**
* Fades out currently running background music track.
@@ -81,15 +83,16 @@ class Sound : public ConfigListener
/**
* Fades out a background music and play a new one.
*
- * @param path The full path to the fade in music file.
- * @param ms Duration of fade-out effect (ms)
+ * @param fileName The name of the music file.
+ * @param ms Duration of fade-out effect (ms)
*/
- void fadeOutAndPlayMusic(const std::string &path, int ms = 1000);
+ void fadeOutAndPlayMusic(const std::string &fileName, int ms = 1000);
int getMaxVolume() const
{ return MIX_MAX_VOLUME; }
void setMusicVolume(int volume);
+
void setSfxVolume(int volume);
/**
@@ -112,7 +115,7 @@ class Sound : public ConfigListener
void volumeRestore();
- std::string getCurrentMusicFile()
+ std::string getCurrentMusicFile() const
{ return mCurrentMusicFile; }
/**
@@ -133,7 +136,7 @@ class Sound : public ConfigListener
* When calling fadeOutAndPlayMusic(),
* the music file below will then be played
*/
- std::string mNextMusicPath;
+ std::string mNextMusicFile;
bool mInstalled;
@@ -141,7 +144,7 @@ class Sound : public ConfigListener
int mMusicVolume;
std::string mCurrentMusicFile;
- Mix_Music *mMusic;
+ Music *mMusic;
bool mPlayBattle;
bool mPlayGui;
bool mPlayMusic;
diff --git a/src/textcommand.h b/src/textcommand.h
index b1af7667d..27b44cc7a 100644
--- a/src/textcommand.h
+++ b/src/textcommand.h
@@ -155,7 +155,7 @@ class TextCommand
bool isEmpty() const
{ return mCommand == "" && mSymbol == "" ; }
- Image *getImage()
+ Image *getImage() const
{ return mImage; }
private:
diff --git a/src/utils/checkutils.cpp b/src/utils/checkutils.cpp
new file mode 100644
index 000000000..64bb42d0c
--- /dev/null
+++ b/src/utils/checkutils.cpp
@@ -0,0 +1,39 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "utils/checkutils.h"
+
+#include <string.h>
+
+#include "logger.h"
+
+bool reportFalseReal(bool val, const char* file, unsigned line)
+{
+ if (!val)
+ logger->log("Debug: false value at %s:%u", file, line);
+ return val;
+}
+
+bool reportTrueReal(bool val, const char* file, unsigned line)
+{
+ if (val)
+ logger->log("Debug: true value at %s:%u", file, line);
+ return val;
+}
diff --git a/src/utils/checkutils.h b/src/utils/checkutils.h
new file mode 100644
index 000000000..6791ff7e0
--- /dev/null
+++ b/src/utils/checkutils.h
@@ -0,0 +1,30 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef UTILS_CHECKUTILS_H
+#define UTILS_CHECKUTILS_H
+
+#include <string>
+
+bool reportFalseReal(bool val, const char* file, unsigned line);
+
+bool reportTrueReal(bool val, const char* file, unsigned line);
+
+#endif // UTILS_CHECKUTILS_H
diff --git a/src/utils/copynpaste.cpp b/src/utils/copynpaste.cpp
index 3e9e09a5c..d918c8108 100644
--- a/src/utils/copynpaste.cpp
+++ b/src/utils/copynpaste.cpp
@@ -331,7 +331,7 @@ static char* getSelection2(Display *dpy, Window us, Atom selection,
if (left < 1)
{
if (ret == Success)
- XFree(data);
+ XFree(data);
return nullptr;
}
diff --git a/src/utils/physfsrwops.cpp b/src/utils/physfsrwops.cpp
new file mode 100644
index 000000000..1960f0dee
--- /dev/null
+++ b/src/utils/physfsrwops.cpp
@@ -0,0 +1,186 @@
+/*
+ * This code provides a glue layer between PhysicsFS and Simple Directmedia
+ * Layer's (SDL) RWops i/o abstraction.
+ *
+ * License: this code is public domain. I make no warranty that it is useful,
+ * correct, harmless, or environmentally safe.
+ *
+ * This particular file may be used however you like, including copying it
+ * verbatim into a closed-source project, exploiting it commercially, and
+ * removing any trace of my name from the source (although I hope you won't
+ * do that). I welcome enhancements and corrections to this file, but I do
+ * not require you to send me patches if you make changes. This code has
+ * NO WARRANTY.
+ *
+ * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
+ * Please see LICENSE.txt in the root of the source tree.
+ *
+ * SDL falls under the LGPL license. You can get SDL at http://www.libsdl.org/
+ *
+ * This file was written by Ryan C. Gordon. (icculus@icculus.org).
+ *
+ * Copyright (C) 2012 The ManaPlus Developers
+ */
+
+#include <stdio.h> /* used for SEEK_SET, SEEK_CUR, SEEK_END ... */
+#include "utils/physfsrwops.h"
+
+#include "localconsts.h"
+
+static int physfsrwops_seek(SDL_RWops *rw, int offset, int whence)
+{
+ PHYSFS_file *handle = (PHYSFS_file *) rw->hidden.unknown.data1;
+ int pos = 0;
+
+ if (whence == SEEK_SET)
+ {
+ pos = offset;
+ } /* if */
+ else if (whence == SEEK_CUR)
+ {
+ PHYSFS_sint64 current = PHYSFS_tell(handle);
+ if (current == -1)
+ {
+ SDL_SetError("Can't find position in file: %s",
+ PHYSFS_getLastError());
+ return -1;
+ } /* if */
+
+ pos = (int)current;
+ if (((PHYSFS_sint64)pos) != current)
+ {
+ SDL_SetError("Can't fit current file position in an int!");
+ return -1;
+ } /* if */
+
+ if (offset == 0) /* this is a "tell" call. We're done. */
+ return pos;
+
+ pos += offset;
+ } /* else if */
+ else if (whence == SEEK_END)
+ {
+ PHYSFS_sint64 len = PHYSFS_fileLength(handle);
+ if (len == -1)
+ {
+ SDL_SetError("Can't find end of file: %s", PHYSFS_getLastError());
+ return -1;
+ } /* if */
+
+ pos = (int)len;
+ if (((PHYSFS_sint64)pos) != len)
+ {
+ SDL_SetError("Can't fit end-of-file position in an int!");
+ return -1;
+ } /* if */
+
+ pos += offset;
+ } /* else if */
+ else
+ {
+ SDL_SetError("Invalid 'whence' parameter.");
+ return -1;
+ } /* else */
+
+ if ( pos < 0 )
+ {
+ SDL_SetError("Attempt to seek past start of file.");
+ return -1;
+ } /* if */
+
+ if (!PHYSFS_seek(handle, (PHYSFS_uint64) pos))
+ {
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+ return -1;
+ } /* if */
+
+ return pos;
+} /* physfsrwops_seek */
+
+static int physfsrwops_read(SDL_RWops *rw, void *ptr, int size, int maxnum)
+{
+ PHYSFS_file *handle = (PHYSFS_file*)rw->hidden.unknown.data1;
+ PHYSFS_sint64 rc = PHYSFS_read(handle, ptr, size, maxnum);
+ if (rc != maxnum)
+ {
+ if (!PHYSFS_eof(handle)) /* not EOF? Must be an error. */
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+ } /* if */
+
+ return (int)rc;
+} /* physfsrwops_read */
+
+static int physfsrwops_write(SDL_RWops *rw, const void *ptr, int size, int num)
+{
+ PHYSFS_file *handle = (PHYSFS_file*)rw->hidden.unknown.data1;
+ PHYSFS_sint64 rc = PHYSFS_write(handle, ptr, size, num);
+ if (rc != num)
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+
+ return (int) rc;
+} /* physfsrwops_write */
+
+static int physfsrwops_close(SDL_RWops *rw)
+{
+ PHYSFS_file *handle = (PHYSFS_file*)rw->hidden.unknown.data1;
+ if (!PHYSFS_close(handle))
+ {
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+ return -1;
+ } /* if */
+
+ SDL_FreeRW(rw);
+ return 0;
+} /* physfsrwops_close */
+
+static SDL_RWops *create_rwops(PHYSFS_file *handle)
+{
+ SDL_RWops *retval = nullptr;
+
+ if (!handle)
+ {
+ SDL_SetError("PhysicsFS error: %s", PHYSFS_getLastError());
+ }
+ else
+ {
+ retval = SDL_AllocRW();
+ if (retval)
+ {
+ retval->seek = physfsrwops_seek;
+ retval->read = physfsrwops_read;
+ retval->write = physfsrwops_write;
+ retval->close = physfsrwops_close;
+ retval->hidden.unknown.data1 = handle;
+ } /* if */
+ } /* else */
+
+ return retval;
+} /* create_rwops */
+
+SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *handle)
+{
+ SDL_RWops *retval = nullptr;
+ if (!handle)
+ SDL_SetError("NULL pointer passed to PHYSFSRWOPS_makeRWops().");
+ else
+ retval = create_rwops(handle);
+
+ return retval;
+} /* PHYSFSRWOPS_makeRWops */
+
+SDL_RWops *PHYSFSRWOPS_openRead(const char *fname)
+{
+ return create_rwops(PHYSFS_openRead(fname));
+} /* PHYSFSRWOPS_openRead */
+
+SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname)
+{
+ return create_rwops(PHYSFS_openWrite(fname));
+} /* PHYSFSRWOPS_openWrite */
+
+SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname)
+{
+ return create_rwops(PHYSFS_openAppend(fname));
+} /* PHYSFSRWOPS_openAppend */
+
+/* end of physfsrwops.c ... */
diff --git a/src/utils/physfsrwops.h b/src/utils/physfsrwops.h
new file mode 100644
index 000000000..efa004ac6
--- /dev/null
+++ b/src/utils/physfsrwops.h
@@ -0,0 +1,82 @@
+/*
+ * This code provides a glue layer between PhysicsFS and Simple Directmedia
+ * Layer's (SDL) RWops i/o abstraction.
+ *
+ * License: this code is public domain. I make no warranty that it is useful,
+ * correct, harmless, or environmentally safe.
+ *
+ * This particular file may be used however you like, including copying it
+ * verbatim into a closed-source project, exploiting it commercially, and
+ * removing any trace of my name from the source (although I hope you won't
+ * do that). I welcome enhancements and corrections to this file, but I do
+ * not require you to send me patches if you make changes. This code has
+ * NO WARRANTY.
+ *
+ * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
+ * Please see LICENSE.txt in the root of the source tree.
+ *
+ * SDL falls under the LGPL license. You can get SDL at http://www.libsdl.org/
+ *
+ * This file was written by Ryan C. Gordon. (icculus@icculus.org).
+ *
+ * Copyright (C) 2012 The ManaPlus Developers
+ */
+
+#ifndef UTILS_PHYSFSRWOPS_H
+#define UTILS_PHYSFSRWOPS_H
+
+#include <physfs.h>
+#include <SDL.h>
+
+/**
+ * Open a platform-independent filename for reading, and make it accessible
+ * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
+ * RWops is closed. PhysicsFS should be configured to your liking before
+ * opening files through this method.
+ *
+ * @param filename File to open in platform-independent notation.
+ * @return A valid SDL_RWops structure on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ */
+SDL_RWops *PHYSFSRWOPS_openRead(const char *fname);
+
+/**
+ * Open a platform-independent filename for writing, and make it accessible
+ * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
+ * RWops is closed. PhysicsFS should be configured to your liking before
+ * opening files through this method.
+ *
+ * @param filename File to open in platform-independent notation.
+ * @return A valid SDL_RWops structure on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ */
+SDL_RWops *PHYSFSRWOPS_openWrite(const char *fname);
+
+/**
+ * Open a platform-independent filename for appending, and make it accessible
+ * via an SDL_RWops structure. The file will be closed in PhysicsFS when the
+ * RWops is closed. PhysicsFS should be configured to your liking before
+ * opening files through this method.
+ *
+ * @param filename File to open in platform-independent notation.
+ * @return A valid SDL_RWops structure on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ */
+SDL_RWops *PHYSFSRWOPS_openAppend(const char *fname);
+
+/**
+ * Make a SDL_RWops from an existing PhysicsFS file handle. You should
+ * dispose of any references to the handle after successful creation of
+ * the RWops. The actual PhysicsFS handle will be destroyed when the
+ * RWops is closed.
+ *
+ * @param handle a valid PhysicsFS file handle.
+ * @return A valid SDL_RWops structure on success, NULL on error. Specifics
+ * of the error can be gleaned from PHYSFS_getLastError().
+ */
+SDL_RWops *PHYSFSRWOPS_makeRWops(PHYSFS_file *handle);
+
+#endif /* include-once blocker */
+
+/* end of physfsrwops.h ... */
+
diff --git a/src/utils/stringutils.cpp b/src/utils/stringutils.cpp
index b855e3b04..08bcac9e6 100644
--- a/src/utils/stringutils.cpp
+++ b/src/utils/stringutils.cpp
@@ -509,6 +509,39 @@ std::vector<std::string> getLang()
return langs;
}
+std::string getLangSimple()
+{
+ std::string lang = config.getValue("lang", "").c_str();
+ if (lang.empty())
+ {
+ char *lng = getenv("LANG");
+ if (!lng)
+ return "";
+ return lng;
+ }
+ return lang;
+}
+
+std::string getLangShort()
+{
+ std::string lang = config.getValue("lang", "").c_str();
+ if (lang.empty())
+ {
+ char *lng = getenv("LANG");
+ if (!lng)
+ return "";
+ lang = lng;
+ }
+
+ int dot = lang.find(".");
+ if (dot != (signed)std::string::npos)
+ lang = lang.substr(0, dot);
+ dot = lang.find("_");
+ if (dot != (signed)std::string::npos)
+ return lang.substr(0, dot);
+ return lang;
+}
+
std::string packList(std::list<std::string> &list)
{
std::list<std::string>::const_iterator i = list.begin();
@@ -541,6 +574,9 @@ std::string stringToHexPath(const std::string &str)
void deleteCharLeft(std::string &str, unsigned *pos)
{
+ if (!pos)
+ return;
+
while (*pos > 0)
{
(*pos)--;
diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h
index c6eb08a6c..0b22ef847 100644
--- a/src/utils/stringutils.h
+++ b/src/utils/stringutils.h
@@ -188,6 +188,10 @@ std::string combineDye2(std::string file, std::string dye);
std::vector<std::string> getLang();
+std::string getLangSimple();
+
+std::string getLangShort();
+
std::string packList(std::list<std::string> &list);
std::list<std::string> unpackList(const std::string &str);