summaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
authorPhilipp Sehmisch <crush@themanaworld.org>2009-03-29 18:33:44 +0200
committerPhilipp Sehmisch <crush@themanaworld.org>2009-03-29 18:33:44 +0200
commit9587fb9b86ee4081ba14d23c1133bf1a09ee4578 (patch)
tree7682df3ec17534be553caae85ffa9e5a68c9a815 /src/net
parent63b41440a0555c6b39141eab94ef4627f712b476 (diff)
parent8748f26234bba1e71bbe059147fb02256f8cec2a (diff)
downloadmana-9587fb9b86ee4081ba14d23c1133bf1a09ee4578.tar.gz
mana-9587fb9b86ee4081ba14d23c1133bf1a09ee4578.tar.bz2
mana-9587fb9b86ee4081ba14d23c1133bf1a09ee4578.tar.xz
mana-9587fb9b86ee4081ba14d23c1133bf1a09ee4578.zip
Merge branch 'master' of git@gitorious.org:tmw/mainline
Diffstat (limited to 'src/net')
-rw-r--r--src/net/ea/beinghandler.cpp43
-rw-r--r--src/net/ea/buysellhandler.cpp5
-rw-r--r--src/net/ea/chathandler.cpp2
-rw-r--r--src/net/ea/equipmenthandler.cpp47
-rw-r--r--src/net/ea/gui/partytab.cpp53
-rw-r--r--src/net/ea/gui/partytab.h51
-rw-r--r--src/net/ea/inventoryhandler.cpp107
-rw-r--r--src/net/ea/network.cpp9
-rw-r--r--src/net/ea/network.h8
-rw-r--r--src/net/ea/party.cpp194
-rw-r--r--src/net/ea/party.h58
-rw-r--r--src/net/ea/partyhandler.cpp31
-rw-r--r--src/net/ea/partyhandler.h9
-rw-r--r--src/net/ea/playerhandler.cpp11
-rw-r--r--src/net/ea/protocol.h5
-rw-r--r--src/net/ea/skillhandler.cpp3
-rw-r--r--src/net/ea/tradehandler.cpp3
-rw-r--r--src/net/messageout.cpp11
-rw-r--r--src/net/messageout.h4
-rw-r--r--src/net/tmwserv/beinghandler.cpp5
-rw-r--r--src/net/tmwserv/partyhandler.cpp3
-rw-r--r--src/net/tmwserv/playerhandler.cpp3
-rw-r--r--src/net/tmwserv/tradehandler.cpp3
23 files changed, 562 insertions, 106 deletions
diff --git a/src/net/ea/beinghandler.cpp b/src/net/ea/beinghandler.cpp
index 237c9f1f..0ad15d7d 100644
--- a/src/net/ea/beinghandler.cpp
+++ b/src/net/ea/beinghandler.cpp
@@ -24,6 +24,7 @@
#include "net/ea/protocol.h"
#include "net/messagein.h"
+#include "net/messageout.h"
#include "being.h"
#include "beingmanager.h"
@@ -37,7 +38,6 @@
#include "gui/npc_text.h"
#include <iostream>
-#include <SDL_types.h>
extern NpcTextDialog *npcTextDialog;
@@ -69,10 +69,34 @@ BeingHandler::BeingHandler(bool enableSync):
handledMessages = _messages;
}
+Being *createBeing(int id, short job)
+{
+ Being::Type type = Being::UNKNOWN;
+ if (job <= 25 || (job >= 4001 && job <= 4049))
+ type = Being::PLAYER;
+ else if (job >= 46 && job <= 1000)
+ type = Being::NPC;
+ else if (job > 1000 && job <= 2000)
+ {
+ type = Being::MONSTER;
+ job -= 1002;
+ }
+
+ Being *being = beingManager->createBeing(id, type, job);
+
+ if (type == Being::PLAYER || type == Being::NPC)
+ {
+ MessageOut outMsg(0x0094);
+ outMsg.writeInt32(id);//readLong(2));
+ }
+
+ return being;
+}
+
void BeingHandler::handleMessage(MessageIn &msg)
{
int id;
- Uint16 job, speed;
+ short job, speed;
Uint16 headTop, headMid, headBottom;
Uint16 shoes, gloves;
Uint16 weapon, shield;
@@ -108,9 +132,14 @@ void BeingHandler::handleMessage(MessageIn &msg)
break;
}
- dstBeing = beingManager->createBeing(id, job);
+ dstBeing = createBeing(id, job);
}
- else if (msg.getId() == 0x0078)
+ else if (dstBeing->getType() == Being::MONSTER)
+ {
+ job -= 1002;
+ }
+
+ if (msg.getId() == 0x0078)
{
dstBeing->clearPath();
dstBeing->mFrame = 0;
@@ -399,7 +428,11 @@ void BeingHandler::handleMessage(MessageIn &msg)
if (!dstBeing)
{
- dstBeing = beingManager->createBeing(id, job);
+ dstBeing = createBeing(id, job);
+ }
+ else if (dstBeing->getType() == Being::MONSTER)
+ {
+ job -= 1002;
}
dstBeing->setWalkSpeed(speed);
diff --git a/src/net/ea/buysellhandler.cpp b/src/net/ea/buysellhandler.cpp
index b99db6a4..56d6a986 100644
--- a/src/net/ea/buysellhandler.cpp
+++ b/src/net/ea/buysellhandler.cpp
@@ -33,12 +33,11 @@
#include "gui/buy.h"
#include "gui/buysell.h"
-#include "gui/chat.h"
#include "gui/sell.h"
-#include "utils/gettext.h"
+#include "gui/widgets/chattab.h"
-#include <SDL_types.h>
+#include "utils/gettext.h"
BuySellHandler::BuySellHandler()
{
diff --git a/src/net/ea/chathandler.cpp b/src/net/ea/chathandler.cpp
index 14432b28..6aca58a3 100644
--- a/src/net/ea/chathandler.cpp
+++ b/src/net/ea/chathandler.cpp
@@ -30,7 +30,7 @@
#include "game.h"
#include "player_relations.h"
-#include "gui/chat.h"
+#include "gui/widgets/chattab.h"
#include "utils/gettext.h"
#include "utils/stringutils.h"
diff --git a/src/net/ea/equipmenthandler.cpp b/src/net/ea/equipmenthandler.cpp
index 7a287bea..d30b2681 100644
--- a/src/net/ea/equipmenthandler.cpp
+++ b/src/net/ea/equipmenthandler.cpp
@@ -31,10 +31,12 @@
#include "localplayer.h"
#include "log.h"
-#include "gui/chat.h"
+#include "gui/widgets/chattab.h"
#include "utils/gettext.h"
+enum { debugEquipment = 1 };
+
EquipmentHandler::EquipmentHandler()
{
static const Uint16 _messages[] = {
@@ -65,7 +67,7 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
for (int loop = 0; loop < itemCount; loop++)
{
- index = msg.readInt16();
+ index = msg.readInt16() - INVENTORY_OFFSET;
itemId = msg.readInt16();
msg.readInt8(); // type
msg.readInt8(); // identify flag
@@ -75,6 +77,11 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
msg.readInt8(); // refine
msg.skip(8); // card
+ if (debugEquipment)
+ {
+ logger->log("Index: %d, ID: %d", index, itemId);
+ }
+
inventory->setItem(index, itemId, 1, true);
if (equipPoint)
@@ -93,21 +100,19 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
break;
case SMSG_PLAYER_EQUIP:
- index = msg.readInt16();
+ index = msg.readInt16() - INVENTORY_OFFSET;
equipPoint = msg.readInt16();
type = msg.readInt8();
- logger->log("Equipping: %i %i %i", index, equipPoint, type);
-
- if (!type) {
+ if (!type)
+ {
localChatTab->chatLog(_("Unable to equip."), BY_SERVER);
break;
}
- if (!equipPoint) {
- // No point given, no point in searching
+ // No point in searching when no point given
+ if (!equipPoint)
break;
- }
/*
* An item may occupy more than 1 slot. If so, it's
@@ -119,21 +124,25 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
mask <<= 1;
position++;
}
- logger->log("Position %i", position);
- item = player_node->getInventory()->getItem(player_node->mEquipment->getEquipment(position));
+ if (debugEquipment)
+ {
+ logger->log("Equipping: %i %i %i at position %i",
+ index, equipPoint, type, position);
+ }
+
+ item = inventory->getItem(player_node->mEquipment->getEquipment(position));
// Unequip any existing equipped item in this position
- if (item) {
+ if (item)
item->setEquipped(false);
- }
item = inventory->getItem(index);
player_node->mEquipment->setEquipment(position, index);
break;
case SMSG_PLAYER_UNEQUIP:
- index = msg.readInt16();
+ index = msg.readInt16() - INVENTORY_OFFSET;
equipPoint = msg.readInt16();
type = msg.readInt8();
@@ -166,8 +175,12 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
else {
player_node->mEquipment->removeEquipment(position);
}
- logger->log("Unequipping: %i %i(%i) %i",
- index, equipPoint, type, position);
+
+ if (debugEquipment)
+ {
+ logger->log("Unequipping: %i %i(%i) %i",
+ index, equipPoint, type, position);
+ }
break;
case SMSG_PLAYER_ATTACK_RANGE:
@@ -180,6 +193,8 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
if (index <= 1)
break;
+ index -= INVENTORY_OFFSET;
+
item = inventory->getItem(index);
if (item) {
diff --git a/src/net/ea/gui/partytab.cpp b/src/net/ea/gui/partytab.cpp
new file mode 100644
index 00000000..4e486bf0
--- /dev/null
+++ b/src/net/ea/gui/partytab.cpp
@@ -0,0 +1,53 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <guichan/widgets/label.hpp>
+
+#include "partytab.h"
+
+#include "net/messageout.h"
+
+#include "net/ea/party.h"
+#include "net/ea/protocol.h"
+
+#include "resources/iteminfo.h"
+#include "resources/itemdb.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/strprintf.h"
+#include "utils/stringutils.h"
+
+PartyTab::PartyTab() : ChatTab(_("Party"))
+{
+}
+
+PartyTab::~PartyTab()
+{
+}
+
+void PartyTab::handleInput(const std::string &msg) {
+ // TODO
+}
+
+void PartyTab::handleCommand(std::string msg) {
+ // TODO
+}
diff --git a/src/net/ea/gui/partytab.h b/src/net/ea/gui/partytab.h
new file mode 100644
index 00000000..fce4b515
--- /dev/null
+++ b/src/net/ea/gui/partytab.h
@@ -0,0 +1,51 @@
+/*
+ * The Mana World
+ * Copyright (C) 2009 The Mana World Development Team
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef CHANNELTAB_H
+#define CHANNELTAB_H
+
+#include "gui/widgets/chattab.h"
+
+/**
+ * A tab for a chat channel.
+ */
+class PartyTab : public ChatTab
+{
+ public:
+ /**
+ * Constructor.
+ */
+ PartyTab();
+
+ /**
+ * Destructor.
+ */
+ ~PartyTab();
+
+ protected:
+ void handleInput(const std::string &msg);
+
+ void handleCommand(std::string msg);
+};
+
+extern PartyTab *partyTab;
+
+#endif // CHANNELTAB_H
diff --git a/src/net/ea/inventoryhandler.cpp b/src/net/ea/inventoryhandler.cpp
index 21ae6dcb..e1429093 100644
--- a/src/net/ea/inventoryhandler.cpp
+++ b/src/net/ea/inventoryhandler.cpp
@@ -32,9 +32,10 @@
#include "localplayer.h"
#include "log.h"
-#include "gui/chat.h"
#include "gui/storagewindow.h"
+#include "gui/widgets/chattab.h"
+
#include "resources/iteminfo.h"
#include "utils/gettext.h"
@@ -43,6 +44,8 @@
#include <SDL_types.h>
+enum { debugInventory = 1 };
+
InventoryHandler::InventoryHandler()
{
static const Uint16 _messages[] = {
@@ -74,28 +77,26 @@ void InventoryHandler::handleMessage(MessageIn &msg)
{
case SMSG_PLAYER_INVENTORY:
case SMSG_PLAYER_STORAGE_ITEMS:
- switch (msg.getId()) {
- case SMSG_PLAYER_INVENTORY:
- // Clear inventory - this will be a complete refresh
- inventory->clear();
- break;
- case SMSG_PLAYER_STORAGE_ITEMS:
- /*
- * This packet will always be followed by a
- * SMSG_PLAYER_STORAGE_EQUIP packet. The two packets
- * together comprise a complete refresh of storage, so
- * clear storage here
- */
- storage->clear();
- break;
- default:
- logger->log("HOW DID WE GET HERE?");
- return;
+ if (msg.getId() == SMSG_PLAYER_INVENTORY)
+ {
+ // Clear inventory - this will be a complete refresh
+ inventory->clear();
+ }
+ else
+ {
+ /*
+ * This packet will always be followed by a
+ * SMSG_PLAYER_STORAGE_EQUIP packet. The two packets
+ * together comprise a complete refresh of storage, so
+ * clear storage here
+ */
+ storage->clear();
}
msg.readInt16(); // length
number = (msg.getLength() - 4) / 18;
- for (int loop = 0; loop < number; loop++) {
+ for (int loop = 0; loop < number; loop++)
+ {
index = msg.readInt16();
itemId = msg.readInt16();
itemType = msg.readInt8();
@@ -105,6 +106,17 @@ void InventoryHandler::handleMessage(MessageIn &msg)
for (int i = 0; i < 4; i++)
cards[i] = msg.readInt16();
+ index -= (msg.getId() == SMSG_PLAYER_INVENTORY) ?
+ INVENTORY_OFFSET : STORAGE_OFFSET;
+
+ if (debugInventory)
+ {
+ logger->log("Index: %d, ID: %d, Type: %d, Identified: %d, "
+ "Qty: %d, Cards: %d, %d, %d, %d",
+ index, itemId, itemType, identified, amount,
+ cards[0], cards[1], cards[2], cards[3]);
+ }
+
if (msg.getId() == SMSG_PLAYER_INVENTORY) {
inventory->setItem(index, itemId, amount, false);
@@ -114,8 +126,6 @@ void InventoryHandler::handleMessage(MessageIn &msg)
item->setEquipment(true);
}
} else {
- logger->log("Index:%d, ID:%d, Type:%d, Identified:%d, Qty:%d, Cards:%d, %d, %d, %d",
- index, itemId, itemType, identified, amount, cards[0], cards[1], cards[2], cards[3]);
storage->setItem(index, itemId, amount, false);
}
}
@@ -126,7 +136,7 @@ void InventoryHandler::handleMessage(MessageIn &msg)
number = (msg.getLength() - 4) / 20;
for (int loop = 0; loop < number; loop++) {
- index = msg.readInt16();
+ index = msg.readInt16() - STORAGE_OFFSET;
itemId = msg.readInt16();
itemType = msg.readInt8();
identified = msg.readInt8();
@@ -138,14 +148,20 @@ void InventoryHandler::handleMessage(MessageIn &msg)
for (int i = 0; i < 4; i++)
cards[i] = msg.readInt16();
- logger->log("Index:%d, ID:%d, Type:%d, Identified:%d, Qty:%d, Cards:%d, %d, %d, %d",
- index, itemId, itemType, identified, amount, cards[0], cards[1], cards[2], cards[3]);
+ if (debugInventory)
+ {
+ logger->log("Index: %d, ID: %d, Type: %d, Identified: %d, "
+ "Qty: %d, Cards: %d, %d, %d, %d",
+ index, itemId, itemType, identified, amount,
+ cards[0], cards[1], cards[2], cards[3]);
+ }
+
storage->setItem(index, itemId, amount, false);
}
break;
case SMSG_PLAYER_INVENTORY_ADD:
- index = msg.readInt16();
+ index = msg.readInt16() - INVENTORY_OFFSET;
amount = msg.readInt16();
itemId = msg.readInt16();
identified = msg.readInt8();
@@ -156,20 +172,26 @@ void InventoryHandler::handleMessage(MessageIn &msg)
equipType = msg.readInt16();
itemType = msg.readInt8();
- if (msg.readInt8() > 0) {
- if (config.getValue("showpickupchat", true)) {
+ if (msg.readInt8() > 0)
+ {
+ if (config.getValue("showpickupchat", true))
localChatTab->chatLog(_("Unable to pick up item"), BY_SERVER);
- }
- } else {
+ }
+ else
+ {
const ItemInfo &itemInfo = ItemDB::get(itemId);
const std::string amountStr =
(amount > 1) ? toString(amount) : "a";
- if (config.getValue("showpickupchat", true)) {
+
+ if (config.getValue("showpickupchat", true))
+ {
localChatTab->chatLog(strprintf(_("You picked up %s [%s]"),
amountStr.c_str(), itemInfo.getName().c_str()),
BY_SERVER);
}
- if (config.getValue("showpickupparticle", false)) {
+
+ if (config.getValue("showpickupparticle", false))
+ {
player_node->pickedUp(itemInfo.getName());
}
@@ -183,9 +205,10 @@ void InventoryHandler::handleMessage(MessageIn &msg)
break;
case SMSG_PLAYER_INVENTORY_REMOVE:
- index = msg.readInt16();
+ index = msg.readInt16() - INVENTORY_OFFSET;
amount = msg.readInt16();
- if (Item *item = inventory->getItem(index)) {
+ if (Item *item = inventory->getItem(index))
+ {
item->increaseQuantity(-amount);
if (item->getQuantity() == 0)
inventory->removeItemAt(index);
@@ -193,7 +216,7 @@ void InventoryHandler::handleMessage(MessageIn &msg)
break;
case SMSG_PLAYER_INVENTORY_USE:
- index = msg.readInt16();
+ index = msg.readInt16() - INVENTORY_OFFSET;
msg.readInt16(); // item id
msg.readInt32(); // id
amount = msg.readInt16();
@@ -204,7 +227,7 @@ void InventoryHandler::handleMessage(MessageIn &msg)
break;
case SMSG_ITEM_USE_RESPONSE:
- index = msg.readInt16();
+ index = msg.readInt16() - INVENTORY_OFFSET;
amount = msg.readInt16();
if (msg.readInt8() == 0) {
@@ -230,7 +253,7 @@ void InventoryHandler::handleMessage(MessageIn &msg)
/*
* Move an item into storage
*/
- index = msg.readInt16();
+ index = msg.readInt16() - STORAGE_OFFSET;
amount = msg.readInt32();
itemId = msg.readInt16();
identified = msg.readInt8();
@@ -239,10 +262,13 @@ void InventoryHandler::handleMessage(MessageIn &msg)
for (int i = 0; i < 4; i++)
cards[i] = msg.readInt16();
- if (Item *item = storage->getItem(index)) {
+ if (Item *item = storage->getItem(index))
+ {
item->setId(itemId);
item->increaseQuantity(amount);
- } else {
+ }
+ else
+ {
storage->setItem(index, itemId, amount, false);
}
break;
@@ -251,9 +277,10 @@ void InventoryHandler::handleMessage(MessageIn &msg)
/*
* Move an item out of storage
*/
- index = msg.readInt16();
+ index = msg.readInt16() - STORAGE_OFFSET;
amount = msg.readInt16();
- if (Item *item = storage->getItem(index)) {
+ if (Item *item = storage->getItem(index))
+ {
item->increaseQuantity(-amount);
if (item->getQuantity() == 0)
storage->removeItemAt(index);
diff --git a/src/net/ea/network.cpp b/src/net/ea/network.cpp
index e17b8f3b..4aecb268 100644
--- a/src/net/ea/network.cpp
+++ b/src/net/ea/network.cpp
@@ -91,6 +91,8 @@ int networkThread(void *data)
return 0;
}
+Network *Network::mInstance = 0;
+
Network::Network():
mSocket(0),
mAddress(), mPort(0),
@@ -102,6 +104,7 @@ Network::Network():
mWorkerThread(0)
{
mMutex = SDL_CreateMutex();
+ mInstance = this;
}
Network::~Network()
@@ -112,6 +115,7 @@ Network::~Network()
disconnect();
SDL_DestroyMutex(mMutex);
+ mInstance = 0;
delete[] mInBuffer;
delete[] mOutBuffer;
@@ -420,6 +424,11 @@ void Network::receive()
SDLNet_FreeSocketSet(set);
}
+Network *Network::instance()
+{
+ return mInstance;
+}
+
void Network::setError(const std::string &error)
{
logger->log("Network error: %s", error.c_str());
diff --git a/src/net/ea/network.h b/src/net/ea/network.h
index 651b1182..c246ab8e 100644
--- a/src/net/ea/network.h
+++ b/src/net/ea/network.h
@@ -36,8 +36,6 @@
class MessageHandler;
class MessageIn;
-class Network;
-
class Network
{
public:
@@ -85,7 +83,9 @@ class Network
NET_ERROR
};
- protected:
+ private:
+ static Network *instance();
+
void setError(const std::string &error);
Uint16 readWord(int pos);
@@ -113,6 +113,8 @@ class Network
typedef std::map<Uint16, MessageHandler*> MessageHandlers;
typedef MessageHandlers::iterator MessageHandlerIterator;
MessageHandlers mMessageHandlers;
+
+ static Network *mInstance;
};
#endif
diff --git a/src/net/ea/party.cpp b/src/net/ea/party.cpp
new file mode 100644
index 00000000..0fbba2f1
--- /dev/null
+++ b/src/net/ea/party.cpp
@@ -0,0 +1,194 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net>
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "being.h"
+#include "localplayer.h"
+#include "party.h"
+
+#include "gui/widgets/chattab.h"
+#include "gui/chat.h"
+#include "gui/confirm_dialog.h"
+#include "gui/partywindow.h"
+
+#include "net/messageout.h"
+#include "net/ea/protocol.h"
+#include "net/ea/gui/partytab.h"
+
+#include "utils/gettext.h"
+#include "utils/strprintf.h"
+
+void eAthena::Party::respond(const std::string &command, const std::string &args)
+{
+ if (command == "new" || command == "create")
+ {
+ create(args);
+ return;
+ }
+ if (command == "leave")
+ {
+ leave(args);
+ return;
+ }
+ if (command == "settings")
+ {
+ partyTab->chatLog(_("Not yet implemented!"), BY_SERVER);
+ return;
+ /*
+ MessageOut outMsg(CMSG_PARTY_SETTINGS);
+ outMsg.writeInt16(0); // Experience
+ outMsg.writeInt16(0); // Item
+ */
+ }
+ partyTab->chatLog(_("Party command not known."), BY_SERVER);
+}
+
+void eAthena::Party::create(const std::string &party)
+{
+ if (party.empty())
+ {
+ localChatTab->chatLog(_("Party name is missing."), BY_SERVER);
+ return;
+ }
+ MessageOut outMsg(CMSG_PARTY_CREATE);
+ outMsg.writeString(party.substr(0, 23), 24);
+}
+
+void eAthena::Party::leave(const std::string &args)
+{
+ MessageOut outMsg(CMSG_PARTY_LEAVE);
+ localChatTab->chatLog(_("Left party."), BY_SERVER);
+ player_node->setInParty(false);
+}
+
+void eAthena::Party::createResponse(bool ok)
+{
+ if (ok)
+ {
+ localChatTab->chatLog(_("Party successfully created."), BY_SERVER);
+ player_node->setInParty(true);
+ }
+ else
+ {
+ localChatTab->chatLog(_("Could not create party."), BY_SERVER);
+ }
+}
+
+void eAthena::Party::inviteResponse(const std::string &nick, int status)
+{
+ switch (status)
+ {
+ case 0:
+ partyTab->chatLog(strprintf(_("%s is already a member of a party."),
+ nick.c_str()), BY_SERVER);
+ break;
+ case 1:
+ partyTab->chatLog(strprintf(_("%s refused your invitation."),
+ nick.c_str()), BY_SERVER);
+ break;
+ case 2:
+ partyTab->chatLog(strprintf(_("%s is now a member of your party."),
+ nick.c_str()), BY_SERVER);
+ break;
+ }
+}
+
+void eAthena::Party::respondToInvite(bool accept)
+{
+ MessageOut outMsg(CMSG_PARTY_INVITED);
+ outMsg.writeInt32(player_node->getId());
+ outMsg.writeInt32(accept ? 1 : 0);
+ player_node->setInParty(player_node->getInParty() || accept);
+}
+
+void eAthena::Party::leftResponse(const std::string &nick)
+{
+ localChatTab->chatLog(strprintf(_("%s has left your party."), nick.c_str()),
+ BY_SERVER);
+ partyWindow->removePartyMember(nick);
+}
+
+void eAthena::Party::receiveChat(Being *being, const std::string &msg)
+{
+ if (!being)
+ {
+ return;
+ }
+ if (being->getType() != Being::PLAYER)
+ {
+ localChatTab->chatLog(_("Party chat received, but being is not a player"),
+ BY_SERVER);
+ return;
+ }
+ being->setSpeech(msg, SPEECH_TIME);
+ localChatTab->chatLog(being->getName() + " : " + msg, BY_PARTY);
+}
+
+void eAthena::Party::help(const std::string &args)
+{
+ // Strip "party " from the front
+ std::string msg = args.substr(6, args.length());
+
+ if (msg.empty())
+ {
+ localChatTab->chatLog(_("Command: /party <command> <args>"), BY_SERVER);
+ localChatTab->chatLog(_("where <command> can be one of:"), BY_SERVER);
+ localChatTab->chatLog(_(" /new"), BY_SERVER);
+ localChatTab->chatLog(_(" /create"), BY_SERVER);
+ localChatTab->chatLog(_(" /prefix"), BY_SERVER);
+ localChatTab->chatLog(_(" /leave"), BY_SERVER);
+ localChatTab->chatLog(_("This command implements the partying function."),
+ BY_SERVER);
+ localChatTab->chatLog(_("Type /help party <command> for further help."),
+ BY_SERVER);
+ return;
+ }
+ if (msg == "new" || msg == "create")
+ {
+ localChatTab->chatLog(_("Command: /party new <party-name>"), BY_SERVER);
+ localChatTab->chatLog(_("Command: /party create <party-name>"), BY_SERVER);
+ localChatTab->chatLog(_("These commands create a new party <party-name."),
+ BY_SERVER);
+ return;
+ }
+ if (msg == "prefix")
+ {
+ localChatTab->chatLog(_("Command: /party prefix <prefix-char>"), BY_SERVER);
+ localChatTab->chatLog(_("This command sets the party prefix character."),
+ BY_SERVER);
+ localChatTab->chatLog(_("Any message preceded by <prefix-char> is sent to "
+ "the party instead of everyone."), BY_SERVER);
+ localChatTab->chatLog(_("Command: /party prefix"), BY_SERVER);
+ localChatTab->chatLog(_("This command reports the current party prefix "
+ "character."), BY_SERVER);
+ return;
+ }
+ //if (msg == "settings")
+ //if (msg == "info")
+ if (msg == "leave")
+ {
+ localChatTab->chatLog(_("Command: /party leave"), BY_SERVER);
+ localChatTab->chatLog(_("This command causes the player to leave the party."),
+ BY_SERVER);
+ return;
+ }
+ localChatTab->chatLog(_("Unknown /party command."), BY_SERVER);
+ localChatTab->chatLog(_("Type /help party for a list of options."), BY_SERVER);
+}
diff --git a/src/net/ea/party.h b/src/net/ea/party.h
new file mode 100644
index 00000000..6907de47
--- /dev/null
+++ b/src/net/ea/party.h
@@ -0,0 +1,58 @@
+/*
+ * The Mana World
+ * Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net>
+ *
+ * This file is part of The Mana World.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PARTY_H
+#define PARTY_H
+
+#include "being.h"
+
+#include <string>
+
+namespace eAthena
+{
+ namespace Party
+ {
+ void respond(const std::string &command, const std::string &args);
+
+ void create(const std::string &party);
+ void leave(const std::string &args);
+
+ void createResponse(bool ok);
+ void inviteResponse(const std::string &nick, int status);
+ void invitedAsk(const std::string &nick, int gender,
+ const std::string &partyName);
+
+ /**
+ * Send invite response to the server
+ */
+ void respondToInvite(bool accept);
+
+ /**
+ * The player has left your party
+ */
+ void leftResponse(const std::string &nick);
+ void receiveChat(Being *being, const std::string &msg);
+
+ void help(const std::string &args);
+ }
+}
+
+#endif
diff --git a/src/net/ea/partyhandler.cpp b/src/net/ea/partyhandler.cpp
index d903976e..7ecf0863 100644
--- a/src/net/ea/partyhandler.cpp
+++ b/src/net/ea/partyhandler.cpp
@@ -21,21 +21,29 @@
#include "net/ea/partyhandler.h"
+#include "net/ea/gui/partytab.h"
+
#include "net/ea/protocol.h"
#include "net/messagein.h"
#include "gui/chat.h"
+#include "gui/partywindow.h"
#include "beingmanager.h"
#include "party.h"
-PartyHandler::PartyHandler(Party *party) : mParty(party)
+PartyTab *partyTab;
+
+static void newPartyTab() { partyTab = new PartyTab(); }
+static void deletePartyTab() { delete partyTab ; }
+
+PartyHandler::PartyHandler()
{
static const Uint16 _messages[] = {
SMSG_PARTY_CREATE,
SMSG_PARTY_INFO,
- SMSG_PARTY_INVITE,
+ SMSG_PARTY_INVITE_RESPONSE,
SMSG_PARTY_INVITED,
SMSG_PARTY_SETTINGS,
SMSG_PARTY_MEMBER_INFO,
@@ -46,6 +54,13 @@ PartyHandler::PartyHandler(Party *party) : mParty(party)
0
};
handledMessages = _messages;
+
+ newPartyTab();
+}
+
+PartyHandler::~PartyHandler()
+{
+ deletePartyTab();
}
void PartyHandler::handleMessage(MessageIn &msg)
@@ -53,15 +68,15 @@ void PartyHandler::handleMessage(MessageIn &msg)
switch (msg.getId())
{
case SMSG_PARTY_CREATE:
- mParty->createResponse(msg.readInt8());
+ eAthena::Party::createResponse(msg.readInt8());
break;
case SMSG_PARTY_INFO:
break;
- case SMSG_PARTY_INVITE:
+ case SMSG_PARTY_INVITE_RESPONSE:
{
std::string nick = msg.readString(24);
int status = msg.readInt8();
- mParty->inviteResponse(nick, status);
+ eAthena::Party::inviteResponse(nick, status);
break;
}
case SMSG_PARTY_INVITED:
@@ -85,7 +100,7 @@ void PartyHandler::handleMessage(MessageIn &msg)
gender = being->getGender();
partyName = msg.readString(24);
}
- mParty->invitedAsk(nick, gender, partyName);
+ partyWindow->showPartyInvite(nick, partyName);
break;
}
case SMSG_PARTY_SETTINGS:
@@ -97,7 +112,7 @@ void PartyHandler::handleMessage(MessageIn &msg)
/*int id = */msg.readInt32();
std::string nick = msg.readString(24);
/*int fail = */msg.readInt8();
- mParty->leftResponse(nick);
+ eAthena::Party::leftResponse(nick);
break;
}
case SMSG_PARTY_UPDATE_HP:
@@ -114,7 +129,7 @@ void PartyHandler::handleMessage(MessageIn &msg)
int id = msg.readInt32();
Being *being = beingManager->findBeing(id);
std::string chatMsg = msg.readString(msgLength);
- mParty->receiveChat(being, chatMsg);
+ eAthena::Party::receiveChat(being, chatMsg);
}
break;
}
diff --git a/src/net/ea/partyhandler.h b/src/net/ea/partyhandler.h
index 851c4ae3..c6ee261b 100644
--- a/src/net/ea/partyhandler.h
+++ b/src/net/ea/partyhandler.h
@@ -24,17 +24,14 @@
#include "net/messagehandler.h"
-class Party;
-
class PartyHandler : public MessageHandler
{
public:
- PartyHandler(Party *party);
+ PartyHandler();
- void handleMessage(MessageIn &msg);
+ ~PartyHandler();
- private:
- Party *mParty;
+ void handleMessage(MessageIn &msg);
};
#endif // NET_EA_PARTYHANDLER_H
diff --git a/src/net/ea/playerhandler.cpp b/src/net/ea/playerhandler.cpp
index 00230ea3..534c1b7b 100644
--- a/src/net/ea/playerhandler.cpp
+++ b/src/net/ea/playerhandler.cpp
@@ -24,6 +24,7 @@
#include "net/ea/protocol.h"
#include "net/messagein.h"
+#include "net/messageout.h"
#include "engine.h"
#include "localplayer.h"
@@ -33,7 +34,6 @@
#include "gui/buy.h"
#include "gui/buysell.h"
-#include "gui/chat.h"
#include "gui/gui.h"
#include "gui/npc_text.h"
#include "gui/npcintegerdialog.h"
@@ -45,6 +45,8 @@
#include "gui/storagewindow.h"
#include "gui/viewport.h"
+#include "gui/widgets/chattab.h"
+
#include "utils/stringutils.h"
#include "utils/gettext.h"
@@ -91,7 +93,8 @@ namespace {
sellDialog->setVisible(false);
buySellDialog->setVisible(false);
- if (storageWindow->isVisible()) storageWindow->close();
+ if (storageWindow->isVisible())
+ storageWindow->close();
}
} deathListener;
@@ -192,7 +195,9 @@ void PlayerHandler::handleMessage(MessageIn &msg)
nearby = (engine->getCurrentMapName() == mapPath);
// Switch the actual map, deleting the previous one if necessary
- engine->changeMap(mapPath);
+ mapPath = mapPath.substr(0, mapPath.rfind("."));
+ if (engine->changeMap(mapPath))
+ MessageOut outMsg(CMSG_MAP_LOADED);
float scrollOffsetX = 0.0f;
float scrollOffsetY = 0.0f;
diff --git a/src/net/ea/protocol.h b/src/net/ea/protocol.h
index c96ff7b6..ff13cce9 100644
--- a/src/net/ea/protocol.h
+++ b/src/net/ea/protocol.h
@@ -22,6 +22,9 @@
#ifndef EA_PROTOCOL_H
#define EA_PROTOCOL_H
+static const int INVENTORY_OFFSET = 2;
+static const int STORAGE_OFFSET = 1;
+
/*********************************
* Packets from server to client *
*********************************/
@@ -98,7 +101,7 @@
#define SMSG_PARTY_CREATE 0x00fa
#define SMSG_PARTY_INFO 0x00fb
-#define SMSG_PARTY_INVITE 0x00fd
+#define SMSG_PARTY_INVITE_RESPONSE 0x00fd
#define SMSG_PARTY_INVITED 0x00fe
#define SMSG_PARTY_SETTINGS 0x0102
#define SMSG_PARTY_MEMBER_INFO 0x0104
diff --git a/src/net/ea/skillhandler.cpp b/src/net/ea/skillhandler.cpp
index fcc0f4b2..477f96bf 100644
--- a/src/net/ea/skillhandler.cpp
+++ b/src/net/ea/skillhandler.cpp
@@ -27,9 +27,10 @@
#include "log.h"
-#include "gui/chat.h"
#include "gui/skill.h"
+#include "gui/widgets/chattab.h"
+
#include "utils/gettext.h"
/** job dependend identifiers (?) */
diff --git a/src/net/ea/tradehandler.cpp b/src/net/ea/tradehandler.cpp
index ea41ed70..1df02a1e 100644
--- a/src/net/ea/tradehandler.cpp
+++ b/src/net/ea/tradehandler.cpp
@@ -30,10 +30,11 @@
#include "localplayer.h"
#include "player_relations.h"
-#include "gui/chat.h"
#include "gui/confirm_dialog.h"
#include "gui/trade.h"
+#include "gui/widgets/chattab.h"
+
#include "utils/gettext.h"
std::string tradePartnerName;
diff --git a/src/net/messageout.cpp b/src/net/messageout.cpp
index 4cb4dc36..35e9a425 100644
--- a/src/net/messageout.cpp
+++ b/src/net/messageout.cpp
@@ -33,21 +33,16 @@
#include <cstring>
#include <string>
-#ifdef TMWSERV_SUPPORT
MessageOut::MessageOut(short id):
mData(0),
-#else
-MessageOut::MessageOut(Network *network):
- mNetwork(network),
-#endif
mDataSize(0),
mPos(0)
{
-#ifdef TMWSERV_SUPPORT
- writeInt16(id);
-#else
+#ifdef EATHENA_SUPPORT
+ mNetwork = Network::instance();
mData = mNetwork->mOutBuffer + mNetwork->mOutSize;
#endif
+ writeInt16(id);
}
#ifdef TMWSERV_SUPPORT
diff --git a/src/net/messageout.h b/src/net/messageout.h
index 1ddd040d..9dc31525 100644
--- a/src/net/messageout.h
+++ b/src/net/messageout.h
@@ -43,15 +43,13 @@ class MessageOut
/**
* Constructor.
*/
-#ifdef TMWSERV_SUPPORT
MessageOut(short id);
+#ifdef TMWSERV_SUPPORT
/**
* Destructor.
*/
~MessageOut();
-#else
- MessageOut(Network *network);
#endif
void writeInt8(Sint8 value); /**< Writes a byte. */
diff --git a/src/net/tmwserv/beinghandler.cpp b/src/net/tmwserv/beinghandler.cpp
index 1a1744cc..08847d7d 100644
--- a/src/net/tmwserv/beinghandler.cpp
+++ b/src/net/tmwserv/beinghandler.cpp
@@ -139,7 +139,7 @@ void BeingHandler::handleBeingEnterMessage(MessageIn &msg)
}
else
{
- being = beingManager->createBeing(id, type, 0);
+ being = beingManager->createBeing(id, Being::PLAYER, 0);
being->setName(name);
}
Player *p = static_cast< Player * >(being);
@@ -154,7 +154,8 @@ void BeingHandler::handleBeingEnterMessage(MessageIn &msg)
case OBJECT_NPC:
{
int subtype = msg.readInt16();
- being = beingManager->createBeing(id, type, subtype);
+ being = beingManager->createBeing(id, type == OBJECT_MONSTER ?
+ Being::MONSTER : Being::NPC, subtype);
std::string name = msg.readString();
if (name.length() > 0) being->setName(name);
} break;
diff --git a/src/net/tmwserv/partyhandler.cpp b/src/net/tmwserv/partyhandler.cpp
index dfbcea80..510eb77a 100644
--- a/src/net/tmwserv/partyhandler.cpp
+++ b/src/net/tmwserv/partyhandler.cpp
@@ -26,9 +26,10 @@
#include "net/messagein.h"
-#include "gui/chat.h"
#include "gui/partywindow.h"
+#include "gui/widgets/chattab.h"
+
#include "log.h"
#include "localplayer.h"
diff --git a/src/net/tmwserv/playerhandler.cpp b/src/net/tmwserv/playerhandler.cpp
index f02ed4c1..106894a1 100644
--- a/src/net/tmwserv/playerhandler.cpp
+++ b/src/net/tmwserv/playerhandler.cpp
@@ -85,9 +85,6 @@ namespace {
npcTextDialog->setVisible(false);
buyDialog->setVisible(false);
sellDialog->setVisible(false);
-#ifdef EATHENA_SUPPORT
- buySellDialog->setVisible(false);
-#endif
current_npc = 0;
}
} deathListener;
diff --git a/src/net/tmwserv/tradehandler.cpp b/src/net/tmwserv/tradehandler.cpp
index 85228355..8b3e06c6 100644
--- a/src/net/tmwserv/tradehandler.cpp
+++ b/src/net/tmwserv/tradehandler.cpp
@@ -30,10 +30,11 @@
#include "item.h"
#include "localplayer.h"
-#include "gui/chat.h"
#include "gui/confirm_dialog.h"
#include "gui/trade.h"
+#include "gui/widgets/chattab.h"
+
std::string tradePartnerName;
int tradePartnerID;