From e6e9b2c524f28e18f7efa582ee0dd0ee1e1420df Mon Sep 17 00:00:00 2001
From: Andrei Karas <akaras@inbox.ru>
Date: Thu, 27 Aug 2015 21:26:15 +0300
Subject: Move receive code from npchandler into separate file.

---
 src/CMakeLists.txt             |   4 +
 src/Makefile.am                |   4 +
 src/net/ea/npchandler.cpp      | 182 +---------------------------------
 src/net/ea/npchandler.h        |  20 ----
 src/net/ea/npcrecv.cpp         | 217 +++++++++++++++++++++++++++++++++++++++++
 src/net/ea/npcrecv.h           |  55 +++++++++++
 src/net/eathena/npchandler.cpp | 122 ++++++-----------------
 src/net/eathena/npchandler.h   |  15 ---
 src/net/eathena/npcrecv.cpp    | 109 +++++++++++++++++++++
 src/net/eathena/npcrecv.h      |  42 ++++++++
 src/net/tmwa/npchandler.cpp    |  42 ++++----
 11 files changed, 487 insertions(+), 325 deletions(-)
 create mode 100644 src/net/ea/npcrecv.cpp
 create mode 100644 src/net/ea/npcrecv.h
 create mode 100644 src/net/eathena/npcrecv.cpp
 create mode 100644 src/net/eathena/npcrecv.h

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b1a74e79a..3faaed6d1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1385,6 +1385,8 @@ SET(SRCS_EVOL
     net/ea/network.h
     net/ea/npchandler.cpp
     net/ea/npchandler.h
+    net/ea/npcrecv.cpp
+    net/ea/npcrecv.h
     net/ea/partyhandler.cpp
     net/ea/partyhandler.h
     net/ea/playerhandler.cpp
@@ -1664,6 +1666,8 @@ SET(SRCS_EATHENA
     net/eathena/network.h
     net/eathena/npchandler.cpp
     net/eathena/npchandler.h
+    net/eathena/npcrecv.cpp
+    net/eathena/npcrecv.h
     net/eathena/packets.h
     net/eathena/partyhandler.cpp
     net/eathena/partyhandler.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 440e257aa..3ac6c0503 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1227,6 +1227,8 @@ manaplus_SOURCES += main.cpp \
 	      net/ea/network.h \
 	      net/ea/npchandler.cpp \
 	      net/ea/npchandler.h \
+	      net/ea/npcrecv.cpp \
+	      net/ea/npcrecv.h \
 	      net/ea/partyhandler.cpp \
 	      net/ea/partyhandler.h \
 	      net/ea/playerhandler.cpp \
@@ -1510,6 +1512,8 @@ manaplus_SOURCES += gui/windows/bankwindow.cpp \
 	      net/eathena/network.h \
 	      net/eathena/npchandler.cpp \
 	      net/eathena/npchandler.h \
+	      net/eathena/npcrecv.cpp \
+	      net/eathena/npcrecv.h \
 	      net/eathena/packets.h \
 	      net/eathena/partyhandler.cpp \
 	      net/eathena/partyhandler.h \
diff --git a/src/net/ea/npchandler.cpp b/src/net/ea/npchandler.cpp
index 2224de3e0..78ed6de53 100644
--- a/src/net/ea/npchandler.cpp
+++ b/src/net/ea/npchandler.cpp
@@ -28,6 +28,8 @@
 
 #include "net/messagein.h"
 
+#include "net/ea/npcrecv.h"
+
 #include "utils/langs.h"
 
 #include "debug.h"
@@ -35,186 +37,10 @@
 namespace Ea
 {
 
-NpcDialog *NpcHandler::mDialog = nullptr;
-bool NpcHandler::mRequestLang = false;
-
 NpcHandler::NpcHandler()
 {
-    mDialog = nullptr;
-    mRequestLang = false;
-}
-
-void NpcHandler::processNpcChoice(Net::MessageIn &msg)
-{
-    npcHandler->getNpc(msg);
-    mRequestLang = false;
-
-    if (mDialog)
-    {
-        mDialog->choiceRequest();
-        mDialog->parseListItems(msg.readString(msg.getLength() - 8,
-            "select items"));
-    }
-    else
-    {
-        msg.readString(msg.getLength() - 8, "select items");
-    }
-}
-
-void NpcHandler::processNpcMessage(Net::MessageIn &msg)
-{
-    npcHandler->getNpc(msg);
-    mRequestLang = false;
-
-    const std::string message = msg.readString(msg.getLength() - 8, "message");
-    // ignore future legacy npc commands.
-    if (message.size() > 3 && message.substr(0, 3) == "###")
-        return;
-    if (mDialog)
-        mDialog->addText(message);
-}
-
-void NpcHandler::processNpcClose(Net::MessageIn &msg)
-{
-    // Show the close button
-    npcHandler->getNpc(msg);
-    mRequestLang = false;
-    if (mDialog)
-        mDialog->showCloseButton();
-}
-
-void NpcHandler::processNpcNext(Net::MessageIn &msg)
-{
-    // Show the next button
-    npcHandler->getNpc(msg);
-    mRequestLang = false;
-    if (mDialog)
-        mDialog->showNextButton();
-}
-
-void NpcHandler::processNpcIntInput(Net::MessageIn &msg)
-{
-    // Request for an integer
-    npcHandler->getNpc(msg);
-    mRequestLang = false;
-    if (mDialog)
-        mDialog->integerRequest(0);
-}
-
-void NpcHandler::processNpcStrInput(Net::MessageIn &msg)
-{
-    // Request for a string
-    BeingId npcId = npcHandler->getNpc(msg);
-    if (mRequestLang)
-    {
-        mRequestLang = false;
-        npcHandler->stringInput(npcId, getLangSimple());
-    }
-    else if (mDialog)
-    {
-        mDialog->textRequest("");
-    }
-}
-
-void NpcHandler::processNpcCommand(Net::MessageIn &msg)
-{
-    const BeingId npcId = npcHandler->getNpc(msg);
-    mRequestLang = false;
-
-    const int cmd = msg.readInt16("cmd");
-    const BeingId id = msg.readBeingId("id");
-    const int x = msg.readInt16("x");
-    const int y = msg.readInt16("y");
-    switch (cmd)
-    {
-        case 0:
-            mRequestLang = true;
-            break;
-
-        case 1:
-            if (viewport)
-                viewport->moveCameraToActor(npcId);
-            break;
-
-        case 2:
-            if (viewport)
-            {
-                if (id == BeingId_zero)
-                    viewport->moveCameraToPosition(x, y);
-                else
-                    viewport->moveCameraToActor(id, x, y);
-            }
-            break;
-
-        case 3:
-            if (viewport)
-                viewport->returnCamera();
-            break;
-
-        case 4:
-            if (viewport)
-            {
-                viewport->moveCameraRelative(x, y);
-            }
-            break;
-        case 5:  // close dialog
-            if (mDialog)
-                mDialog->restoreCamera();
-            npcHandler->closeDialog(npcId);
-            break;
-        case 6:  // show avatar
-            if (mDialog)
-            {
-                mDialog->showAvatar(fromInt(id, BeingTypeId));
-            }
-            break;
-        case 7:  // set avatar direction
-            if (mDialog)
-            {
-                mDialog->setAvatarDirection(
-                    Net::MessageIn::fromServerDirection(
-                    static_cast<uint8_t>(id)));
-            }
-            break;
-        case 8:  // set avatar action
-            if (mDialog)
-                mDialog->setAvatarAction(toInt(id, int));
-            break;
-        case 9:  // clear npc dialog
-            if (mDialog)
-                mDialog->clearRows();
-            break;
-        case 10:  // send selected item id
-        {
-            int invSize = toInt(id, int);
-            if (!invSize)
-                invSize = 1;
-            if (mDialog)
-                mDialog->itemRequest(invSize);
-            break;
-        }
-        case 11:  // send selected item index
-        {
-            int invSize = toInt(id, int);
-            if (!invSize)
-                invSize = 1;
-            if (mDialog)
-                mDialog->itemIndexRequest(invSize);
-            break;
-        }
-        default:
-            UNIMPLIMENTEDPACKET;
-            break;
-    }
-}
-
-void NpcHandler::processChangeTitle(Net::MessageIn &msg)
-{
-    npcHandler->getNpc(msg);
-    mRequestLang = false;
-    const std::string str = msg.readString(-1, "title");
-    if (mDialog)
-        mDialog->setCaption(str);
+    NpcRecv::mDialog = nullptr;
+    NpcRecv::mRequestLang = false;
 }
 
 }  // namespace Ea
diff --git a/src/net/ea/npchandler.h b/src/net/ea/npchandler.h
index 28a423c39..98321d29f 100644
--- a/src/net/ea/npchandler.h
+++ b/src/net/ea/npchandler.h
@@ -44,26 +44,6 @@ class NpcHandler notfinal : public Net::NpcHandler
 
     protected:
         NpcHandler();
-
-        static void processNpcChoice(Net::MessageIn &msg);
-
-        static void processNpcMessage(Net::MessageIn &msg);
-
-        static void processNpcClose(Net::MessageIn &msg);
-
-        static void processNpcNext(Net::MessageIn &msg);
-
-        static void processNpcIntInput(Net::MessageIn &msg);
-
-        static void processNpcStrInput(Net::MessageIn &msg);
-
-        static void processNpcCommand(Net::MessageIn &msg);
-
-        static void processChangeTitle(Net::MessageIn &msg);
-
-        static NpcDialog *mDialog;
-
-        static bool mRequestLang;
 };
 
 }  // namespace Ea
