summaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/net')
-rw-r--r--src/net/ea/beinghandler.cpp23
-rw-r--r--src/net/ea/charserverhandler.cpp33
-rw-r--r--src/net/ea/chathandler.cpp2
-rw-r--r--src/net/ea/equipmenthandler.cpp193
-rw-r--r--src/net/ea/equipmenthandler.h6
-rw-r--r--src/net/ea/generalhandler.cpp42
-rw-r--r--src/net/ea/generalhandler.h2
-rw-r--r--src/net/ea/inventoryhandler.cpp45
-rw-r--r--src/net/ea/loginhandler.cpp22
-rw-r--r--src/net/ea/maphandler.cpp20
-rw-r--r--src/net/ea/network.cpp6
-rw-r--r--src/net/ea/partyhandler.cpp1
-rw-r--r--src/net/ea/playerhandler.cpp290
-rw-r--r--src/net/ea/playerhandler.h8
-rw-r--r--src/net/ea/protocol.h25
-rw-r--r--src/net/ea/specialhandler.cpp (renamed from src/net/ea/skillhandler.cpp)87
-rw-r--r--src/net/ea/specialhandler.h (renamed from src/net/ea/skillhandler.h)14
-rw-r--r--src/net/net.cpp8
-rw-r--r--src/net/net.h4
-rw-r--r--src/net/playerhandler.h8
-rw-r--r--src/net/specialhandler.h (renamed from src/net/skillhandler.h)16
-rw-r--r--src/net/tmwserv/beinghandler.cpp64
-rw-r--r--src/net/tmwserv/charserverhandler.cpp38
-rw-r--r--src/net/tmwserv/chathandler.cpp31
-rw-r--r--src/net/tmwserv/gameserver/player.cpp49
-rw-r--r--src/net/tmwserv/gameserver/player.h7
-rw-r--r--src/net/tmwserv/generalhandler.cpp12
-rw-r--r--src/net/tmwserv/loginhandler.cpp42
-rw-r--r--src/net/tmwserv/partyhandler.cpp7
-rw-r--r--src/net/tmwserv/playerhandler.cpp57
-rw-r--r--src/net/tmwserv/playerhandler.h8
-rw-r--r--src/net/tmwserv/protocol.h4
-rw-r--r--src/net/tmwserv/specialhandler.cpp (renamed from src/net/tmwserv/skillhandler.cpp)27
-rw-r--r--src/net/tmwserv/specialhandler.h (renamed from src/net/tmwserv/skillhandler.h)14
-rw-r--r--src/net/tmwserv/tradehandler.cpp12
35 files changed, 653 insertions, 574 deletions
diff --git a/src/net/ea/beinghandler.cpp b/src/net/ea/beinghandler.cpp
index f149f15f..1d780a60 100644
--- a/src/net/ea/beinghandler.cpp
+++ b/src/net/ea/beinghandler.cpp
@@ -194,14 +194,15 @@ void BeingHandler::handleMessage(MessageIn &msg)
Uint16 srcX, srcY, dstX, dstY;
msg.readCoordinatePair(srcX, srcY, dstX, dstY);
dstBeing->setAction(Being::STAND);
- dstBeing->mX = srcX;
- dstBeing->mY = srcY;
+ dstBeing->setTileCoords(srcX, srcY);
dstBeing->setDestination(dstX, dstY);
}
else
{
Uint8 dir;
- msg.readCoordinates(dstBeing->mX, dstBeing->mY, dir);
+ Uint16 x, y;
+ msg.readCoordinates(x, y, dir);
+ dstBeing->setTileCoords(x, y);
dstBeing->setDirection(dir);
}
@@ -234,8 +235,7 @@ void BeingHandler::handleMessage(MessageIn &msg)
if (dstBeing) {
dstBeing->setAction(Being::STAND);
- dstBeing->mX = srcX;
- dstBeing->mY = srcY;
+ dstBeing->setTileCoords(srcX, srcY);
dstBeing->setDestination(dstX, dstY);
}
@@ -515,14 +515,15 @@ void BeingHandler::handleMessage(MessageIn &msg)
{
Uint16 srcX, srcY, dstX, dstY;
msg.readCoordinatePair(srcX, srcY, dstX, dstY);
- dstBeing->mX = srcX;
- dstBeing->mY = srcY;
+ dstBeing->setTileCoords(srcX, srcY);
dstBeing->setDestination(dstX, dstY);
}
else
{
Uint8 dir;
- msg.readCoordinates(dstBeing->mX, dstBeing->mY, dir);
+ Uint16 x, y;
+ msg.readCoordinates(x, y, dir);
+ dstBeing->setTileCoords(x, y);
dstBeing->setDirection(dir);
}
@@ -577,8 +578,10 @@ void BeingHandler::handleMessage(MessageIn &msg)
if (mSync || id != player_node->getId()) {
dstBeing = beingManager->findBeing(id);
if (dstBeing) {
- dstBeing->mX = msg.readInt16();
- dstBeing->mY = msg.readInt16();
+ Uint16 x, y;
+ x = msg.readInt16();
+ y = msg.readInt16();
+ dstBeing->setTileCoords(x, y);
if (dstBeing->mAction == Being::WALK) {
dstBeing->mFrame = 0;
dstBeing->setAction(Being::STAND);
diff --git a/src/net/ea/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp
index 77bfaa50..6fae1864 100644
--- a/src/net/ea/charserverhandler.cpp
+++ b/src/net/ea/charserverhandler.cpp
@@ -61,18 +61,16 @@ CharServerHandler::CharServerHandler():
void CharServerHandler::handleMessage(MessageIn &msg)
{
- int slot, flags;
+ int slot;
LocalPlayer *tempPlayer;
logger->log("CharServerHandler: Packet ID: %x, Length: %d",
msg.getId(), msg.getLength());
switch (msg.getId())
{
- case 0x006b:
+ case SMSG_CHAR_LOGIN:
msg.skip(2); // Length word
- flags = msg.readInt32(); // Aethyra extensions flags
- logger->log("Server flags are: %x", flags);
- msg.skip(16); // Unused
+ msg.skip(20); // Unused
// Derive number of characters from message length
n_character = (msg.getLength() - 24) / 106;
@@ -92,13 +90,13 @@ void CharServerHandler::handleMessage(MessageIn &msg)
case SMSG_CHAR_LOGIN_ERROR:
switch (msg.readInt8()) {
case 0:
- errorMessage = _("Access denied");
+ errorMessage = _("Access denied.");
break;
case 1:
- errorMessage = _("Cannot use this ID");
+ errorMessage = _("Cannot use this ID.");
break;
default:
- errorMessage = _("Unknown failure to select character");
+ errorMessage = _("Unknown failure to select character.");
break;
}
mCharInfo->unlock();
@@ -169,14 +167,15 @@ void CharServerHandler::handleMessage(MessageIn &msg)
LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
{
- LocalPlayer *tempPlayer = new LocalPlayer(mLoginData->account_ID, 0, NULL);
+ LocalPlayer *tempPlayer = new LocalPlayer(msg.readInt32(), 0, NULL);
tempPlayer->setGender(mLoginData->sex);
- tempPlayer->mCharId = msg.readInt32();
- tempPlayer->setXp(msg.readInt32());
+ tempPlayer->setExp(msg.readInt32());
tempPlayer->setMoney(msg.readInt32());
- tempPlayer->mJobXp = msg.readInt32();
- tempPlayer->mJobLevel = msg.readInt32();
+ tempPlayer->setExperience(JOB, msg.readInt32(), 1);
+ int temp = msg.readInt32();
+ tempPlayer->setAttributeBase(JOB, temp);
+ tempPlayer->setAttributeEffective(JOB, temp);
tempPlayer->setSprite(Being::SHOE_SPRITE, msg.readInt16());
tempPlayer->setSprite(Being::GLOVES_SPRITE, msg.readInt16());
tempPlayer->setSprite(Being::CAPE_SPRITE, msg.readInt16());
@@ -187,8 +186,8 @@ LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
msg.skip(2); // unknown
tempPlayer->setHp(msg.readInt16());
tempPlayer->setMaxHp(msg.readInt16());
- tempPlayer->mMp = msg.readInt16();
- tempPlayer->mMaxMp = msg.readInt16();
+ tempPlayer->setMP(msg.readInt16());
+ tempPlayer->setMaxMP(msg.readInt16());
msg.readInt16(); // speed
msg.readInt16(); // class
int hairStyle = msg.readInt16();
@@ -205,7 +204,7 @@ LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
tempPlayer->setSprite(Being::MISC2_SPRITE, msg.readInt16());
tempPlayer->setName(msg.readString(24));
for (int i = 0; i < 6; i++) {
- tempPlayer->mAttr[i] = msg.readInt8();
+ tempPlayer->setAttributeBase(i + STR, msg.readInt8());
}
slot = msg.readInt8(); // character slot
msg.readInt8(); // unknown
@@ -272,7 +271,7 @@ void CharServerHandler::newCharacter(const std::string &name, int slot,
void CharServerHandler::deleteCharacter(int slot, LocalPlayer* character)
{
MessageOut outMsg(CMSG_CHAR_DELETE);
- outMsg.writeInt32(character->mCharId);
+ outMsg.writeInt32(character->getId());
outMsg.writeString("a@a.com", 40);
}
diff --git a/src/net/ea/chathandler.cpp b/src/net/ea/chathandler.cpp
index 49f83e67..65f1db3c 100644
--- a/src/net/ea/chathandler.cpp
+++ b/src/net/ea/chathandler.cpp
@@ -166,7 +166,7 @@ void ChatHandler::handleMessage(MessageIn &msg)
case SMSG_MVP:
// Display MVP player
msg.readInt32(); // id
- localChatTab->chatLog("MVP player", BY_SERVER);
+ localChatTab->chatLog(_("MVP player."), BY_SERVER);
break;
}
}
diff --git a/src/net/ea/equipmenthandler.cpp b/src/net/ea/equipmenthandler.cpp
index 0153b5da..3520bca5 100644
--- a/src/net/ea/equipmenthandler.cpp
+++ b/src/net/ea/equipmenthandler.cpp
@@ -35,10 +35,112 @@
#include "utils/gettext.h"
+const Equipment::EquipmentSlots EQUIP_POINTS[Equipment::EQUIP_VECTOREND] = {
+ Equipment::EQUIP_LEGS_SLOT,
+ Equipment::EQUIP_FIGHT1_SLOT,
+ Equipment::EQUIP_GLOVES_SLOT,
+ Equipment::EQUIP_RING2_SLOT,
+ Equipment::EQUIP_RING1_SLOT,
+ Equipment::EQUIP_FIGHT2_SLOT,
+ Equipment::EQUIP_FEET_SLOT,
+ Equipment::EQUIP_NECK_SLOT,
+ Equipment::EQUIP_HEAD_SLOT,
+ Equipment::EQUIP_TORSO_SLOT,
+ Equipment::EQUIP_PROJECTILE_SLOT};
+
+Item *equips[Equipment::EQUIP_VECTOREND];
+
namespace EAthena {
enum { debugEquipment = 1 };
+void setEquipment(int eAthenaSlot, int index, bool equiped)
+{
+ if (!eAthenaSlot)
+ return;
+
+ Item *item = player_node->getInventory()->getItem(index);
+
+ if (!item)
+ return;
+
+ int position = 0;
+
+ if (eAthenaSlot & 0x8000) { // Arrows
+ position = Equipment::EQUIP_PROJECTILE_SLOT;
+ }
+ else
+ {
+ /*
+ * An item may occupy more than 1 slot. If so, it's
+ * only shown as equipped on the *first* slot.
+ */
+ int mask = 1;
+ while (!(eAthenaSlot & mask))
+ {
+ mask <<= 1;
+ position++;
+ }
+
+ position = EQUIP_POINTS[position];
+ }
+
+ if (equips[position])
+ equips[position]->setEquipped(false);
+
+ if (equiped && item)
+ {
+ equips[position] = item;
+ item->setEquipped(true);
+ player_node->mEquipment->setEquipment(position, item->getId(), item->getQuantity());
+
+ if (debugEquipment)
+ {
+ logger->log("Equipping: %i %i at position %i",
+ index, eAthenaSlot, position);
+ }
+ }
+ else
+ {
+ equips[position] = NULL;
+ player_node->mEquipment->setEquipment(position, -1);
+
+ if (debugEquipment)
+ {
+ logger->log("Unequipping: %i %i at position %i",
+ index, eAthenaSlot, position);
+ }
+ }
+}
+
+void clearEquipment()
+{
+ for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
+ {
+ if (equips[i])
+ {
+ equips[i]->setEquipped(false);
+ player_node->mEquipment->setEquipment(i, -1);
+ }
+
+ equips[i] = NULL;
+ }
+}
+
+Item *getRealEquipedItem(const Item *equipped)
+{
+ if (!equipped)
+ return NULL;
+
+ for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
+ {
+ if (equips[i] && equipped->getId() == equips[i]->getId())
+ return equips[i];
+ }
+
+ return NULL;
+}
+
EquipmentHandler::EquipmentHandler()
{
static const Uint16 _messages[] = {
@@ -50,6 +152,7 @@ EquipmentHandler::EquipmentHandler()
0
};
handledMessages = _messages;
+ memset(equips, 0, sizeof(equips));
}
void EquipmentHandler::handleMessage(MessageIn &msg)
@@ -57,8 +160,6 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
int itemCount;
int index, equipPoint, itemId;
int type;
- int mask, position;
- Item *item;
Inventory *inventory = player_node->getInventory();
switch (msg.getId())
@@ -79,25 +180,9 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
msg.readInt8(); // refine
msg.skip(8); // card
- if (debugEquipment)
- {
- logger->log("Index: %d, ID: %d", index, itemId);
- }
-
inventory->setItem(index, itemId, 1, true);
- if (equipPoint)
- {
- mask = 1;
- position = 0;
- while (!(equipPoint & mask))
- {
- mask <<= 1;
- position++;
- }
- item = inventory->getItem(index);
- player_node->mEquipment->setEquipment(position, index);
- }
+ setEquipment(equipPoint, index, true);
}
break;
@@ -112,35 +197,7 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
break;
}
- // No point in searching when no point given
- if (!equipPoint)
- break;
-
- /*
- * An item may occupy more than 1 slot. If so, it's
- * only shown as equipped on the *first* slot.
- */
- mask = 1;
- position = 0;
- while (!(equipPoint & mask)) {
- mask <<= 1;
- position++;
- }
-
- if (debugEquipment)
- {
- logger->log("Equipping: %i %i %i at position %i",
- index, equipPoint, type, position);
- }
-
- item = inventory->getItem(player_node->mEquipment->getEquipment(position));
-
- // Unequip any existing equipped item in this position
- if (item)
- item->setEquipped(false);
-
- item = inventory->getItem(index);
- player_node->mEquipment->setEquipment(position, index);
+ setEquipment(equipPoint, index, true);
break;
case SMSG_PLAYER_UNEQUIP:
@@ -153,36 +210,7 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
break;
}
- if (!equipPoint) {
- // No point given, no point in searching
- break;
- }
-
- mask = 1;
- position = 0;
- while (!(equipPoint & mask)) {
- mask <<= 1;
- position++;
- }
-
- item = inventory->getItem(index);
- if (!item)
- break;
-
- item->setEquipped(false);
-
- if (equipPoint & 0x8000) { // Arrows
- player_node->mEquipment->setArrows(-1);
- }
- else {
- player_node->mEquipment->removeEquipment(position);
- }
-
- if (debugEquipment)
- {
- logger->log("Unequipping: %i %i(%i) %i",
- index, equipPoint, type, position);
- }
+ setEquipment(equipPoint, index, false);
break;
case SMSG_PLAYER_ATTACK_RANGE:
@@ -197,13 +225,8 @@ void EquipmentHandler::handleMessage(MessageIn &msg)
index -= INVENTORY_OFFSET;
- item = inventory->getItem(index);
-
- if (item) {
- item->setEquipped(true);
- player_node->mEquipment->setArrows(index);
- logger->log("Arrows equipped: %i", index);
- }
+ logger->log("Arrows equipped: %i", index);
+ setEquipment(0x8000, index, true);
break;
}
}
diff --git a/src/net/ea/equipmenthandler.h b/src/net/ea/equipmenthandler.h
index 852be3c9..47c2f803 100644
--- a/src/net/ea/equipmenthandler.h
+++ b/src/net/ea/equipmenthandler.h
@@ -24,8 +24,14 @@
#include "net/messagehandler.h"
+class Item;
+
namespace EAthena {
+void setEquipment(int eAthenaSlot, int index, bool equiped);
+void clearEquipment();
+Item *getRealEquipedItem(const Item *equipped);
+
class EquipmentHandler : public MessageHandler
{
public:
diff --git a/src/net/ea/generalhandler.cpp b/src/net/ea/generalhandler.cpp
index 404bff69..1d500d62 100644
--- a/src/net/ea/generalhandler.cpp
+++ b/src/net/ea/generalhandler.cpp
@@ -19,10 +19,12 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "gui/inventorywindow.h"
-
#include "net/ea/generalhandler.h"
+#include "gui/inventorywindow.h"
+#include "gui/skilldialog.h"
+#include "gui/statuswindow.h"
+
#include "net/ea/network.h"
#include "net/ea/protocol.h"
@@ -41,7 +43,7 @@
#include "net/ea/playerhandler.h"
#include "net/ea/partyhandler.h"
#include "net/ea/tradehandler.h"
-#include "net/ea/skillhandler.h"
+#include "net/ea/specialhandler.h"
#include "net/ea/gui/partytab.h"
@@ -77,7 +79,7 @@ GeneralHandler::GeneralHandler():
mNpcHandler(new NpcHandler),
mPartyHandler(new PartyHandler),
mPlayerHandler(new PlayerHandler),
- mSkillHandler(new SkillHandler),
+ mSpecialHandler(new SpecialHandler),
mTradeHandler(new TradeHandler)
{
static const Uint16 _messages[] = {
@@ -115,26 +117,26 @@ void GeneralHandler::handleMessage(MessageIn &msg)
switch (code) {
case 0:
- errorMessage = _("Authentication failed");
+ errorMessage = _("Authentication failed.");
break;
case 1:
- errorMessage = _("No servers available");
+ errorMessage = _("No servers available.");
break;
case 2:
if (state == STATE_GAME)
errorMessage = _("Someone else is trying to use this "
- "account");
+ "account.");
else
- errorMessage = _("This account is already logged in");
+ errorMessage = _("This account is already logged in.");
break;
case 3:
- errorMessage = _("Speed hack detected");
+ errorMessage = _("Speed hack detected.");
break;
case 8:
- errorMessage = _("Duplicated login");
+ errorMessage = _("Duplicated login.");
break;
default:
- errorMessage = _("Unknown connection error");
+ errorMessage = _("Unknown connection error.");
break;
}
state = STATE_ERROR;
@@ -157,7 +159,7 @@ void GeneralHandler::load()
mNetwork->registerHandler(mMapHandler.get());
mNetwork->registerHandler(mNpcHandler.get());
mNetwork->registerHandler(mPlayerHandler.get());
- mNetwork->registerHandler(mSkillHandler.get());
+ mNetwork->registerHandler(mSpecialHandler.get());
mNetwork->registerHandler(mTradeHandler.get());
mNetwork->registerHandler(mPartyHandler.get());
}
@@ -201,6 +203,22 @@ void GeneralHandler::guiWindowsLoaded()
{
partyTab = new PartyTab;
inventoryWindow->setSplitAllowed(false);
+ skillDialog->loadSkills("ea-skills.xml");
+
+ statusWindow->addAttribute(STR, _("Strength"), true);
+ statusWindow->addAttribute(AGI, _("Agility"), true);
+ statusWindow->addAttribute(VIT, _("Vitality"), true);
+ statusWindow->addAttribute(INT, _("Intelligence"), true);
+ statusWindow->addAttribute(DEX, _("Dexterity"), true);
+ statusWindow->addAttribute(LUK, _("Luck"), true);
+
+ statusWindow->addAttribute(ATK, _("Attack"), false);
+ statusWindow->addAttribute(DEF, _("Defense"), false);
+ statusWindow->addAttribute(MATK, _("M.Attack"), false);
+ statusWindow->addAttribute(MDEF, _("M.Defense"), false);
+ statusWindow->addAttribute(HIT, _("% Accuracy"), false);
+ statusWindow->addAttribute(FLEE, _("% Evade"), false);
+ statusWindow->addAttribute(CRIT, _("% Critical"), false);
}
void GeneralHandler::guiWindowsUnloaded()
diff --git a/src/net/ea/generalhandler.h b/src/net/ea/generalhandler.h
index ebbc84ca..98364e5d 100644
--- a/src/net/ea/generalhandler.h
+++ b/src/net/ea/generalhandler.h
@@ -66,7 +66,7 @@ class GeneralHandler : public MessageHandler, public Net::GeneralHandler
MessageHandlerPtr mNpcHandler;
MessageHandlerPtr mPartyHandler;
MessageHandlerPtr mPlayerHandler;
- MessageHandlerPtr mSkillHandler;
+ MessageHandlerPtr mSpecialHandler;
MessageHandlerPtr mTradeHandler;
};
diff --git a/src/net/ea/inventoryhandler.cpp b/src/net/ea/inventoryhandler.cpp
index c1f04661..b6e91609 100644
--- a/src/net/ea/inventoryhandler.cpp
+++ b/src/net/ea/inventoryhandler.cpp
@@ -21,6 +21,7 @@
#include "net/ea/inventoryhandler.h"
+#include "net/ea/equipmenthandler.h"
#include "net/ea/protocol.h"
#include "net/messagein.h"
@@ -86,6 +87,7 @@ void InventoryHandler::handleMessage(MessageIn &msg)
if (msg.getId() == SMSG_PLAYER_INVENTORY)
{
// Clear inventory - this will be a complete refresh
+ clearEquipment();
inventory->clear();
}
else
@@ -178,42 +180,25 @@ void InventoryHandler::handleMessage(MessageIn &msg)
equipType = msg.readInt16();
itemType = msg.readInt8();
- if (msg.readInt8() > 0)
- {
- if (config.getValue("showpickupchat", 1))
- {
- localChatTab->chatLog(_("Unable to pick up item."),
- BY_SERVER);
- }
- }
- else
{
const ItemInfo &itemInfo = ItemDB::get(itemId);
- const std::string amountStr =
- // TRANSLATORS: Used as in "You picked up a ...", when
- // picking up only one item.
- (amount > 1) ? toString(amount) : _("a");
- if (config.getValue("showpickupchat", 1))
+ if (msg.readInt8() > 0)
{
- localChatTab->chatLog(strprintf(_("You picked up %s [@@%d|%s@@]."),
- amountStr.c_str(), itemInfo.getId(), itemInfo.getName().c_str()),
- BY_SERVER);
+ player_node->pickedUp(itemInfo, 0);
}
-
- if (config.getValue("showpickupparticle", 0))
+ else
{
- player_node->pickedUp(itemInfo.getName());
- }
+ player_node->pickedUp(itemInfo, amount);
+
+ Item *item = inventory->getItem(index);
+
+ if (item && item->getId() == itemId)
+ amount += inventory->getItem(index)->getQuantity();
- if (Item *item = inventory->getItem(index)) {
- item->setId(itemId);
- item->increaseQuantity(amount);
- } else {
inventory->setItem(index, itemId, amount, equipType != 0);
}
- }
- break;
+ } break;
case SMSG_PLAYER_INVENTORY_REMOVE:
index = msg.readInt16() - INVENTORY_OFFSET;
@@ -319,11 +304,13 @@ void InventoryHandler::equipItem(const Item *item)
void InventoryHandler::unequipItem(const Item *item)
{
- if (!item)
+ const Item *real_item = item->isEquipped() ? item : getRealEquipedItem(item);
+
+ if (!real_item)
return;
MessageOut outMsg(CMSG_PLAYER_UNEQUIP);
- outMsg.writeInt16(item->getInvIndex() + INVENTORY_OFFSET);
+ outMsg.writeInt16(real_item->getInvIndex() + INVENTORY_OFFSET);
}
void InventoryHandler::useItem(const Item *item)
diff --git a/src/net/ea/loginhandler.cpp b/src/net/ea/loginhandler.cpp
index 54e31cf3..8e7187c0 100644
--- a/src/net/ea/loginhandler.cpp
+++ b/src/net/ea/loginhandler.cpp
@@ -76,13 +76,13 @@ void LoginHandler::handleMessage(MessageIn &msg)
errorMessage = _("Account was not found. Please re-login.");
break;
case 2:
- errorMessage = _("Old password incorrect");
+ errorMessage = _("Old password incorrect.");
break;
case 3:
- errorMessage = _("New password too short");
+ errorMessage = _("New password too short.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_ACCOUNTCHANGE_ERROR;
@@ -96,7 +96,7 @@ void LoginHandler::handleMessage(MessageIn &msg)
len = msg.readInt16() - 4;
mUpdateHost = msg.readString(len);
- logger->log("Received update host \"%s\" from login server",
+ logger->log("Received update host \"%s\" from login server.",
mUpdateHost.c_str());
break;
@@ -139,21 +139,21 @@ void LoginHandler::handleMessage(MessageIn &msg)
switch (code) {
case 0:
- errorMessage = _("Unregistered ID");
+ errorMessage = _("Unregistered ID.");
break;
case 1:
- errorMessage = _("Wrong password");
+ errorMessage = _("Wrong password.");
break;
case 2:
- errorMessage = _("Account expired");
+ errorMessage = _("Account expired.");
break;
case 3:
- errorMessage = _("Rejected from server");
+ errorMessage = _("Rejected from server.");
break;
case 4:
errorMessage = _("You have been permanently banned from "
- "the game. Please contact the GM Team.");
+ "the game. Please contact the GM team.");
break;
case 6:
errorMessage = strprintf(_("You have been temporarily "
@@ -163,10 +163,10 @@ void LoginHandler::handleMessage(MessageIn &msg)
msg.readString(20).c_str());
break;
case 9:
- errorMessage = _("This user name is already taken");
+ errorMessage = _("This user name is already taken.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_ERROR;
diff --git a/src/net/ea/maphandler.cpp b/src/net/ea/maphandler.cpp
index 6f8a9827..c3c9437c 100644
--- a/src/net/ea/maphandler.cpp
+++ b/src/net/ea/maphandler.cpp
@@ -61,14 +61,17 @@ void MapHandler::handleMessage(MessageIn &msg)
switch (msg.getId())
{
case SMSG_MAP_LOGIN_SUCCESS:
+ {
+ Uint16 x, y;
msg.readInt32(); // server tick
- msg.readCoordinates(player_node->mX, player_node->mY, direction);
+ msg.readCoordinates(x, y, direction);
msg.skip(2); // unknown
logger->log("Protocol: Player start position: (%d, %d), Direction: %d",
- player_node->mX, player_node->mY, direction);
+ x, y, direction);
state = STATE_GAME;
+ player_node->setTileCoords(x, y);
game = new Game;
- break;
+ } break;
case SMSG_SERVER_PING:
// We ignore this for now
@@ -76,22 +79,27 @@ void MapHandler::handleMessage(MessageIn &msg)
break;
case SMSG_WHO_ANSWER:
- localChatTab->chatLog("Online users: " + toString(msg.readInt32()),
- BY_SERVER);
+ localChatTab->chatLog(strprintf(_("Online users: %d"),
+ msg.readInt32()), BY_SERVER);
break;
}
}
+#include <fstream>
+
void MapHandler::connect(LoginData *loginData)
{
// Send login infos
MessageOut outMsg(CMSG_MAP_SERVER_CONNECT);
outMsg.writeInt32(loginData->account_ID);
- outMsg.writeInt32(player_node->mCharId);
+ outMsg.writeInt32(player_node->getId());
outMsg.writeInt32(loginData->session_ID1);
outMsg.writeInt32(loginData->session_ID2);
outMsg.writeInt8((loginData->sex == GENDER_MALE) ? 1 : 0);
+ // Change the player's ID to the account ID to match what eAthena uses
+ player_node->setId(loginData->account_ID);
+
// We get 4 useless bytes before the real answer comes in (what are these?)
mNetwork->skip(4);
}
diff --git a/src/net/ea/network.cpp b/src/net/ea/network.cpp
index 956d7877..c6bc712c 100644
--- a/src/net/ea/network.cpp
+++ b/src/net/ea/network.cpp
@@ -318,9 +318,9 @@ bool Network::realConnect()
if (SDLNet_ResolveHost(&ipAddress, mAddress.c_str(), mPort) == -1)
{
- std::string error = "Unable to resolve host \"" + mAddress + "\"";
- setError(error);
- logger->log("SDLNet_ResolveHost: %s", error.c_str());
+ std::string errorMessage = "Unable to resolve host \"" + mAddress + "\"";
+ setError(errorMessage);
+ logger->log("SDLNet_ResolveHost: %s", errorMessage.c_str());
return false;
}
diff --git a/src/net/ea/partyhandler.cpp b/src/net/ea/partyhandler.cpp
index 5e7f43c4..a4a84b07 100644
--- a/src/net/ea/partyhandler.cpp
+++ b/src/net/ea/partyhandler.cpp
@@ -230,6 +230,7 @@ void PartyHandler::handleMessage(MessageIn &msg)
if (id == player_node->getId())
{
partyWindow->clearMembers();
+ partyWindow->clearPartyName();
partyWindow->setVisible(false);
partyTab->chatLog(_("You have left the party."), BY_SERVER);
}
diff --git a/src/net/ea/playerhandler.cpp b/src/net/ea/playerhandler.cpp
index 58167339..3e379d82 100644
--- a/src/net/ea/playerhandler.cpp
+++ b/src/net/ea/playerhandler.cpp
@@ -37,7 +37,7 @@
#include "gui/gui.h"
#include "gui/okdialog.h"
#include "gui/sell.h"
-#include "gui/skill.h"
+#include "gui/statuswindow.h"
#include "gui/storagewindow.h"
#include "gui/viewport.h"
@@ -54,6 +54,9 @@ OkDialog *deathNotice = NULL;
// everything beyond will reset the port hard.
static const int MAP_TELEPORT_SCROLL_DISTANCE = 8;
+#define ATTR_BONUS(atr) \
+(player_node->getAttributeEffective(atr) - player_node->getAttributeBase(atr))
+
// TODO Move somewhere else
namespace {
@@ -197,17 +200,16 @@ void PlayerHandler::handleMessage(MessageIn &msg)
/* Scroll if neccessary */
if (!nearby
- || (abs(x - player_node->mX) > MAP_TELEPORT_SCROLL_DISTANCE)
- || (abs(y - player_node->mY) > MAP_TELEPORT_SCROLL_DISTANCE))
+ || (abs(x - player_node->getTileX()) > MAP_TELEPORT_SCROLL_DISTANCE)
+ || (abs(y - player_node->getTileY()) > MAP_TELEPORT_SCROLL_DISTANCE))
{
- scrollOffsetX = (x - player_node->mX) * 32;
- scrollOffsetY = (y - player_node->mY) * 32;
+ scrollOffsetX = (x - player_node->getTileX()) * 32;
+ scrollOffsetY = (y - player_node->getTileY()) * 32;
}
player_node->setAction(Being::STAND);
player_node->mFrame = 0;
- player_node->mX = x;
- player_node->mY = y;
+ player_node->setTileCoords(x, y);
logger->log("Adjust scrolling by %d:%d", (int) scrollOffsetX,
(int) scrollOffsetY);
@@ -224,18 +226,14 @@ void PlayerHandler::handleMessage(MessageIn &msg)
switch (type)
{
case 0x0000: player_node->setWalkSpeed(value); break;
+ case 0x0004: break; // manner
case 0x0005: player_node->setHp(value); break;
case 0x0006: player_node->setMaxHp(value); break;
- case 0x0007: player_node->mMp = value; break;
- case 0x0008: player_node->mMaxMp = value; break;
- case 0x0009:
- player_node->mStatsPointsToAttribute = value;
- break;
+ case 0x0007: player_node->setMP(value); break;
+ case 0x0008: player_node->setMaxMP(value); break;
+ case 0x0009: player_node->setCharacterPoints(value); break;
case 0x000b: player_node->setLevel(value); break;
- case 0x000c:
- player_node->mSkillPoint = value;
- skillDialog->update();
- break;
+ case 0x000c: player_node->setSkillPoints(value); break;
case 0x0018:
if (value >= player_node->getMaxWeight() / 2 &&
player_node->getTotalWeight() <
@@ -251,15 +249,48 @@ void PlayerHandler::handleMessage(MessageIn &msg)
player_node->setTotalWeight(value);
break;
case 0x0019: player_node->setMaxWeight(value); break;
- case 0x0029: player_node->ATK = value; break;
- case 0x002b: player_node->MATK = value; break;
- case 0x002d: player_node->DEF = value; break;
- case 0x002e: player_node->DEF_BONUS = value; break;
- case 0x002f: player_node->MDEF = value; break;
- case 0x0031: player_node->HIT = value; break;
- case 0x0032: player_node->FLEE = value; break;
+
+ case 0x0029: player_node->setAttributeEffective(ATK, value
+ + ATTR_BONUS(ATK));
+ player_node->setAttributeBase(ATK, value);
+ break;
+ case 0x002a: value += player_node->getAttributeBase(ATK);
+ player_node->setAttributeEffective(ATK, value); break;
+
+ case 0x002b: player_node->setAttributeEffective(MATK, value
+ + ATTR_BONUS(MATK));
+ player_node->setAttributeBase(MATK, value);
+ statusWindow->update(StatusWindow::MP); break;
+ case 0x002c: value += player_node->getAttributeBase(MATK);
+ player_node->setAttributeEffective(MATK, value);
+ statusWindow->update(StatusWindow::MP); break;
+ case 0x002d: player_node->setAttributeEffective(DEF, value
+ + ATTR_BONUS(DEF));
+ player_node->setAttributeBase(DEF, value); break;
+ case 0x002e: value += player_node->getAttributeBase(DEF);
+ player_node->setAttributeEffective(DEF, value); break;
+
+ case 0x002f: player_node->setAttributeEffective(MDEF, value
+ + ATTR_BONUS(MDEF));
+ player_node->setAttributeBase(MDEF, value); break;
+ case 0x0030: value += player_node->getAttributeBase(MDEF);
+ player_node->setAttributeEffective(MDEF, value); break;
+
+ case 0x0031: player_node->setAttributeBase(HIT, value);
+ player_node->setAttributeEffective(HIT, value); break;
+
+ case 0x0032: player_node->setAttributeEffective(FLEE, value
+ + ATTR_BONUS(FLEE));
+ player_node->setAttributeBase(FLEE, value); break;
+ case 0x0033: value += player_node->getAttributeBase(FLEE);
+ player_node->setAttributeEffective(FLEE, value); break;
+
+ case 0x0034: player_node->setAttributeBase(CRIT, value);
+ player_node->setAttributeEffective(CRIT, value); break;
+
case 0x0035: player_node->mAttackSpeed = value; break;
- case 0x0037: player_node->mJobLevel = value; break;
+ case 0x0037: player_node->setAttributeBase(JOB, value);
+ player_node->setAttributeEffective(JOB, value); break;
case 500: player_node->setGMLevel(value); break;
}
@@ -276,54 +307,45 @@ void PlayerHandler::handleMessage(MessageIn &msg)
case SMSG_PLAYER_STAT_UPDATE_2:
switch (msg.readInt16()) {
case 0x0001:
- player_node->setXp(msg.readInt32());
+ player_node->setExp(msg.readInt32());
break;
case 0x0002:
- player_node->mJobXp = msg.readInt32();
+ player_node->setExperience(JOB, msg.readInt32(),
+ player_node->getExperience(JOB).second);
break;
case 0x0014: {
int curGp = player_node->getMoney();
player_node->setMoney(msg.readInt32());
if (player_node->getMoney() > curGp)
- localChatTab->chatLog(_("You picked up ") +
+ localChatTab->chatLog(strprintf(_("You picked up "
+ "%s."),
Units::formatCurrency(player_node->getMoney()
- - curGp), BY_SERVER);
+ - curGp).c_str()), BY_SERVER);
}
break;
case 0x0016:
- player_node->mXpForNextLevel = msg.readInt32();
+ player_node->setExpNeeded(msg.readInt32());
break;
case 0x0017:
- player_node->mJobXpForNextLevel = msg.readInt32();
+ player_node->setExperience(JOB,
+ player_node->getExperience(JOB).first,
+ msg.readInt32());
break;
}
break;
- case SMSG_PLAYER_STAT_UPDATE_3:
+ case SMSG_PLAYER_STAT_UPDATE_3: // Update a base attribute
{
int type = msg.readInt32();
int base = msg.readInt32();
int bonus = msg.readInt32();
- int total = base + bonus;
- switch (type) {
- case 0x000d: player_node->mAttr[LocalPlayer::STR] = total;
- break;
- case 0x000e: player_node->mAttr[LocalPlayer::AGI] = total;
- break;
- case 0x000f: player_node->mAttr[LocalPlayer::VIT] = total;
- break;
- case 0x0010: player_node->mAttr[LocalPlayer::INT] = total;
- break;
- case 0x0011: player_node->mAttr[LocalPlayer::DEX] = total;
- break;
- case 0x0012: player_node->mAttr[LocalPlayer::LUK] = total;
- break;
- }
+ player_node->setAttributeBase(type, base);
+ player_node->setAttributeEffective(type, base + bonus);
}
break;
- case SMSG_PLAYER_STAT_UPDATE_4:
+ case SMSG_PLAYER_STAT_UPDATE_4: // Attribute increase ack
{
int type = msg.readInt16();
int fail = msg.readInt8();
@@ -332,72 +354,105 @@ void PlayerHandler::handleMessage(MessageIn &msg)
if (fail != 1)
break;
- switch (type) {
- case 0x000d: player_node->mAttr[LocalPlayer::STR] = value;
- break;
- case 0x000e: player_node->mAttr[LocalPlayer::AGI] = value;
- break;
- case 0x000f: player_node->mAttr[LocalPlayer::VIT] = value;
- break;
- case 0x0010: player_node->mAttr[LocalPlayer::INT] = value;
- break;
- case 0x0011: player_node->mAttr[LocalPlayer::DEX] = value;
- break;
- case 0x0012: player_node->mAttr[LocalPlayer::LUK] = value;
- break;
- }
+ int bonus = ATTR_BONUS(type);
+
+ player_node->setAttributeBase(type, value);
+ player_node->setAttributeEffective(type, value + bonus);
}
break;
// Updates stats and status points
case SMSG_PLAYER_STAT_UPDATE_5:
- player_node->mStatsPointsToAttribute = msg.readInt16();
- player_node->mAttr[LocalPlayer::STR] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::STR] = msg.readInt8();
- player_node->mAttr[LocalPlayer::AGI] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::AGI] = msg.readInt8();
- player_node->mAttr[LocalPlayer::VIT] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::VIT] = msg.readInt8();
- player_node->mAttr[LocalPlayer::INT] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::INT] = msg.readInt8();
- player_node->mAttr[LocalPlayer::DEX] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::DEX] = msg.readInt8();
- player_node->mAttr[LocalPlayer::LUK] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::LUK] = msg.readInt8();
- player_node->ATK = msg.readInt16(); // ATK
- player_node->ATK_BONUS = msg.readInt16(); // ATK bonus
- player_node->MATK = msg.readInt16(); // MATK max
- player_node->MATK_BONUS = msg.readInt16(); // MATK min
- player_node->DEF = msg.readInt16(); // DEF
- player_node->DEF_BONUS = msg.readInt16(); // DEF bonus
- player_node->MDEF = msg.readInt16(); // MDEF
- player_node->MDEF_BONUS = msg.readInt16(); // MDEF bonus
- player_node->HIT = msg.readInt16(); // HIT
- player_node->FLEE = msg.readInt16(); // FLEE
- player_node->FLEE_BONUS = msg.readInt16(); // FLEE bonus
- msg.readInt16(); // critical
- msg.readInt16(); // unknown
+ player_node->setCharacterPoints(msg.readInt16());
+
+ {
+ int val = msg.readInt8();
+ player_node->setAttributeEffective(STR, val + ATTR_BONUS(STR));
+ player_node->setAttributeBase(STR, val);
+ statusWindow->setPointsNeeded(STR, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(AGI, val + ATTR_BONUS(AGI));
+ player_node->setAttributeBase(AGI, val);
+ statusWindow->setPointsNeeded(AGI, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(VIT, val + ATTR_BONUS(VIT));
+ player_node->setAttributeBase(VIT, val);
+ statusWindow->setPointsNeeded(VIT, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(INT, val + ATTR_BONUS(INT));
+ player_node->setAttributeBase(INT, val);
+ statusWindow->setPointsNeeded(INT, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(DEX, val + ATTR_BONUS(DEX));
+ player_node->setAttributeBase(DEX, val);
+ statusWindow->setPointsNeeded(DEX, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(LUK, val + ATTR_BONUS(LUK));
+ player_node->setAttributeBase(LUK, val);
+ statusWindow->setPointsNeeded(LUK, msg.readInt8());
+
+ val = msg.readInt16(); // ATK
+ player_node->setAttributeBase(ATK, val);
+ val += msg.readInt16(); // ATK bonus
+ player_node->setAttributeEffective(ATK, val);
+
+ val = msg.readInt16(); // MATK
+ player_node->setAttributeBase(MATK, val);
+ val += msg.readInt16(); // MATK bonus
+ player_node->setAttributeEffective(MATK, val);
+ statusWindow->update(StatusWindow::MP);
+
+ val = msg.readInt16(); // DEF
+ player_node->setAttributeBase(DEF, val);
+ val += msg.readInt16(); // DEF bonus
+ player_node->setAttributeEffective(DEF, val);
+
+ val = msg.readInt16(); // MDEF
+ player_node->setAttributeBase(MDEF, val);
+ val += msg.readInt16(); // MDEF bonus
+ player_node->setAttributeEffective(MDEF, val);
+
+ val = msg.readInt16(); // HIT
+ player_node->setAttributeBase(ATK, val);
+ player_node->setAttributeEffective(ATK, val);
+
+ val = msg.readInt16(); // FLEE
+ player_node->setAttributeBase(FLEE, val);
+ val += msg.readInt16(); // FLEE bonus
+ player_node->setAttributeEffective(FLEE, val);
+
+ val = msg.readInt16();
+ player_node->setAttributeBase(CRIT, val);
+ player_node->setAttributeEffective(CRIT, val);
+ }
+
+ msg.readInt16(); // manner
break;
case SMSG_PLAYER_STAT_UPDATE_6:
switch (msg.readInt16()) {
case 0x0020:
- player_node->mAttrUp[LocalPlayer::STR] = msg.readInt8();
+ statusWindow->setPointsNeeded(STR, msg.readInt8());
break;
case 0x0021:
- player_node->mAttrUp[LocalPlayer::AGI] = msg.readInt8();
+ statusWindow->setPointsNeeded(AGI, msg.readInt8());
break;
case 0x0022:
- player_node->mAttrUp[LocalPlayer::VIT] = msg.readInt8();
+ statusWindow->setPointsNeeded(VIT, msg.readInt8());
break;
case 0x0023:
- player_node->mAttrUp[LocalPlayer::INT] = msg.readInt8();
+ statusWindow->setPointsNeeded(INT, msg.readInt8());
break;
case 0x0024:
- player_node->mAttrUp[LocalPlayer::DEX] = msg.readInt8();
+ statusWindow->setPointsNeeded(DEX, msg.readInt8());
break;
case 0x0025:
- player_node->mAttrUp[LocalPlayer::LUK] = msg.readInt8();
+ statusWindow->setPointsNeeded(LUK, msg.readInt8());
break;
}
break;
@@ -433,44 +488,30 @@ void PlayerHandler::emote(int emoteId)
outMsg.writeInt8(emoteId);
}
-void PlayerHandler::increaseStat(LocalPlayer::Attribute attr)
+void PlayerHandler::increaseAttribute(size_t attr)
{
- MessageOut outMsg(CMSG_STAT_UPDATE_REQUEST);
-
- switch (attr)
+ if (attr >= STR && attr <= LUK)
{
- case LocalPlayer::STR:
- outMsg.writeInt16(0x000d);
- break;
-
- case LocalPlayer::AGI:
- outMsg.writeInt16(0x000e);
- break;
-
- case LocalPlayer::VIT:
- outMsg.writeInt16(0x000f);
- break;
-
- case LocalPlayer::INT:
- outMsg.writeInt16(0x0010);
- break;
-
- case LocalPlayer::DEX:
- outMsg.writeInt16(0x0011);
- break;
-
- case LocalPlayer::LUK:
- outMsg.writeInt16(0x0012);
- break;
+ MessageOut outMsg(CMSG_STAT_UPDATE_REQUEST);
+ outMsg.writeInt16(attr);
+ outMsg.writeInt8(1);
}
- outMsg.writeInt8(1);
}
-void PlayerHandler::decreaseStat(LocalPlayer::Attribute attr)
+void PlayerHandler::decreaseAttribute(size_t attr)
{
// Supported by eA?
}
+void PlayerHandler::increaseSkill(int skillId)
+{
+ if (player_node->getSkillPoints() <= 0)
+ return;
+
+ MessageOut outMsg(CMSG_SKILL_LEVELUP_REQUEST);
+ outMsg.writeInt16(skillId);
+}
+
void PlayerHandler::pickUp(FloorItem *floorItem)
{
MessageOut outMsg(CMSG_ITEM_PICKUP);
@@ -521,4 +562,9 @@ void PlayerHandler::ignoreAll(bool ignore)
// TODO
}
+bool PlayerHandler::canUseMagic()
+{
+ return player_node->getAttributeEffective(MATK) > 0;
+}
+
} // namespace EAthena
diff --git a/src/net/ea/playerhandler.h b/src/net/ea/playerhandler.h
index 5dbc171b..78e64a88 100644
--- a/src/net/ea/playerhandler.h
+++ b/src/net/ea/playerhandler.h
@@ -39,9 +39,11 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
void emote(int emoteId);
- void increaseStat(LocalPlayer::Attribute attr);
+ void increaseAttribute(size_t attr);
- void decreaseStat(LocalPlayer::Attribute attr);
+ void decreaseAttribute(size_t attr);
+
+ void increaseSkill(int skillId);
void pickUp(FloorItem *floorItem);
@@ -56,6 +58,8 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
void ignorePlayer(const std::string &player, bool ignore);
void ignoreAll(bool ignore);
+
+ bool canUseMagic();
};
} // namespace EAthena
diff --git a/src/net/ea/protocol.h b/src/net/ea/protocol.h
index b3759946..279e4c2f 100644
--- a/src/net/ea/protocol.h
+++ b/src/net/ea/protocol.h
@@ -22,6 +22,25 @@
#ifndef EA_PROTOCOL_H
#define EA_PROTOCOL_H
+enum {
+ JOB = 0xa,
+
+ STR = 0xd,
+ AGI,
+ VIT,
+ INT,
+ DEX,
+ LUK,
+
+ ATK,
+ DEF,
+ MATK,
+ MDEF,
+ HIT,
+ FLEE,
+ CRIT
+};
+
static const int INVENTORY_OFFSET = 2;
static const int STORAGE_OFFSET = 1;
@@ -69,6 +88,7 @@ static const int STORAGE_OFFSET = 1;
#define SMSG_PLAYER_ARROW_EQUIP 0x013c
#define SMSG_PLAYER_ARROW_MESSAGE 0x013b
#define SMSG_PLAYER_SKILLS 0x010f
+#define SMSG_PLAYER_SKILL_UP 0x010e
#define SMSG_SKILL_FAILED 0x0110
#define SMSG_ITEM_USE_RESPONSE 0x00a8
#define SMSG_ITEM_VISIBLE 0x009d /**< An item is on the floor */
@@ -160,6 +180,11 @@ static const int STORAGE_OFFSET = 1;
#define CMSG_SKILL_LEVELUP_REQUEST 0x0112
#define CMSG_STAT_UPDATE_REQUEST 0x00bb
+#define CMSG_SKILL_USE_BEING 0x0113
+#define CMSG_SKILL_USE_POSITION 0x0116
+// Variant of 0x116 with 80 char string at end (unsure of use)
+#define CMSG_SKILL_USE_POSITION_MORE 0x0190
+#define CMSG_SKILL_USE_MAP 0x011b
#define CMSG_PLAYER_INVENTORY_USE 0x00a7
#define CMSG_PLAYER_INVENTORY_DROP 0x00a2
diff --git a/src/net/ea/skillhandler.cpp b/src/net/ea/specialhandler.cpp
index 69b0fd65..528f531e 100644
--- a/src/net/ea/skillhandler.cpp
+++ b/src/net/ea/specialhandler.cpp
@@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "net/ea/skillhandler.h"
+#include "net/ea/specialhandler.h"
#include "net/ea/protocol.h"
@@ -29,7 +29,7 @@
#include "localplayer.h"
#include "log.h"
-#include "gui/skill.h"
+#include "gui/skilldialog.h"
#include "gui/widgets/chattab.h"
@@ -67,60 +67,68 @@
/** should always be zero if failed */
#define SKILL_FAILED 0x00
-Net::SkillHandler *skillHandler;
+Net::SpecialHandler *specialHandler;
namespace EAthena {
-SkillHandler::SkillHandler()
+SpecialHandler::SpecialHandler()
{
static const Uint16 _messages[] = {
SMSG_PLAYER_SKILLS,
SMSG_SKILL_FAILED,
+ SMSG_PLAYER_SKILL_UP,
0
};
handledMessages = _messages;
- skillHandler = this;
+ specialHandler = this;
}
-void SkillHandler::handleMessage(MessageIn &msg)
+void SpecialHandler::handleMessage(MessageIn &msg)
{
int skillCount;
+ int skillId;
switch (msg.getId())
{
case SMSG_PLAYER_SKILLS:
msg.readInt16(); // length
skillCount = (msg.getLength() - 4) / 37;
- skillDialog->cleanList();
for (int k = 0; k < skillCount; k++)
{
- int skillId = msg.readInt16();
+ skillId = msg.readInt16();
msg.readInt16(); // target type
- msg.readInt16(); // unknown
+ msg.skip(2); // unused
int level = msg.readInt16();
- int sp = msg.readInt16();
- msg.readInt16(); // range
- std::string skillName = msg.readString(24);
+ msg.readInt16(); // sp
+ msg.readInt16(); // range
+ msg.skip(24); // unused
int up = msg.readInt8();
- if (level != 0 || up != 0)
- {
- if (skillDialog->hasSkill(skillId)) {
- skillDialog->setSkill(skillId, level, sp);
- }
- else {
- skillDialog->addSkill(skillId, level, sp);
- }
- }
+ player_node->setAttributeBase(skillId, level);
+ player_node->setAttributeEffective(skillId, level);
+ skillDialog->setModifiable(skillId, up);
+ }
+ break;
+
+ case SMSG_PLAYER_SKILL_UP:
+ {
+ skillId = msg.readInt16();
+ int level = msg.readInt16();
+ msg.readInt16(); // sp
+ msg.readInt16(); // range
+ int up = msg.readInt8();
+
+ player_node->setAttributeBase(skillId, level);
+ player_node->setAttributeEffective(skillId, level);
+ skillDialog->setModifiable(skillId, up);
}
- skillDialog->update();
break;
case SMSG_SKILL_FAILED:
// Action failed (ex. sit because you have not reached the
// right level)
- short skill = msg.readInt16();
+ skillId = msg.readInt16();
short bskill = msg.readInt16();
msg.readInt16(); // unknown
char success = msg.readInt8();
@@ -131,7 +139,7 @@ void SkillHandler::handleMessage(MessageIn &msg)
}
std::string msg;
- if (success == SKILL_FAILED && skill == SKILL_BASIC)
+ if (success == SKILL_FAILED && skillId == SKILL_BASIC)
{
switch (bskill)
{
@@ -196,7 +204,7 @@ void SkillHandler::handleMessage(MessageIn &msg)
}
else
{
- switch (skill)
+ switch (skillId)
{
case SKILL_WARP :
msg = _("Warp failed...");
@@ -215,28 +223,33 @@ void SkillHandler::handleMessage(MessageIn &msg)
}
}
-void SkillHandler::up(int skillId)
+void SpecialHandler::use(int id)
{
- if (player_node->mSkillPoint <= 0)
- return;
-
- MessageOut outMsg(CMSG_SKILL_LEVELUP_REQUEST);
- outMsg.writeInt16(skillId);
+ // TODO
}
-void SkillHandler::use(int skillId, int level, int beingId)
+void SpecialHandler::use(int id, int level, int beingId)
{
- // TODO
+ MessageOut outMsg(CMSG_SKILL_USE_BEING);
+ outMsg.writeInt16(level);
+ outMsg.writeInt16(id);
+ outMsg.writeInt16(beingId);
}
-void SkillHandler::use(int skillId, int level, int x, int y)
+void SpecialHandler::use(int id, int level, int x, int y)
{
- // TODO
+ MessageOut outMsg(CMSG_SKILL_USE_POSITION);
+ outMsg.writeInt16(level);
+ outMsg.writeInt16(id);
+ outMsg.writeInt16(x);
+ outMsg.writeInt16(y);
}
-void SkillHandler::use(int skillId, const std::string &map)
+void SpecialHandler::use(int id, const std::string &map)
{
- // TODO
+ MessageOut outMsg(CMSG_SKILL_USE_MAP);
+ outMsg.writeInt16(id);
+ outMsg.writeString(map, 16);
}
} // namespace EAthena
diff --git a/src/net/ea/skillhandler.h b/src/net/ea/specialhandler.h
index c1965213..eac53569 100644
--- a/src/net/ea/skillhandler.h
+++ b/src/net/ea/specialhandler.h
@@ -24,24 +24,24 @@
#include "net/messagehandler.h"
#include "net/net.h"
-#include "net/skillhandler.h"
+#include "net/specialhandler.h"
namespace EAthena {
-class SkillHandler : public MessageHandler, public Net::SkillHandler
+class SpecialHandler : public MessageHandler, public Net::SpecialHandler
{
public:
- SkillHandler();
+ SpecialHandler();
void handleMessage(MessageIn &msg);
- void up(int skillId);
+ void use(int id);
- void use(int skillId, int level, int beingId);
+ void use(int id, int level, int beingId);
- void use(int skillId, int level, int x, int y);
+ void use(int id, int level, int x, int y);
- void use(int skillId, const std::string &map);
+ void use(int id, const std::string &map);
};
} // namespace EAthena
diff --git a/src/net/net.cpp b/src/net/net.cpp
index a329af1a..7df336c6 100644
--- a/src/net/net.cpp
+++ b/src/net/net.cpp
@@ -33,7 +33,7 @@
#include "net/npchandler.h"
#include "net/partyhandler.h"
#include "net/playerhandler.h"
-#include "net/skillhandler.h"
+#include "net/specialhandler.h"
#include "net/tradehandler.h"
extern Net::AdminHandler *adminHandler;
@@ -47,7 +47,7 @@ extern Net::MapHandler *mapHandler;
extern Net::NpcHandler *npcHandler;
extern Net::PartyHandler *partyHandler;
extern Net::PlayerHandler *playerHandler;
-extern Net::SkillHandler *skillHandler;
+extern Net::SpecialHandler *specialHandler;
extern Net::TradeHandler *tradeHandler;
Net::AdminHandler *Net::getAdminHandler()
@@ -111,9 +111,9 @@ Net::PlayerHandler *Net::getPlayerHandler()
return playerHandler;
}
-Net::SkillHandler *Net::getSkillHandler()
+Net::SpecialHandler *Net::getSpecialHandler()
{
- return skillHandler;
+ return specialHandler;
}
Net::TradeHandler *Net::getTradeHandler()
diff --git a/src/net/net.h b/src/net/net.h
index 9154c1ef..1d91faa7 100644
--- a/src/net/net.h
+++ b/src/net/net.h
@@ -36,7 +36,7 @@ class MapHandler;
class NpcHandler;
class PartyHandler;
class PlayerHandler;
-class SkillHandler;
+class SpecialHandler;
class TradeHandler;
AdminHandler *getAdminHandler();
@@ -51,7 +51,7 @@ MapHandler *getMapHandler();
NpcHandler *getNpcHandler();
PartyHandler *getPartyHandler();
PlayerHandler *getPlayerHandler();
-SkillHandler *getSkillHandler();
+SpecialHandler *getSpecialHandler();
TradeHandler *getTradeHandler();
} // namespace Net
diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h
index 163b48f3..a0fd8bac 100644
--- a/src/net/playerhandler.h
+++ b/src/net/playerhandler.h
@@ -35,9 +35,11 @@ class PlayerHandler
virtual void emote(int emoteId) = 0;
- virtual void increaseStat(LocalPlayer::Attribute attr) = 0;
+ virtual void increaseAttribute(size_t attr) = 0;
- virtual void decreaseStat(LocalPlayer::Attribute attr) = 0;
+ virtual void decreaseAttribute(size_t attr) = 0;
+
+ virtual void increaseSkill(int skillId) = 0;
virtual void pickUp(FloorItem *floorItem) = 0;
@@ -52,6 +54,8 @@ class PlayerHandler
virtual void ignorePlayer(const std::string &player, bool ignore) = 0;
virtual void ignoreAll(bool ignore) = 0;
+
+ virtual bool canUseMagic() = 0;
};
} // namespace Net
diff --git a/src/net/skillhandler.h b/src/net/specialhandler.h
index 9db6ac5b..602003aa 100644
--- a/src/net/skillhandler.h
+++ b/src/net/specialhandler.h
@@ -19,23 +19,23 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef SKILLHANDLER_H
-#define SKILLHANDLER_H
+#ifndef SPECIALHANDLER_H
+#define SPECIALHANDLER_H
#include <iosfwd>
namespace Net {
-class SkillHandler
+class SpecialHandler
{
public:
- virtual void up(int skillId) = 0;
+ virtual void use(int id) = 0;
- virtual void use(int skillId, int level, int beingId) = 0;
+ virtual void use(int id, int level, int beingId) = 0;
- virtual void use(int skillId, int level, int x, int y) = 0;
+ virtual void use(int id, int level, int x, int y) = 0;
- virtual void use(int skillId, const std::string &map) = 0;
+ virtual void use(int id, const std::string &map) = 0;
};
}
-#endif // SKILLHANDLER_H
+#endif // SPECIALHANDLER_H
diff --git a/src/net/tmwserv/beinghandler.cpp b/src/net/tmwserv/beinghandler.cpp
index 7076ff8e..acd6b62c 100644
--- a/src/net/tmwserv/beinghandler.cpp
+++ b/src/net/tmwserv/beinghandler.cpp
@@ -187,28 +187,14 @@ void BeingHandler::handleBeingsMoveMessage(MessageIn &msg)
Being *being = beingManager->findBeing(id);
int sx = 0;
int sy = 0;
- int dx = 0;
- int dy = 0;
int speed = 0;
if (flags & MOVING_POSITION)
{
- Uint16 sx2, sy2;
- msg.readCoordinates(sx2, sy2);
- sx = sx2 * 32 + 16;
- sy = sy2 * 32 + 16;
+ sx = msg.readInt16();
+ sy = msg.readInt16();
speed = msg.readInt8();
}
- if (flags & MOVING_DESTINATION)
- {
- dx = msg.readInt16();
- dy = msg.readInt16();
- if (!(flags & MOVING_POSITION))
- {
- sx = dx;
- sy = dy;
- }
- }
if (!being || !(flags & (MOVING_POSITION | MOVING_DESTINATION)))
{
continue;
@@ -228,33 +214,9 @@ void BeingHandler::handleBeingsMoveMessage(MessageIn &msg)
if (being == player_node)
continue;
- // If being is a player, and he only moves a little, its ok to be a little out of sync
- if (being->getType() == Being::PLAYER && abs(being->getPixelX() - dx) +
- abs(being->getPixelY() - dy) < 16 &&
- (dx != being->getDestination().x &&
- dy != being->getDestination().y))
- {
- being->setDestination(being->getPixelX(),being->getPixelY());
- continue;
- }
- if (abs(being->getPixelX() - sx) +
- abs(being->getPixelY() - sy) > 10 * 32)
- {
- // Too large a desynchronization.
- being->setPosition(sx, sy);
- being->setDestination(dx, dy);
- }
- else if (!(flags & MOVING_POSITION))
- {
- being->setDestination(dx, dy);
- }
- else if (!(flags & MOVING_DESTINATION))
- {
- being->adjustCourse(sx, sy);
- }
- else
+ if (flags & MOVING_POSITION)
{
- being->setDestination(sx, sy, dx, dy);
+ being->setDestination(sx, sy);
}
}
}
@@ -306,23 +268,27 @@ void BeingHandler::handleBeingActionChangeMessage(MessageIn &msg)
static char const *const deadMsg[] =
{
_("You are dead."),
- _("We regret to inform you that your character was killed in battle."),
+ _("We regret to inform you that your character was killed in "
+ "battle."),
_("You are not that alive anymore."),
_("The cold hands of the grim reaper are grabbing for your soul."),
_("Game Over!"),
- _("No, kids. Your character did not really die. It... err... went to a better place."),
- _("Your plan of breaking your enemies weapon by bashing it with your throat failed."),
+ _("No, kids. Your character did not really die. It... err... "
+ "went to a better place."),
+ _("Your plan of breaking your enemies weapon by bashing it with "
+ "your throat failed."),
_("I guess this did not run too well."),
_("Do you want your possessions identified?"), // Nethack reference
_("Sadly, no trace of you was ever found..."), // Secret of Mana reference
_("Annihilated."), // Final Fantasy VI reference
- _("Looks like you got your head handed to you."), //Earthbound reference
- _("You screwed up again, dump your body down the tubes and get you another one.") // Leisure Suit Larry 1 Reference
+ _("Looks like you got your head handed to you."), // Earthbound reference
+ _("You screwed up again, dump your body down the tubes and get "
+ "you another one.") // Leisure Suit Larry 1 Reference
};
std::string message(deadMsg[rand()%13]);
- message.append(_(" Press OK to respawn"));
- OkDialog *dlg = new OkDialog(_("You died"), message);
+ message.append(std::string(" ") + _("Press OK to respawn."));
+ OkDialog *dlg = new OkDialog(_("You Died"), message);
dlg->addActionListener(&(Net::GameServer::Player::respawnListener));
}
}
diff --git a/src/net/tmwserv/charserverhandler.cpp b/src/net/tmwserv/charserverhandler.cpp
index 7b74904f..0146babb 100644
--- a/src/net/tmwserv/charserverhandler.cpp
+++ b/src/net/tmwserv/charserverhandler.cpp
@@ -81,25 +81,25 @@ void CharServerHandler::handleMessage(MessageIn &msg)
delete mCharInfo->getEntry();
mCharInfo->setEntry(0);
mCharInfo->unlock();
- new OkDialog("Info", "Player deleted");
+ new OkDialog(_("Info"), _("Player deleted."));
}
// Character deletion failed
else
{
- std::string message = "";
+ std::string errorMessage = "";
switch (errMsg)
{
case ERRMSG_NO_LOGIN:
- message = "Not logged in";
+ errorMessage = _("Not logged in.");
break;
case ERRMSG_INVALID_ARGUMENT:
- message = "Selection out of range";
+ errorMessage = _("Selection out of range.");
break;
default:
- message = "Unknown error";
+ errorMessage = _("Unknown error.");
}
mCharInfo->unlock();
- new OkDialog("Error", message);
+ new OkDialog(_("Error"), errorMessage);
}
}
break;
@@ -131,44 +131,44 @@ void CharServerHandler::handleCharCreateResponse(MessageIn &msg)
// Character creation failed
if (errMsg != ERRMSG_OK)
{
- std::string message = "";
+ std::string errorMessage = "";
switch (errMsg)
{
case ERRMSG_NO_LOGIN:
- message = "Not logged in";
+ errorMessage = _("Not logged in.");
break;
case CREATE_TOO_MUCH_CHARACTERS:
- message = "No empty slot";
+ errorMessage = _("No empty slot.");
break;
case ERRMSG_INVALID_ARGUMENT:
- message = "Invalid name";
+ errorMessage = _("Invalid name.");
break;
case CREATE_EXISTS_NAME:
- message = "Character's name already exists";
+ errorMessage = _("Character's name already exists.");
break;
case CREATE_INVALID_HAIRSTYLE:
- message = "Invalid hairstyle";
+ errorMessage = _("Invalid hairstyle.");
break;
case CREATE_INVALID_HAIRCOLOR:
- message = "Invalid hair color";
+ errorMessage = _("Invalid hair color.");
break;
case CREATE_INVALID_GENDER:
- message = "Invalid gender";
+ errorMessage = _("Invalid gender.");
break;
case CREATE_RAW_STATS_TOO_HIGH:
- message = "Character's stats are too high";
+ errorMessage = _("Character's stats are too high.");
break;
case CREATE_RAW_STATS_TOO_LOW:
- message = "Character's stats are too low";
+ errorMessage = _("Character's stats are too low.");
break;
case CREATE_RAW_STATS_EQUAL_TO_ZERO:
- message = "One stat is zero";
+ errorMessage = _("One stat is zero.");
break;
default:
- message = "Unknown error";
+ errorMessage = _("Unknown error.");
break;
}
- new OkDialog("Error", message);
+ new OkDialog(_("Error"), errorMessage);
}
if (mCharCreateDialog)
diff --git a/src/net/tmwserv/chathandler.cpp b/src/net/tmwserv/chathandler.cpp
index e2d09534..ad3ae49b 100644
--- a/src/net/tmwserv/chathandler.cpp
+++ b/src/net/tmwserv/chathandler.cpp
@@ -159,7 +159,7 @@ void ChatHandler::handleEnterChannelResponse(MessageIn &msg)
std::string user;
std::string userModes;
- tab->chatLog("Players in this channel:", BY_CHANNEL);
+ tab->chatLog(_("Players in this channel:"), BY_CHANNEL);
while(msg.getUnreadLength())
{
user = msg.readString();
@@ -176,13 +176,13 @@ void ChatHandler::handleEnterChannelResponse(MessageIn &msg)
}
else
{
- localChatTab->chatLog("Error joining channel.", BY_SERVER);
+ localChatTab->chatLog(_("Error joining channel."), BY_SERVER);
}
}
void ChatHandler::handleListChannelsResponse(MessageIn &msg)
{
- localChatTab->chatLog("Listing channels", BY_SERVER);
+ localChatTab->chatLog(_("Listing channels."), BY_SERVER);
while(msg.getUnreadLength())
{
std::string channelName = msg.readString();
@@ -194,7 +194,7 @@ void ChatHandler::handleListChannelsResponse(MessageIn &msg)
channelName += numUsers.str();
localChatTab->chatLog(channelName, BY_SERVER);
}
- localChatTab->chatLog("End of channel list.", BY_SERVER);
+ localChatTab->chatLog(_("End of channel list."), BY_SERVER);
}
void ChatHandler::handlePrivateMessage(MessageIn &msg)
@@ -237,7 +237,7 @@ void ChatHandler::handleListChannelUsersResponse(MessageIn &msg)
std::string userNick;
std::string userModes;
Channel *channel = channelManager->findByName(channelName);
- channel->getTab()->chatLog("Players in this channel:", BY_CHANNEL);
+ channel->getTab()->chatLog(_("Players in this channel:"), BY_CHANNEL);
while(msg.getUnreadLength())
{
userNick = msg.readString();
@@ -266,15 +266,18 @@ void ChatHandler::handleChannelEvent(MessageIn &msg)
switch(eventId)
{
case CHAT_EVENT_NEW_PLAYER:
- line += " entered the channel.";
+ channel->getTab()->chatLog(strprintf(_("%s entered the "
+ "channel."), line.c_str()), BY_CHANNEL);
break;
case CHAT_EVENT_LEAVING_PLAYER:
- line += " left the channel.";
+ channel->getTab()->chatLog(strprintf(_("%s left the channel."),
+ line.c_str()), BY_CHANNEL);
break;
case CHAT_EVENT_TOPIC_CHANGE:
- line = "Topic: " + line;
+ channel->getTab()->chatLog(strprintf(_("Topic: %s"),
+ line.c_str()), BY_CHANNEL);
break;
case CHAT_EVENT_MODE_CHANGE:
@@ -284,7 +287,9 @@ void ChatHandler::handleChannelEvent(MessageIn &msg)
std::string user1 = line.substr(0, first);
std::string user2 = line.substr(first+1, second);
std::string mode = line.substr(second+1, line.length());
- line = user1 + " has set mode " + mode + " on user " + user2;
+ channel->getTab()->chatLog(strprintf(_("%s has set mode %s "
+ "on user %s."), user1.c_str(), mode.c_str(),
+ user2.c_str()), BY_CHANNEL);
} break;
case CHAT_EVENT_KICKED_PLAYER:
@@ -292,14 +297,14 @@ void ChatHandler::handleChannelEvent(MessageIn &msg)
int first = line.find(":");
std::string user1 = line.substr(0, first);
std::string user2 = line.substr(first+1, line.length());
- line = user1 + " has kicked " + user2;
+ channel->getTab()->chatLog(strprintf(_("%s has kicked %s."),
+ user1, user2), BY_CHANNEL);
} break;
default:
- line = "Unknown channel event.";
+ channel->getTab()->chatLog(_("Unknown channel event."),
+ BY_CHANNEL);
}
-
- channel->getTab()->chatLog(line, BY_CHANNEL);
}
}
diff --git a/src/net/tmwserv/gameserver/player.cpp b/src/net/tmwserv/gameserver/player.cpp
index 93853681..4e63930b 100644
--- a/src/net/tmwserv/gameserver/player.cpp
+++ b/src/net/tmwserv/gameserver/player.cpp
@@ -41,14 +41,6 @@ void Net::GameServer::Player::walk(int x, int y)
Net::GameServer::connection->send(msg);
}
-void Net::GameServer::Player::pickUp(int x, int y)
-{
- MessageOut msg(PGMSG_PICKUP);
- msg.writeInt16(x);
- msg.writeInt16(y);
- Net::GameServer::connection->send(msg);
-}
-
void Net::GameServer::Player::moveItem(int oldSlot, int newSlot, int amount)
{
MessageOut msg(PGMSG_MOVE_ITEM);
@@ -58,47 +50,6 @@ void Net::GameServer::Player::moveItem(int oldSlot, int newSlot, int amount)
Net::GameServer::connection->send(msg);
}
-void Net::GameServer::Player::useSpecial(int special)
-{
- MessageOut msg(PGMSG_USE_SPECIAL);
- msg.writeInt8(special);
- Net::GameServer::connection->send(msg);
-}
-
-void Net::GameServer::Player::requestTrade(int id)
-{
- MessageOut msg(PGMSG_TRADE_REQUEST);
- msg.writeInt16(id);
- Net::GameServer::connection->send(msg);
-}
-
-void Net::GameServer::Player::acceptTrade(bool accept)
-{
- MessageOut msg(accept ? PGMSG_TRADE_REQUEST : PGMSG_TRADE_CANCEL);
- Net::GameServer::connection->send(msg);
-}
-
-void Net::GameServer::Player::tradeMoney(int amount)
-{
- MessageOut msg(PGMSG_TRADE_SET_MONEY);
- msg.writeInt32(amount);
- Net::GameServer::connection->send(msg);
-}
-
-void Net::GameServer::Player::raiseAttribute(int attribute)
-{
- MessageOut msg(PGMSG_RAISE_ATTRIBUTE);
- msg.writeInt8(attribute);
- Net::GameServer::connection->send(msg);
-}
-
-void Net::GameServer::Player::lowerAttribute(int attribute)
-{
- MessageOut msg(PGMSG_LOWER_ATTRIBUTE);
- msg.writeInt8(attribute);
- Net::GameServer::connection->send(msg);
-}
-
void Net::GameServer::Player::respawn()
{
MessageOut msg(PGMSG_RESPAWN);
diff --git a/src/net/tmwserv/gameserver/player.h b/src/net/tmwserv/gameserver/player.h
index 24b25dc7..9a202c6e 100644
--- a/src/net/tmwserv/gameserver/player.h
+++ b/src/net/tmwserv/gameserver/player.h
@@ -41,14 +41,7 @@ namespace Net
namespace Player
{
void walk(int x, int y);
- void pickUp(int x, int y);
void moveItem(int oldSlot, int newSlot, int amount);
- void useSpecial(int special);
- void requestTrade(int id);
- void acceptTrade(bool accept);
- void tradeMoney(int amount);
- void raiseAttribute(int attribute);
- void lowerAttribute(int attribute);
void respawn();
static RespawnRequestListener respawnListener;
}
diff --git a/src/net/tmwserv/generalhandler.cpp b/src/net/tmwserv/generalhandler.cpp
index 5886aafb..d643586b 100644
--- a/src/net/tmwserv/generalhandler.cpp
+++ b/src/net/tmwserv/generalhandler.cpp
@@ -21,6 +21,8 @@
#include "gui/inventorywindow.h"
#include "gui/partywindow.h"
+#include "gui/skilldialog.h"
+#include "gui/statuswindow.h"
#include "net/tmwserv/generalhandler.h"
@@ -146,6 +148,16 @@ void GeneralHandler::guiWindowsLoaded()
{
inventoryWindow->setSplitAllowed(true);
partyWindow->clearPartyName();
+ skillDialog->loadSkills("tmw-skills.xml");
+
+ player_node->setExpNeeded(100);
+
+ statusWindow->addAttribute(16, _("Strength"), true);
+ statusWindow->addAttribute(17, _("Agility"), true);
+ statusWindow->addAttribute(18, _("Dexterity"), true);
+ statusWindow->addAttribute(19, _("Vitality"), true);
+ statusWindow->addAttribute(20, _("Intelligence"), true);
+ statusWindow->addAttribute(21, _("Willpower"), true);
}
void GeneralHandler::guiWindowsUnloaded()
diff --git a/src/net/tmwserv/loginhandler.cpp b/src/net/tmwserv/loginhandler.cpp
index 35739669..f728d831 100644
--- a/src/net/tmwserv/loginhandler.cpp
+++ b/src/net/tmwserv/loginhandler.cpp
@@ -77,16 +77,16 @@ void LoginHandler::handleMessage(MessageIn &msg)
{
switch (errMsg) {
case ERRMSG_INVALID_ARGUMENT:
- errorMessage = _("Wrong magic_token");
+ errorMessage = _("Wrong magic_token.");
break;
case ERRMSG_FAILURE:
- errorMessage = _("Already logged in");
+ errorMessage = _("Already logged in.");
break;
case LOGIN_SERVER_FULL:
- errorMessage = _("Server is full");
+ errorMessage = _("Server is full.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_ERROR;
@@ -107,16 +107,16 @@ void LoginHandler::handleMessage(MessageIn &msg)
{
switch (errMsg) {
case ERRMSG_INVALID_ARGUMENT:
- errorMessage = _("New password incorrect");
+ errorMessage = _("New password incorrect.");
break;
case ERRMSG_FAILURE:
- errorMessage = _("Old password incorrect");
+ errorMessage = _("Old password incorrect.");
break;
case ERRMSG_NO_LOGIN:
errorMessage = _("Account not connected. Please login first.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_ACCOUNTCHANGE_ERROR;
@@ -137,19 +137,19 @@ void LoginHandler::handleMessage(MessageIn &msg)
{
switch (errMsg) {
case ERRMSG_INVALID_ARGUMENT:
- errorMessage = _("New email address incorrect");
+ errorMessage = _("New email address incorrect.");
break;
case ERRMSG_FAILURE:
- errorMessage = _("Old email address incorrect");
+ errorMessage = _("Old email address incorrect.");
break;
case ERRMSG_NO_LOGIN:
errorMessage = _("Account not connected. Please login first.");
break;
case ERRMSG_EMAIL_ALREADY_EXISTS:
- errorMessage = _("The new Email Address already exists.");
+ errorMessage = _("The new email address already exists.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_ACCOUNTCHANGE_ERROR;
@@ -173,19 +173,19 @@ void LoginHandler::handleLoginResponse(MessageIn &msg)
{
switch (errMsg) {
case LOGIN_INVALID_VERSION:
- errorMessage = _("Client version is too old");
+ errorMessage = _("Client version is too old.");
break;
case ERRMSG_INVALID_ARGUMENT:
- errorMessage = _("Wrong username or password");
+ errorMessage = _("Wrong username or password.");
break;
case ERRMSG_FAILURE:
- errorMessage = _("Already logged in");
+ errorMessage = _("Already logged in.");
break;
case LOGIN_SERVER_FULL:
- errorMessage = _("Server is full");
+ errorMessage = _("Server is full.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_LOGIN_ERROR;
@@ -205,19 +205,19 @@ void LoginHandler::handleRegisterResponse(MessageIn &msg)
{
switch (errMsg) {
case REGISTER_INVALID_VERSION:
- errorMessage = _("Client version is too old");
+ errorMessage = _("Client version is too old.");
break;
case ERRMSG_INVALID_ARGUMENT:
- errorMessage = _("Wrong username, password or email address");
+ errorMessage = _("Wrong username, password or email address.");
break;
case REGISTER_EXISTS_USERNAME:
- errorMessage = _("Username already exists");
+ errorMessage = _("Username already exists.");
break;
case REGISTER_EXISTS_EMAIL:
- errorMessage = _("Email address already exists");
+ errorMessage = _("Email address already exists.");
break;
default:
- errorMessage = _("Unknown error");
+ errorMessage = _("Unknown error.");
break;
}
state = STATE_LOGIN_ERROR;
diff --git a/src/net/tmwserv/partyhandler.cpp b/src/net/tmwserv/partyhandler.cpp
index 557a3a43..2af0e4cb 100644
--- a/src/net/tmwserv/partyhandler.cpp
+++ b/src/net/tmwserv/partyhandler.cpp
@@ -100,8 +100,8 @@ void PartyHandler::handleMessage(MessageIn &msg)
int id = msg.readInt16(); // being id
std::string name = msg.readString();
- localChatTab->chatLog(strprintf(_("%s joined the "
- "party."), name.c_str()));
+ localChatTab->chatLog(strprintf(_("%s joined the party.",
+ name.c_str()));
if (!player_node->isInParty())
player_node->setInParty(true);
@@ -117,7 +117,8 @@ void PartyHandler::handleMessage(MessageIn &msg)
case CPMSG_PARTY_REJECTED:
{
std::string name = msg.readString();
- localChatTab->chatLog(name + "rejected your invite.");
+ localChatTab->chatLog(strprintf(_("%s rejected your invite."),
+ name.c_str()));
} break;
}
}
diff --git a/src/net/tmwserv/playerhandler.cpp b/src/net/tmwserv/playerhandler.cpp
index bbc73b7c..ce1990ed 100644
--- a/src/net/tmwserv/playerhandler.cpp
+++ b/src/net/tmwserv/playerhandler.cpp
@@ -43,7 +43,6 @@
#include "gui/gui.h"
#include "gui/okdialog.h"
#include "gui/sell.h"
-#include "gui/skill.h"
#include "gui/viewport.h"
// TODO Move somewhere else
@@ -134,7 +133,7 @@ void PlayerHandler::handleMessage(MessageIn &msg)
logger->log("ATTRIBUTE UPDATE:");
while (msg.getUnreadLength())
{
- int stat = msg.readInt8();
+ int stat = msg.readInt16();
int base = msg.readInt16();
int value = msg.readInt16();
logger->log("%d set to %d %d", stat, base, value);
@@ -144,24 +143,11 @@ void PlayerHandler::handleMessage(MessageIn &msg)
player_node->setMaxHp(base);
player_node->setHp(value);
}
- else if (stat < NB_CHARACTER_ATTRIBUTES)
+ else
{
- if (stat >= CHAR_SKILL_BEGIN && stat < CHAR_SKILL_END
- && player_node->getAttributeBase(stat) < base
- && player_node->getAttributeBase(stat) > -1)
- {
- Particle* effect = particleEngine->addEffect("graphics/particles/skillup.particle.xml", 0, 0);
- player_node->controlParticle(effect);
- }
-
player_node->setAttributeBase(stat, base);
player_node->setAttributeEffective(stat, value);
}
- else
- {
- logger->log("Warning: server wants to update unknown "
- "attribute %d to %d", stat, value);
- }
}
} break;
@@ -174,15 +160,7 @@ void PlayerHandler::handleMessage(MessageIn &msg)
int current = msg.readInt32();
int next = msg.readInt32();
- if (skill < CHAR_SKILL_NB)
- {
- player_node->setExperience(skill, current, next);
- }
- else
- {
- logger->log("Warning: server wants to update experience of unknown "
- "skill %d to %d / %d", skill, current, next);
- }
+ player_node->setExperience(skill, current, next);
}
} break;
@@ -199,7 +177,7 @@ void PlayerHandler::handleMessage(MessageIn &msg)
case GPMSG_LEVEL_PROGRESS:
{
logger->log("Level Progress Update");
- player_node->setLevelProgress(msg.readInt8());
+ player_node->setExp(msg.readInt8());
} break;
@@ -358,20 +336,32 @@ void PlayerHandler::emote(int emoteId)
// TODO
}
-void PlayerHandler::increaseStat(LocalPlayer::Attribute attr)
+void PlayerHandler::increaseAttribute(size_t attr)
{
- // TODO
+ MessageOut msg(PGMSG_RAISE_ATTRIBUTE);
+ msg.writeInt8(attr);
+ Net::GameServer::connection->send(msg);
}
-void PlayerHandler::decreaseStat(LocalPlayer::Attribute attr)
+void PlayerHandler::decreaseAttribute(size_t attr)
{
- // TODO
+ MessageOut msg(PGMSG_LOWER_ATTRIBUTE);
+ msg.writeInt8(attr);
+ Net::GameServer::connection->send(msg);
+}
+
+void PlayerHandler::increaseSkill(int skillId)
+{
+ // Not used atm
}
void PlayerHandler::pickUp(FloorItem *floorItem)
{
int id = floorItem->getId();
- Net::GameServer::Player::pickUp(id >> 16, id & 0xFFFF);
+ MessageOut msg(PGMSG_PICKUP);
+ msg.writeInt16(id >> 16);
+ msg.writeInt16(id & 0xFFFF);
+ Net::GameServer::connection->send(msg);
}
void PlayerHandler::setDirection(char direction)
@@ -414,4 +404,9 @@ void PlayerHandler::ignoreAll(bool ignore)
// TODO
}
+bool PlayerHandler::canUseMagic()
+{
+ return true;
+}
+
} // namespace TmwServ
diff --git a/src/net/tmwserv/playerhandler.h b/src/net/tmwserv/playerhandler.h
index 164d30ae..287baa3d 100644
--- a/src/net/tmwserv/playerhandler.h
+++ b/src/net/tmwserv/playerhandler.h
@@ -38,9 +38,11 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
void emote(int emoteId);
- void increaseStat(LocalPlayer::Attribute attr);
+ void increaseAttribute(size_t attr);
- void decreaseStat(LocalPlayer::Attribute attr);
+ void decreaseAttribute(size_t attr);
+
+ void increaseSkill(int skillId);
void pickUp(FloorItem *floorItem);
@@ -56,6 +58,8 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
void ignoreAll(bool ignore);
+ bool canUseMagic();
+
private:
void handleMapChangeMessage(MessageIn &msg);
};
diff --git a/src/net/tmwserv/protocol.h b/src/net/tmwserv/protocol.h
index 2f1ea885..60a50d89 100644
--- a/src/net/tmwserv/protocol.h
+++ b/src/net/tmwserv/protocol.h
@@ -83,7 +83,7 @@ enum {
PGMSG_MOVE_ITEM = 0x0114, // B slot1, B slot2, B amount
GPMSG_INVENTORY = 0x0120, // { B slot, W item id [, B amount] }*
GPMSG_INVENTORY_FULL = 0x0121, // { B slot, W item id [, B amount] }*
- GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { B attribute, W base value, W modified value }*
+ GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { W attribute, W base value, W modified value }*
GPMSG_PLAYER_EXP_CHANGE = 0x0140, // { W skill, D exp got, D exp needed }*
GPMSG_LEVELUP = 0x0150, // W new level
GPMSG_LEVEL_PROGRESS = 0x0151, // B percent completed to next levelup
@@ -104,7 +104,7 @@ enum {
GPMSG_BEING_ACTION_CHANGE = 0x0271, // W being id, B action
PGMSG_DIRECTION_CHANGE = 0x0272, // B Direction
GPMSG_BEING_DIR_CHANGE = 0x0273, // W being id, B direction
- GPMSG_BEINGS_MOVE = 0x0280, // { W being id, B flags [, C position, B speed] [, W*2 destination] }*
+ GPMSG_BEINGS_MOVE = 0x0280, // { W being id, B flags [, W*2 position, B speed] }*
GPMSG_ITEMS = 0x0281, // { W item id, W*2 position }*
PGMSG_ATTACK = 0x0290, // W being id
GPMSG_BEING_ATTACK = 0x0291, // W being id
diff --git a/src/net/tmwserv/skillhandler.cpp b/src/net/tmwserv/specialhandler.cpp
index e35b896a..f259e77a 100644
--- a/src/net/tmwserv/skillhandler.cpp
+++ b/src/net/tmwserv/specialhandler.cpp
@@ -19,33 +19,42 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "net/tmwserv/skillhandler.h"
+#include "net/tmwserv/specialhandler.h"
-Net::SkillHandler *skillHandler;
+#include "net/tmwserv/gameserver/internal.h"
+
+#include "net/tmwserv/connection.h"
+#include "net/tmwserv/protocol.h"
+
+#include "net/messageout.h"
+
+Net::SpecialHandler *specialHandler;
namespace TmwServ {
-SkillHandler::SkillHandler()
+SpecialHandler::SpecialHandler()
{
- skillHandler = this;
+ specialHandler = this;
}
-void SkillHandler::up(int skillId)
+void SpecialHandler::use(int id)
{
- // TODO
+ MessageOut msg(PGMSG_USE_SPECIAL);
+ msg.writeInt8(id);
+ Net::GameServer::connection->send(msg);
}
-void SkillHandler::use(int skillId, int level, int beingId)
+void SpecialHandler::use(int id, int level, int beingId)
{
// TODO
}
-void SkillHandler::use(int skillId, int level, int x, int y)
+void SpecialHandler::use(int id, int level, int x, int y)
{
// TODO
}
-void SkillHandler::use(int skillId, const std::string &map)
+void SpecialHandler::use(int id, const std::string &map)
{
// TODO
}
diff --git a/src/net/tmwserv/skillhandler.h b/src/net/tmwserv/specialhandler.h
index 8c459c4f..c7ebd6a2 100644
--- a/src/net/tmwserv/skillhandler.h
+++ b/src/net/tmwserv/specialhandler.h
@@ -22,22 +22,22 @@
#ifndef NET_TMWSERV_SKILLHANDLER_H
#define NET_TMWSERV_SKILLHANDLER_H
-#include "net/skillhandler.h"
+#include "net/specialhandler.h"
namespace TmwServ {
-class SkillHandler : public Net::SkillHandler
+class SpecialHandler : public Net::SpecialHandler
{
public:
- SkillHandler();
+ SpecialHandler();
- void up(int skillId);
+ void use(int id);
- void use(int skillId, int level, int beingId);
+ void use(int id, int level, int beingId);
- void use(int skillId, int level, int x, int y);
+ void use(int id, int level, int x, int y);
- void use(int skillId, const std::string &map);
+ void use(int id, const std::string &map);
};
} // namespace TmwServ
diff --git a/src/net/tmwserv/tradehandler.cpp b/src/net/tmwserv/tradehandler.cpp
index aabd8b2a..55a00d4c 100644
--- a/src/net/tmwserv/tradehandler.cpp
+++ b/src/net/tmwserv/tradehandler.cpp
@@ -55,7 +55,11 @@ namespace {
void action(const gcn::ActionEvent &event)
{
if (event.getId() == "yes")
- Net::GameServer::Player::requestTrade(tradePartnerID);
+ {
+ MessageOut msg(PGMSG_TRADE_REQUEST);
+ msg.writeInt16(tradePartnerID);
+ Net::GameServer::connection->send(msg);
+ }
else
Net::getTradeHandler()->cancel();
}
@@ -105,7 +109,7 @@ void TradeHandler::handleMessage(MessageIn &msg)
Being *being = beingManager->findBeing(msg.readInt16());
if (!being || !mAcceptTradeRequests)
{
- Net::GameServer::Player::acceptTrade(false);
+ respond(false);
break;
}
player_node->setTrading(true);
@@ -171,7 +175,9 @@ void TradeHandler::request(Being *being)
void TradeHandler::respond(bool accept)
{
- // TODO
+ MessageOut msg(accept ? PGMSG_TRADE_REQUEST : PGMSG_TRADE_CANCEL);
+ Net::GameServer::connection->send(msg);
+
if (!accept)
player_node->setTrading(false);
}