summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2012-06-30 14:37:49 +0300
committerAndrei Karas <akaras@inbox.ru>2012-07-01 17:51:01 +0300
commitc01aec243610016c2cd5e4211fee484627bc69ea (patch)
tree46a0b704701a9c1229fafa5e7ed7117002fc1579 /src
parent8321043b76660235a5ebbfbb8f43504f43c1af8b (diff)
downloadmv-c01aec243610016c2cd5e4211fee484627bc69ea.tar.gz
mv-c01aec243610016c2cd5e4211fee484627bc69ea.tar.bz2
mv-c01aec243610016c2cd5e4211fee484627bc69ea.tar.xz
mv-c01aec243610016c2cd5e4211fee484627bc69ea.zip
Add npc avatars for evol server.
Change protocol version to 6.
Diffstat (limited to 'src')
-rw-r--r--src/gui/npcdialog.cpp198
-rw-r--r--src/gui/npcdialog.h21
-rw-r--r--src/gui/widgets/playerbox.cpp2
-rw-r--r--src/gui/widgets/playerbox.h9
-rw-r--r--src/net/messagein.cpp76
-rw-r--r--src/net/messagein.h2
-rw-r--r--src/net/tmwa/network.h4
-rw-r--r--src/net/tmwa/npchandler.cpp19
8 files changed, 256 insertions, 75 deletions
diff --git a/src/gui/npcdialog.cpp b/src/gui/npcdialog.cpp
index ffd8e8e2d..ec76ea3f5 100644
--- a/src/gui/npcdialog.cpp
+++ b/src/gui/npcdialog.cpp
@@ -22,6 +22,7 @@
#include "gui/npcdialog.h"
+#include "being.h"
#include "configuration.h"
#include "client.h"
@@ -37,6 +38,7 @@
#include "gui/widgets/itemlinkhandler.h"
#include "gui/widgets/layout.h"
#include "gui/widgets/listbox.h"
+#include "gui/widgets/playerbox.h"
#include "gui/widgets/scrollarea.h"
#include "gui/widgets/textbox.h"
#include "gui/widgets/textfield.h"
@@ -68,7 +70,10 @@ NpcDialog::NpcDialog(int npcId) :
mLastNextTime(0),
mCameraMode(-1),
mCameraX(0),
- mCameraY(0)
+ mCameraY(0),
+ mPlayerBox(new PlayerBox),
+ mAvatarBeing(nullptr),
+ mShowAvatar(false)
{
// Basic Window Setup
setWindowName("NpcText");
@@ -82,6 +87,9 @@ NpcDialog::NpcDialog(int npcId) :
setDefaultSize(400, 400, ImageRect::CENTER);
+ mPlayerBox->setWidth(70);
+ mPlayerBox->setHeight(100);
+
mItemLinkHandler = new ItemLinkHandler;
// Setup output text box
mTextBox = new BrowserBox(BrowserBox::AUTO_WRAP);
@@ -155,6 +163,12 @@ NpcDialog::~NpcDialog()
clearLayout();
+ if (mPlayerBox)
+ {
+ delete mPlayerBox->getBeing();
+ delete mPlayerBox;
+ }
+
delete mTextBox;
mTextBox = nullptr;
delete mClearButton;
@@ -469,6 +483,88 @@ void NpcDialog::closeAll()
}
}
+void NpcDialog::placeNormalControls()
+{
+ if (mShowAvatar)
+ {
+ place(0, 0, mPlayerBox);
+ place(1, 0, mScrollArea, 5, 3);
+ place(4, 3, mClearButton);
+ place(5, 3, mButton);
+ }
+ else
+ {
+ place(0, 0, mScrollArea, 5, 3);
+ place(3, 3, mClearButton);
+ place(4, 3, mButton);
+ }
+}
+
+void NpcDialog::placeMenuControls()
+{
+ if (mShowAvatar)
+ {
+ place(0, 0, mPlayerBox);
+ place(1, 0, mScrollArea, 6, 3);
+ place(0, 3, mListScrollArea, 7, 3);
+ place(3, 6, mClearButton, 2);
+ place(5, 6, mButton, 2);
+ }
+ else
+ {
+ place(0, 0, mScrollArea, 6, 3);
+ place(0, 3, mListScrollArea, 6, 3);
+ place(2, 6, mClearButton, 2);
+ place(4, 6, mButton, 2);
+ }
+}
+
+void NpcDialog::placeTextInputControls()
+{
+ if (mShowAvatar)
+ {
+ place(0, 0, mPlayerBox);
+ place(1, 0, mScrollArea, 6, 3);
+ place(0, 3, mTextField, 6);
+ place(0, 4, mResetButton, 2);
+ place(4, 4, mClearButton, 2);
+ place(5, 4, mButton, 2);
+ }
+ else
+ {
+ place(0, 0, mScrollArea, 6, 3);
+ place(0, 3, mTextField, 6);
+ place(0, 4, mResetButton, 2);
+ place(2, 4, mClearButton, 2);
+ place(4, 4, mButton, 2);
+ }
+}
+
+void NpcDialog::placeIntInputControls()
+{
+ if (mShowAvatar)
+ {
+ place(0, 0, mPlayerBox);
+ place(1, 0, mScrollArea, 6, 3);
+ place(1, 3, mMinusButton, 1);
+ place(2, 3, mIntField, 4);
+ place(6, 3, mPlusButton, 1);
+ place(0, 4, mResetButton, 2);
+ place(3, 4, mClearButton, 2);
+ place(5, 4, mButton, 2);
+ }
+ else
+ {
+ place(0, 0, mScrollArea, 6, 3);
+ place(0, 3, mMinusButton, 1);
+ place(1, 3, mIntField, 4);
+ place(5, 3, mPlusButton, 1);
+ place(0, 4, mResetButton, 2);
+ place(2, 4, mClearButton, 2);
+ place(4, 4, mButton, 2);
+ }
+}
+
void NpcDialog::buildLayout()
{
clearLayout();
@@ -481,47 +577,28 @@ void NpcDialog::buildLayout()
mButton->setCaption(CAPTION_NEXT);
else if (mActionState == NPC_ACTION_CLOSE)
mButton->setCaption(CAPTION_CLOSE);
- place(0, 0, mScrollArea, 5, 3);
- place(3, 3, mClearButton);
- place(4, 3, mButton);
+ placeNormalControls();
}
else if (mInputState != NPC_INPUT_NONE)
{
-// if (!mLogInteraction)
-// setText(mNewText);
-
mButton->setCaption(CAPTION_SUBMIT);
if (mInputState == NPC_INPUT_LIST)
{
- place(0, 0, mScrollArea, 6, 3);
- place(0, 3, mListScrollArea, 6, 3);
- place(2, 6, mClearButton, 2);
- place(4, 6, mButton, 2);
-
+ placeMenuControls();
mItemList->setSelected(-1);
}
else if (mInputState == NPC_INPUT_STRING)
{
- place(0, 0, mScrollArea, 6, 3);
- place(0, 3, mTextField, 6);
- place(0, 4, mResetButton, 2);
- place(2, 4, mClearButton, 2);
- place(4, 4, mButton, 2);
+ placeTextInputControls();
}
else if (mInputState == NPC_INPUT_INTEGER)
{
- place(0, 0, mScrollArea, 6, 3);
- place(0, 3, mMinusButton, 1);
- place(1, 3, mIntField, 4);
- place(5, 3, mPlusButton, 1);
- place(0, 4, mResetButton, 2);
- place(2, 4, mClearButton, 2);
- place(4, 4, mButton, 2);
+ placeIntInputControls();
}
}
Layout &layout = getLayout();
- layout.setRowHeight(0, Layout::AUTO_SET);
+ layout.setRowHeight(1, Layout::AUTO_SET);
redraw();
@@ -557,3 +634,74 @@ void NpcDialog::restoreCamera()
}
mCameraMode = -1;
}
+
+void NpcDialog::showAvatar(int avatarId)
+{
+ bool needShow = (avatarId != 0);
+ if (needShow)
+ {
+ delete mAvatarBeing;
+ mAvatarBeing = new Being(0, ActorSprite::NPC, avatarId, nullptr);
+ mPlayerBox->setPlayer(mAvatarBeing);
+ if (mAvatarBeing && !mAvatarBeing->empty())
+ {
+ mAvatarBeing->logic();
+ Sprite *sprite = mAvatarBeing->getSprite(0);
+ if (sprite)
+ {
+ int width = sprite->getWidth() + 2 * getPadding();
+ mPlayerBox->setWidth(width);
+ int height = sprite->getHeight() + 2 * getPadding();
+ mPlayerBox->setHeight(height);
+ }
+ }
+ }
+ else
+ {
+ delete mAvatarBeing;
+ mAvatarBeing = nullptr;
+ mPlayerBox->setPlayer(nullptr);
+ }
+ if (needShow != mShowAvatar)
+ {
+ mShowAvatar = needShow;
+ buildLayout();
+ }
+ else
+ {
+ mShowAvatar = needShow;
+ }
+}
+
+void NpcDialog::setAvatarDirection(uint8_t direction)
+{
+ Being *being = mPlayerBox->getBeing();
+ if (being)
+ being->setDirection(direction);
+}
+
+void NpcDialog::setAvatarAction(int actionId)
+{
+ Being *being = mPlayerBox->getBeing();
+ if (being)
+ being->setAction((Being::Action)actionId);
+}
+
+void NpcDialog::logic()
+{
+ Window::logic();
+ if (mShowAvatar && mAvatarBeing)
+ {
+ mAvatarBeing->logic();
+ if (mPlayerBox->getWidth() < (signed)(3 * getPadding()))
+ {
+ Sprite *sprite = mAvatarBeing->getSprite(0);
+ if (sprite)
+ {
+ mPlayerBox->setWidth(sprite->getWidth() + 2 * getPadding());
+ mPlayerBox->setHeight(sprite->getHeight() + 2 * getPadding());
+ buildLayout();
+ }
+ }
+ }
+}
diff --git a/src/gui/npcdialog.h b/src/gui/npcdialog.h
index f56af664e..68ee17e33 100644
--- a/src/gui/npcdialog.h
+++ b/src/gui/npcdialog.h
@@ -34,10 +34,12 @@
#include <list>
+class Being;
class BrowserBox;
class ItemLinkHandler;
class IntTextField;
class ListBox;
+class PlayerBox;
class TextBox;
class TextField;
class Button;
@@ -184,12 +186,28 @@ class NpcDialog : public Window, public gcn::ActionListener,
void refocus();
+ void showAvatar(int avatarId);
+
+ void setAvatarDirection(uint8_t direction);
+
+ void setAvatarAction(int actionId);
+
+ void logic();
+
private:
typedef std::list<NpcDialog*> DialogList;
static DialogList instances;
void buildLayout();
+ void placeNormalControls();
+
+ void placeMenuControls();
+
+ void placeTextInputControls();
+
+ void placeIntInputControls();
+
int mNpcId;
bool mLogInteraction;
@@ -245,6 +263,9 @@ class NpcDialog : public Window, public gcn::ActionListener,
int mCameraMode;
int mCameraX;
int mCameraY;
+ PlayerBox *mPlayerBox;
+ Being *mAvatarBeing;
+ bool mShowAvatar;
};
#endif // NPCDIALOG_H
diff --git a/src/gui/widgets/playerbox.cpp b/src/gui/widgets/playerbox.cpp
index 5e2412d3b..90a9c9409 100644
--- a/src/gui/widgets/playerbox.cpp
+++ b/src/gui/widgets/playerbox.cpp
@@ -40,7 +40,7 @@ int PlayerBox::instances = 0;
float PlayerBox::mAlpha = 1.0;
ImageRect PlayerBox::background;
-PlayerBox::PlayerBox(const Being *being):
+PlayerBox::PlayerBox(Being *being):
mBeing(being)
{
setFrameSize(2);
diff --git a/src/gui/widgets/playerbox.h b/src/gui/widgets/playerbox.h
index d2393ca08..9e5a761b4 100644
--- a/src/gui/widgets/playerbox.h
+++ b/src/gui/widgets/playerbox.h
@@ -42,7 +42,7 @@ class PlayerBox : public gcn::ScrollArea
* Constructor. Takes the initial player character that this box should
* display, which defaults to <code>NULL</code>.
*/
- PlayerBox(const Being *being = nullptr);
+ PlayerBox(Being *being = nullptr);
/**
* Destructor.
@@ -54,7 +54,7 @@ class PlayerBox : public gcn::ScrollArea
* player to <code>NULL</code> causes the box not to draw any
* character.
*/
- void setPlayer(const Being *being)
+ void setPlayer(Being *being)
{ mBeing = being; }
/**
@@ -67,8 +67,11 @@ class PlayerBox : public gcn::ScrollArea
*/
void drawFrame(gcn::Graphics *graphics);
+ Being *getBeing()
+ { return mBeing; }
+
private:
- const Being *mBeing; /**< The character used for display */
+ Being *mBeing; /**< The character used for display */
static float mAlpha;
static int instances;
diff --git a/src/net/messagein.cpp b/src/net/messagein.cpp
index 445b43d3f..0af0e389f 100644
--- a/src/net/messagein.cpp
+++ b/src/net/messagein.cpp
@@ -75,6 +75,39 @@ void MessageIn::readCoordinates(uint16_t &x, uint16_t &y)
+ toString(static_cast<int>(y)));
}
+uint8_t MessageIn::fromServerDirection(uint8_t serverDir)
+{
+ // Translate from eAthena format
+ switch (serverDir)
+ {
+ case 0:
+ return 1;
+ case 1:
+ return 3;
+ case 2:
+ return 2;
+ case 3:
+ return 6;
+ case 4:
+ return 4;
+ case 5:
+ return 12;
+ case 6:
+ return 8;
+ case 7:
+ return 9;
+ case 8:
+#ifdef MANASERV_SUPPORT
+ if (Net::getNetworkType() != ServerInfo::MANASERV)
+#endif
+ return 8;
+ default:
+ logger->log("incorrect direction: %d",
+ static_cast<int>(serverDir));
+ return 0;
+ }
+}
+
void MessageIn::readCoordinates(uint16_t &x, uint16_t &y, uint8_t &direction)
{
uint8_t serverDir = 0;
@@ -89,48 +122,7 @@ void MessageIn::readCoordinates(uint16_t &x, uint16_t &y, uint8_t &direction)
y = static_cast<unsigned short>(temp >> 4);
serverDir = data[2] & 0x000f;
-
- // Translate from eAthena format
- switch (serverDir)
- {
- case 0:
- direction = 1;
- break;
- case 1:
- direction = 3;
- break;
- case 2:
- direction = 2;
- break;
- case 3:
- direction = 6;
- break;
- case 4:
- direction = 4;
- break;
- case 5:
- direction = 12;
- break;
- case 6:
- direction = 8;
- break;
- case 7:
- direction = 9;
- break;
- case 8:
-#ifdef MANASERV_SUPPORT
- if (Net::getNetworkType() != ServerInfo::MANASERV)
-#endif
- {
- direction = 8;
- break;
- }
- default:
- logger->log("incorrect direction: %d",
- static_cast<int>(direction));
- // OOPSIE! Impossible or unknown
- direction = 0;
- }
+ direction = fromServerDirection(serverDir);
}
mPos += 3;
PacketCounters::incInBytes(3);
diff --git a/src/net/messagein.h b/src/net/messagein.h
index 00a92f49f..37caa7731 100644
--- a/src/net/messagein.h
+++ b/src/net/messagein.h
@@ -101,6 +101,8 @@ class MessageIn
virtual ~MessageIn()
{ }
+ static uint8_t fromServerDirection(uint8_t serverDir);
+
protected:
/**
* Constructor.
diff --git a/src/net/tmwa/network.h b/src/net/tmwa/network.h
index 2dc91e509..03f24839b 100644
--- a/src/net/tmwa/network.h
+++ b/src/net/tmwa/network.h
@@ -39,8 +39,8 @@
* Protocol version, reported to the eAthena char and mapserver who can adjust
* the protocol accordingly.
*/
-#define CLIENT_PROTOCOL_VERSION 5
-#define CLIENT_TMW_PROTOCOL_VERSION 1
+#define CLIENT_PROTOCOL_VERSION 6
+#define CLIENT_TMW_PROTOCOL_VERSION 1
namespace TmwAthena
{
diff --git a/src/net/tmwa/npchandler.cpp b/src/net/tmwa/npchandler.cpp
index ec3ef48b8..be58f0bc5 100644
--- a/src/net/tmwa/npchandler.cpp
+++ b/src/net/tmwa/npchandler.cpp
@@ -290,10 +290,25 @@ void NpcHandler::processNpcCommand(Net::MessageIn &msg, int npcId)
viewport->moveCameraRelative(x, y);
}
break;
- case 5:
+ case 5: // close dialog
closeDialog(npcId);
break;
-
+ case 6: // show avatar
+ if (mDialog)
+ mDialog->showAvatar(msg.readInt32()); // avatar id
+ break;
+ case 7: // set avatar direction
+ if (mDialog)
+ {
+ mDialog->setAvatarDirection(
+ Net::MessageIn::fromServerDirection(
+ msg.readInt32())); // direction
+ }
+ break;
+ case 8: // set avatar action
+ if (mDialog)
+ mDialog->setAvatarAction(msg.readInt32()); // direction
+ break;
default:
logger->log("unknown npc command: %d", cmd);
break;