diff --git a/src/net/ea/npcrecv.cpp b/src/net/ea/npcrecv.cpp
new file mode 100644
index 000000000..08d0ed498
--- /dev/null
+++ b/src/net/ea/npcrecv.cpp
@@ -0,0 +1,217 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2004-2009  The Mana World Development Team
+ *  Copyright (C) 2009-2010  The Mana Developers
+ *  Copyright (C) 2011-2015  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 "net/ea/npcrecv.h"
+
+#include "gui/viewport.h"
+
+#include "gui/windows/npcdialog.h"
+
+#include "net/messagein.h"
+
+#include "utils/langs.h"
+
+#include "debug.h"
+
+namespace Ea
+{
+
+namespace NpcRecv
+{
+    NpcDialog *mDialog = nullptr;
+    bool mRequestLang = false;
+}  // namespace NpcRecv
+
+void NpcRecv::processNpcChoice(Net::MessageIn &msg)
+{
+    npcHandler->getNpc(msg);
+    mRequestLang = false;
+
+    if (mDialog)
+    {
+        mDialog->choiceRequest();
+        mDialog->parseListItems(msg.readString(msg.getLength() - 8,
+            "select items"));
+    }
+    else
+    {
+        msg.readString(msg.getLength() - 8, "select items");
+    }
+}
+
+void NpcRecv::processNpcMessage(Net::MessageIn &msg)
+{
+    npcHandler->getNpc(msg);
+    mRequestLang = false;
+
+    const std::string message = msg.readString(msg.getLength() - 8, "message");
+    // ignore future legacy npc commands.
+    if (message.size() > 3 && message.substr(0, 3) == "###")
+        return;
+    if (mDialog)
+        mDialog->addText(message);
+}
+
+void NpcRecv::processNpcClose(Net::MessageIn &msg)
+{
+    // Show the close button
+    npcHandler->getNpc(msg);
+    mRequestLang = false;
+    if (mDialog)
+        mDialog->showCloseButton();
+}
+
+void NpcRecv::processNpcNext(Net::MessageIn &msg)
+{
+    // Show the next button
+    npcHandler->getNpc(msg);
+    mRequestLang = false;
+    if (mDialog)
+        mDialog->showNextButton();
+}
+
+void NpcRecv::processNpcIntInput(Net::MessageIn &msg)
+{
+    // Request for an integer
+    npcHandler->getNpc(msg);
+    mRequestLang = false;
+    if (mDialog)
+        mDialog->integerRequest(0);
+}
+
+void NpcRecv::processNpcStrInput(Net::MessageIn &msg)
+{
+    // Request for a string
+    BeingId npcId = npcHandler->getNpc(msg);
+    if (mRequestLang)
+    {
+        mRequestLang = false;
+        npcHandler->stringInput(npcId, getLangSimple());
+    }
+    else if (mDialog)
+    {
+        mDialog->textRequest("");
+    }
+}
+
+void NpcRecv::processNpcCommand(Net::MessageIn &msg)
+{
+    const BeingId npcId = npcHandler->getNpc(msg);
+    mRequestLang = false;
+
+    const int cmd = msg.readInt16("cmd");
+    const BeingId id = msg.readBeingId("id");
+    const int x = msg.readInt16("x");
+    const int y = msg.readInt16("y");
+    switch (cmd)
+    {
+        case 0:
+            mRequestLang = true;
+            break;
+
+        case 1:
+            if (viewport)
+                viewport->moveCameraToActor(npcId);
+            break;
+
+        case 2:
+            if (viewport)
+            {
+                if (id == BeingId_zero)
+                    viewport->moveCameraToPosition(x, y);
+                else
+                    viewport->moveCameraToActor(id, x, y);
+            }
+            break;
+
+        case 3:
+            if (viewport)
+                viewport->returnCamera();
+            break;
+
+        case 4:
+            if (viewport)
+            {
+                viewport->moveCameraRelative(x, y);
+            }
+            break;
+        case 5:  // close dialog
+            if (mDialog)
+                mDialog->restoreCamera();
+            npcHandler->closeDialog(npcId);
+            break;
+        case 6:  // show avatar
+            if (mDialog)
+            {
+                mDialog->showAvatar(fromInt(id, BeingTypeId));
+            }
+            break;
+        case 7:  // set avatar direction
+            if (mDialog)
+            {
+                mDialog->setAvatarDirection(
+                    Net::MessageIn::fromServerDirection(
+                    static_cast<uint8_t>(id)));
+            }
+            break;
+        case 8:  // set avatar action
+            if (mDialog)
+                mDialog->setAvatarAction(toInt(id, int));
+            break;
+        case 9:  // clear npc dialog
+            if (mDialog)
+                mDialog->clearRows();
+            break;
+        case 10:  // send selected item id
+        {
+            int invSize = toInt(id, int);
+            if (!invSize)
+                invSize = 1;
+            if (mDialog)
+                mDialog->itemRequest(invSize);
+            break;
+        }
+        case 11:  // send selected item index
+        {
+            int invSize = toInt(id, int);
+            if (!invSize)
+                invSize = 1;
+            if (mDialog)
+                mDialog->itemIndexRequest(invSize);
+            break;
+        }
+        default:
+            UNIMPLIMENTEDPACKET;
+            break;
+    }
+}
+
+void NpcRecv::processChangeTitle(Net::MessageIn &msg)
+{
+    npcHandler->getNpc(msg);
+    mRequestLang = false;
+    const std::string str = msg.readString(-1, "title");
+    if (mDialog)
+        mDialog->setCaption(str);
+}
+
+}  // namespace Ea
diff --git a/src/net/ea/npcrecv.h b/src/net/ea/npcrecv.h
new file mode 100644
index 000000000..eb1808465
--- /dev/null
+++ b/src/net/ea/npcrecv.h
@@ -0,0 +1,55 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2004-2009  The Mana World Development Team
+ *  Copyright (C) 2009-2010  The Mana Developers
+ *  Copyright (C) 2011-2015  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 NET_EA_NPCRECV_H
+#define NET_EA_NPCRECV_H
+
+#include "net/npchandler.h"
+
+#include "localconsts.h"
+
+class NpcDialog;
+
+namespace Net
+{
+    class MessageIn;
+}
+
+namespace Ea
+{
+    namespace NpcRecv
+    {
+        extern NpcDialog *mDialog;
+        extern bool mRequestLang;
+
+        void processNpcChoice(Net::MessageIn &msg);
+        void processNpcMessage(Net::MessageIn &msg);
+        void processNpcClose(Net::MessageIn &msg);
+        void processNpcNext(Net::MessageIn &msg);
+        void processNpcIntInput(Net::MessageIn &msg);
+        void processNpcStrInput(Net::MessageIn &msg);
+        void processNpcCommand(Net::MessageIn &msg);
+        void processChangeTitle(Net::MessageIn &msg);
+    }  // namespace NpcRecv
+}  // namespace Ea
+
+#endif  // NET_EA_NPCRECV_H
diff --git a/src/net/eathena/npchandler.cpp b/src/net/eathena/npchandler.cpp
index 7b376fbeb..1ed4cb077 100644
--- a/src/net/eathena/npchandler.cpp
+++ b/src/net/eathena/npchandler.cpp
@@ -30,7 +30,10 @@
 
 #include "gui/widgets/createwidget.h"
 
+#include "net/ea/npcrecv.h"
+
 #include "net/eathena/messageout.h"
+#include "net/eathena/npcrecv.h"
 #include "net/eathena/protocol.h"
 
 #include "net/ea/eaprotocol.h"
@@ -74,70 +77,70 @@ void NpcHandler::handleMessage(Net::MessageIn &msg)
     switch (msg.getId())
     {
         case SMSG_NPC_CHOICE:
-            processNpcChoice(msg);
+            Ea::NpcRecv::processNpcChoice(msg);
             break;
 
         case SMSG_NPC_MESSAGE:
-            processNpcMessage(msg);
+            Ea::NpcRecv::processNpcMessage(msg);
             break;
 
         case SMSG_NPC_CLOSE:
-            processNpcClose(msg);
+            Ea::NpcRecv::processNpcClose(msg);
             break;
 
         case SMSG_NPC_NEXT:
-            processNpcNext(msg);
+            Ea::NpcRecv::processNpcNext(msg);
             break;
 
         case SMSG_NPC_INT_INPUT:
-            processNpcIntInput(msg);
+            Ea::NpcRecv::processNpcIntInput(msg);
             break;
 
         case SMSG_NPC_STR_INPUT:
-            processNpcStrInput(msg);
+            Ea::NpcRecv::processNpcStrInput(msg);
             break;
 
         case SMSG_NPC_CUTIN:
-            processNpcCutin(msg);
+            NpcRecv::processNpcCutin(msg);
             break;
 
         case SMSG_NPC_VIEWPOINT:
-            processNpcViewPoint(msg);
+            NpcRecv::processNpcViewPoint(msg);
             break;
 
         case SMSG_NPC_SHOW_PROGRESS_BAR:
-            processNpcShowProgressBar(msg);
+            NpcRecv::processNpcShowProgressBar(msg);
             break;
 
         case SMSG_NPC_CLOSE_TIMEOUT:
-            processNpcCloseTimeout(msg);
+            NpcRecv::processNpcCloseTimeout(msg);
             break;
 
         case SMSG_NPC_COMMAND:
-            processNpcCommand(msg);
+            Ea::NpcRecv::processNpcCommand(msg);
             break;
 
         case SMSG_NPC_CHANGETITLE:
-            processChangeTitle(msg);
+            Ea::NpcRecv::processChangeTitle(msg);
             break;
 
         case SMSG_NPC_AREA:
-            processArea(msg);
+            NpcRecv::processArea(msg);
             break;
 
         case SMSG_NPC_SHOW_DIGIT:
-            processShowDigit(msg);
+            NpcRecv::processShowDigit(msg);
             break;
 
         case SMSG_NPC_PROGRESS_BAR_ABORT:
-            processProgressBarAbort(msg);
+            NpcRecv::processProgressBarAbort(msg);
             break;
 
         default:
             break;
     }
 
-    mDialog = nullptr;
+    Ea::NpcRecv::mDialog = nullptr;
 }
 
 void NpcHandler::talk(const BeingId npcId) const
@@ -164,8 +167,8 @@ void NpcHandler::closeDialog(const BeingId npcId)
         NpcDialog *const dialog = (*it).second;
         if (dialog)
             dialog->close();
-        if (dialog == mDialog)
-            mDialog = nullptr;
+        if (dialog == Ea::NpcRecv::mDialog)
+            Ea::NpcRecv::mDialog = nullptr;
         NpcDialog::mNpcDialogs.erase(it);
     }
 }
@@ -298,7 +301,7 @@ BeingId NpcHandler::getNpc(Net::MessageIn &msg)
     const BeingId npcId = msg.readBeingId("npc id");
 
     const NpcDialogs::const_iterator diag = NpcDialog::mNpcDialogs.find(npcId);
-    mDialog = nullptr;
+    Ea::NpcRecv::mDialog = nullptr;
 
     if (msg.getId() == SMSG_NPC_VIEWPOINT)
         return npcId;
@@ -318,88 +321,23 @@ BeingId NpcHandler::getNpc(Net::MessageIn &msg)
         }
         else
         {
-            CREATEWIDGETV(mDialog, NpcDialog, npcId);
-            mDialog->saveCamera();
+            CREATEWIDGETV(Ea::NpcRecv::mDialog, NpcDialog, npcId);
+            Ea::NpcRecv::mDialog->saveCamera();
             if (localPlayer)
                 localPlayer->stopWalking(false);
-            NpcDialog::mNpcDialogs[npcId] = mDialog;
+            NpcDialog::mNpcDialogs[npcId] = Ea::NpcRecv::mDialog;
         }
     }
     else
     {
         NpcDialog *const dialog = diag->second;
-        if (mDialog && mDialog != dialog)
-            mDialog->restoreCamera();
-        mDialog = dialog;
-        if (mDialog)
-            mDialog->saveCamera();
+        if (Ea::NpcRecv::mDialog && Ea::NpcRecv::mDialog != dialog)
+            Ea::NpcRecv::mDialog->restoreCamera();
+        Ea::NpcRecv::mDialog = dialog;
+        if (Ea::NpcRecv::mDialog)
+            Ea::NpcRecv::mDialog->saveCamera();
     }
     return npcId;
 }
 
-void NpcHandler::processNpcCutin(Net::MessageIn &msg)
-{
-    UNIMPLIMENTEDPACKET;
-    mRequestLang = false;
-    msg.readString(64, "image name");
-    msg.readUInt8("type");
-}
-
-void NpcHandler::processNpcViewPoint(Net::MessageIn &msg)
-{
-    UNIMPLIMENTEDPACKET;
-    mRequestLang = false;
-    // +++ probably need add nav point and start moving to it
-    msg.readInt32("npc id");
-    msg.readInt32("type");  // 0 display for 15 sec,
-                            // 1 display until teleport,
-                            // 2 remove
-    msg.readInt32("x");
-    msg.readInt32("y");
-    msg.readUInt8("number");  // can be used for scripts
-    msg.readInt32("color");
-}
-
-void NpcHandler::processNpcShowProgressBar(Net::MessageIn &msg)
-{
-    UNIMPLIMENTEDPACKET;
-    mRequestLang = false;
-    // +++ probably need show progress bar in npc dialog
-    msg.readInt32("color");
-    msg.readInt32("seconds");
-}
-
-void NpcHandler::processNpcCloseTimeout(Net::MessageIn &msg)
-{
-    UNIMPLIMENTEDPACKET;
-    mRequestLang = false;
-    // this packet send after npc closed by timeout.
-    msg.readInt32("npc id");
-}
-
-void NpcHandler::processArea(Net::MessageIn &msg)
-{
-    const int len = msg.readInt16("len");
-    if (len < 12)
-        return;
-    Being *const dstBeing = actorManager->findBeing(
-        msg.readBeingId("npc id"));
-    const int area = msg.readInt32("area size");
-    if (dstBeing)
-        dstBeing->setAreaSize(area);
-}
-
-void NpcHandler::processShowDigit(Net::MessageIn &msg)
-{
-    UNIMPLIMENTEDPACKET;
-
-    msg.readUInt8("type");
-    msg.readInt32("value");
-}
-
-void NpcHandler::processProgressBarAbort(Net::MessageIn &msg)
-{
-    UNIMPLIMENTEDPACKET;
-}
-
 }  // namespace EAthena
diff --git a/src/net/eathena/npchandler.h b/src/net/eathena/npchandler.h
index 3b35cadc5..bef960b30 100644
--- a/src/net/eathena/npchandler.h
+++ b/src/net/eathena/npchandler.h
@@ -88,21 +88,6 @@ class NpcHandler final : public MessageHandler, public Ea::NpcHandler
         void selectArrow(const int nameId) const override final;
 
         void selectAutoSpell(const int skillId) const override final;
-
-    protected:
-        static void processNpcCutin(Net::MessageIn &msg);
-
-        static void processNpcViewPoint(Net::MessageIn &msg);
-
-        static void processNpcShowProgressBar(Net::MessageIn &msg);
-
-        static void processNpcCloseTimeout(Net::MessageIn &msg);
-
-        static void processArea(Net::MessageIn &msg);
-
-        static void processShowDigit(Net::MessageIn &msg);
-
-        static void processProgressBarAbort(Net::MessageIn &msg);
 };
 
 }  // namespace EAthena
diff --git a/src/net/eathena/npcrecv.cpp b/src/net/eathena/npcrecv.cpp
new file mode 100644
index 000000000..4bc1cf657
--- /dev/null
+++ b/src/net/eathena/npcrecv.cpp
@@ -0,0 +1,109 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2011-2015  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 "net/eathena/npcrecv.h"
+
+#include "actormanager.h"
+
+#include "being/localplayer.h"
+
+#include "gui/windows/npcdialog.h"
+
+#include "gui/widgets/createwidget.h"
+
+#include "net/ea/npcrecv.h"
+
+#include "net/eathena/messageout.h"
+#include "net/eathena/protocol.h"
+
+#include "net/ea/eaprotocol.h"
+
+#include "debug.h"
+
+namespace EAthena
+{
+
+
+void NpcRecv::processNpcCutin(Net::MessageIn &msg)
+{
+    UNIMPLIMENTEDPACKET;
+    Ea::NpcRecv::mRequestLang = false;
+    msg.readString(64, "image name");
+    msg.readUInt8("type");
+}
+
+void NpcRecv::processNpcViewPoint(Net::MessageIn &msg)
+{
+    UNIMPLIMENTEDPACKET;
+    Ea::NpcRecv::mRequestLang = false;
+    // +++ probably need add nav point and start moving to it
+    msg.readInt32("npc id");
+    msg.readInt32("type");  // 0 display for 15 sec,
+                            // 1 display until teleport,
+                            // 2 remove
+    msg.readInt32("x");
+    msg.readInt32("y");
+    msg.readUInt8("number");  // can be used for scripts
+    msg.readInt32("color");
+}
+
+void NpcRecv::processNpcShowProgressBar(Net::MessageIn &msg)
+{
+    UNIMPLIMENTEDPACKET;
+    Ea::NpcRecv::mRequestLang = false;
+    // +++ probably need show progress bar in npc dialog
+    msg.readInt32("color");
+    msg.readInt32("seconds");
+}
+
+void NpcRecv::processNpcCloseTimeout(Net::MessageIn &msg)
+{
+    UNIMPLIMENTEDPACKET;
+    Ea::NpcRecv::mRequestLang = false;
+    // this packet send after npc closed by timeout.
+    msg.readInt32("npc id");
+}
+
+void NpcRecv::processArea(Net::MessageIn &msg)
+{
+    const int len = msg.readInt16("len");
+    if (len < 12)
+        return;
+    Being *const dstBeing = actorManager->findBeing(
+        msg.readBeingId("npc id"));
+    const int area = msg.readInt32("area size");
+    if (dstBeing)
+        dstBeing->setAreaSize(area);
+}
+
+void NpcRecv::processShowDigit(Net::MessageIn &msg)
+{
+    UNIMPLIMENTEDPACKET;
+
+    msg.readUInt8("type");
+    msg.readInt32("value");
+}
+
+void NpcRecv::processProgressBarAbort(Net::MessageIn &msg)
+{
+    UNIMPLIMENTEDPACKET;
+}
+
+}  // namespace EAthena
diff --git a/src/net/eathena/npcrecv.h b/src/net/eathena/npcrecv.h
new file mode 100644
index 000000000..865d53f3a
--- /dev/null
+++ b/src/net/eathena/npcrecv.h
@@ -0,0 +1,42 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2011-2015  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 NET_EATHENA_NPCRECV_H
+#define NET_EATHENA_NPCRECV_H
+
+#include "net/ea/npchandler.h"
+
+#include "net/eathena/messagehandler.h"
+
+namespace EAthena
+{
+    namespace NpcRecv
+    {
+        void processNpcCutin(Net::MessageIn &msg);
+        void processNpcViewPoint(Net::MessageIn &msg);
+        void processNpcShowProgressBar(Net::MessageIn &msg);
+        void processNpcCloseTimeout(Net::MessageIn &msg);
+        void processArea(Net::MessageIn &msg);
+        void processShowDigit(Net::MessageIn &msg);
+        void processProgressBarAbort(Net::MessageIn &msg);
+    }  // namespace NpcRecv
+}  // namespace EAthena
+
+#endif  // NET_EATHENA_NPCRECV_H
diff --git a/src/net/tmwa/npchandler.cpp b/src/net/tmwa/npchandler.cpp
index b01c3277f..c3ad53b41 100644
--- a/src/net/tmwa/npchandler.cpp
+++ b/src/net/tmwa/npchandler.cpp
@@ -28,6 +28,8 @@
 
 #include "gui/widgets/createwidget.h"
 
+#include "net/ea/npcrecv.h"
+
 #include "net/tmwa/messageout.h"
 #include "net/tmwa/protocol.h"
 
@@ -67,42 +69,42 @@ void NpcHandler::handleMessage(Net::MessageIn &msg)
     switch (msg.getId())
     {
         case SMSG_NPC_CHOICE:
-            processNpcChoice(msg);
+            Ea::NpcRecv::processNpcChoice(msg);
             break;
 
         case SMSG_NPC_MESSAGE:
-            processNpcMessage(msg);
+            Ea::NpcRecv::processNpcMessage(msg);
             break;
 
         case SMSG_NPC_CLOSE:
-            processNpcClose(msg);
+            Ea::NpcRecv::processNpcClose(msg);
             break;
 
         case SMSG_NPC_NEXT:
-            processNpcNext(msg);
+            Ea::NpcRecv::processNpcNext(msg);
             break;
 
         case SMSG_NPC_INT_INPUT:
-            processNpcIntInput(msg);
+            Ea::NpcRecv::processNpcIntInput(msg);
             break;
 
         case SMSG_NPC_STR_INPUT:
-            processNpcStrInput(msg);
+            Ea::NpcRecv::processNpcStrInput(msg);
             break;
 
         case SMSG_NPC_COMMAND:
-            processNpcCommand(msg);
+            Ea::NpcRecv::processNpcCommand(msg);
             break;
 
         case SMSG_NPC_CHANGETITLE:
-            processChangeTitle(msg);
+            Ea::NpcRecv::processChangeTitle(msg);
             break;
 
         default:
             break;
     }
 
-    mDialog = nullptr;
+    Ea::NpcRecv::mDialog = nullptr;
     BLOCK_END("NpcHandler::handleMessage")
 }
 
@@ -130,8 +132,8 @@ void NpcHandler::closeDialog(const BeingId npcId)
         NpcDialog *const dialog = (*it).second;
         if (dialog)
             dialog->close();
-        if (dialog == mDialog)
-            mDialog = nullptr;
+        if (dialog == Ea::NpcRecv::mDialog)
+            Ea::NpcRecv::mDialog = nullptr;
         NpcDialog::mNpcDialogs.erase(it);
     }
 }
@@ -248,7 +250,7 @@ BeingId NpcHandler::getNpc(Net::MessageIn &msg)
     const BeingId npcId = msg.readBeingId("npc id");
 
     const NpcDialogs::const_iterator diag = NpcDialog::mNpcDialogs.find(npcId);
-    mDialog = nullptr;
+    Ea::NpcRecv::mDialog = nullptr;
 
     if (diag == NpcDialog::mNpcDialogs.end())
     {
@@ -265,21 +267,21 @@ BeingId NpcHandler::getNpc(Net::MessageIn &msg)
         }
         else
         {
-            CREATEWIDGETV(mDialog, NpcDialog, npcId);
-            mDialog->saveCamera();
+            CREATEWIDGETV(Ea::NpcRecv::mDialog, NpcDialog, npcId);
+            Ea::NpcRecv::mDialog->saveCamera();
             if (localPlayer)
                 localPlayer->stopWalking(false);
-            NpcDialog::mNpcDialogs[npcId] = mDialog;
+            NpcDialog::mNpcDialogs[npcId] = Ea::NpcRecv::mDialog;
         }
     }
     else
     {
         NpcDialog *const dialog = diag->second;
-        if (mDialog && mDialog != dialog)
-            mDialog->restoreCamera();
-        mDialog = dialog;
-        if (mDialog)
-            mDialog->saveCamera();
+        if (Ea::NpcRecv::mDialog && Ea::NpcRecv::mDialog != dialog)
+            Ea::NpcRecv::mDialog->restoreCamera();
+        Ea::NpcRecv::mDialog = dialog;
+        if (Ea::NpcRecv::mDialog)
+            Ea::NpcRecv::mDialog->saveCamera();
     }
     return npcId;
 }
-- 
cgit v1.2.3-70-g09d2