summaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/net')
-rw-r--r--src/net/abilityhandler.h8
-rw-r--r--src/net/manaserv/abilityhandler.cpp11
-rw-r--r--src/net/manaserv/abilityhandler.h6
-rw-r--r--src/net/manaserv/beinghandler.cpp109
-rw-r--r--src/net/manaserv/beinghandler.h5
-rw-r--r--src/net/manaserv/charhandler.cpp82
-rw-r--r--src/net/manaserv/charhandler.h11
-rw-r--r--src/net/manaserv/gamehandler.cpp4
-rw-r--r--src/net/manaserv/generalhandler.cpp2
-rw-r--r--src/net/manaserv/inventoryhandler.cpp258
-rw-r--r--src/net/manaserv/inventoryhandler.h18
-rw-r--r--src/net/manaserv/loginhandler.cpp2
-rw-r--r--src/net/manaserv/manaserv_protocol.h208
-rw-r--r--src/net/manaserv/npchandler.cpp4
-rw-r--r--src/net/manaserv/playerhandler.cpp43
-rw-r--r--src/net/tmwa/abilityhandler.cpp6
-rw-r--r--src/net/tmwa/abilityhandler.h6
17 files changed, 371 insertions, 412 deletions
diff --git a/src/net/abilityhandler.h b/src/net/abilityhandler.h
index 6e3526bb..8e61d0c5 100644
--- a/src/net/abilityhandler.h
+++ b/src/net/abilityhandler.h
@@ -21,8 +21,6 @@
#pragma once
-#include <iosfwd>
-
namespace Net {
class AbilityHandler
@@ -32,11 +30,11 @@ class AbilityHandler
virtual void use(int id) = 0;
- virtual void use(int id, int level, int beingId) = 0;
+ virtual void useOn(int id, int beingId) = 0;
- virtual void use(int id, int level, int x, int y) = 0;
+ virtual void useAt(int id, int x, int y) = 0;
- virtual void use(int id, const std::string &map) = 0;
+ virtual void useInDirection(int id, int direction) = 0;
};
} // namespace Net
diff --git a/src/net/manaserv/abilityhandler.cpp b/src/net/manaserv/abilityhandler.cpp
index b5ce9d2e..a9ce8e37 100644
--- a/src/net/manaserv/abilityhandler.cpp
+++ b/src/net/manaserv/abilityhandler.cpp
@@ -50,7 +50,7 @@ void AbilityHandler::use(int id)
gameServerConnection->send(msg);
}
-void AbilityHandler::use(int id, int level, int beingId)
+void AbilityHandler::useOn(int id, int beingId)
{
MessageOut msg(PGMSG_USE_ABILITY_ON_BEING);
msg.writeInt8(id);
@@ -58,7 +58,7 @@ void AbilityHandler::use(int id, int level, int beingId)
gameServerConnection->send(msg);
}
-void AbilityHandler::use(int id, int level, int x, int y)
+void AbilityHandler::useAt(int id, int x, int y)
{
MessageOut msg(PGMSG_USE_ABILITY_ON_POINT);
msg.writeInt8(id);
@@ -67,9 +67,12 @@ void AbilityHandler::use(int id, int level, int x, int y)
gameServerConnection->send(msg);
}
-void AbilityHandler::use(int id, const std::string &map)
+void AbilityHandler::useInDirection(int id, int direction)
{
- // TODO
+ MessageOut msg(PGMSG_USE_ABILITY_ON_DIRECTION);
+ msg.writeInt8(id);
+ msg.writeInt8(direction);
+ gameServerConnection->send(msg);
}
} // namespace ManaServ
diff --git a/src/net/manaserv/abilityhandler.h b/src/net/manaserv/abilityhandler.h
index 69ab9c2b..e8263989 100644
--- a/src/net/manaserv/abilityhandler.h
+++ b/src/net/manaserv/abilityhandler.h
@@ -36,11 +36,11 @@ class AbilityHandler final : public MessageHandler, public Net::AbilityHandler
void use(int id) override;
- void use(int id, int level, int beingId) override;
+ void useOn(int id, int beingId) override;
- void use(int id, int level, int x, int y) override;
+ void useAt(int id, int x, int y) override;
- void use(int id, const std::string &map) override;
+ void useInDirection(int id, int direction) override;
};
} // namespace ManaServ
diff --git a/src/net/manaserv/beinghandler.cpp b/src/net/manaserv/beinghandler.cpp
index 186239c1..d8f47297 100644
--- a/src/net/manaserv/beinghandler.cpp
+++ b/src/net/manaserv/beinghandler.cpp
@@ -23,6 +23,7 @@
#include "actorspritemanager.h"
#include "being.h"
+#include "effectmanager.h"
#include "localplayer.h"
#include "gui/okdialog.h"
@@ -34,6 +35,8 @@
#include "net/manaserv/playerhandler.h"
#include "net/manaserv/manaserv_protocol.h"
+#include "playerrelations.h"
+#include "resources/emotedb.h"
#include "resources/hairdb.h"
#include "utils/gettext.h"
@@ -45,10 +48,13 @@ namespace ManaServ {
BeingHandler::BeingHandler()
{
static const Uint16 _messages[] = {
- GPMSG_BEING_ATTACK,
GPMSG_BEING_ENTER,
GPMSG_BEING_LEAVE,
+ GPMSG_BEING_EMOTE,
GPMSG_BEINGS_MOVE,
+ GPMSG_BEING_ABILITY_POINT,
+ GPMSG_BEING_ABILITY_BEING,
+ GPMSG_BEING_ABILITY_DIRECTION,
GPMSG_BEINGS_DAMAGE,
GPMSG_BEING_ACTION_CHANGE,
GPMSG_BEING_LOOKS_CHANGE,
@@ -68,11 +74,20 @@ void BeingHandler::handleMessage(MessageIn &msg)
case GPMSG_BEING_LEAVE:
handleBeingLeaveMessage(msg);
break;
+ case GPMSG_BEING_EMOTE:
+ handleBeingEmoteMessage(msg);
+ break;
case GPMSG_BEINGS_MOVE:
handleBeingsMoveMessage(msg);
break;
- case GPMSG_BEING_ATTACK:
- handleBeingAttackMessage(msg);
+ case GPMSG_BEING_ABILITY_POINT:
+ handleBeingAbilityPointMessage(msg);
+ break;
+ case GPMSG_BEING_ABILITY_BEING:
+ handleBeingAbilityBeingMessage(msg);
+ break;
+ case GPMSG_BEING_ABILITY_DIRECTION:
+ handleBeingAbilityDirectionMessage(msg);
break;
case GPMSG_BEINGS_DAMAGE:
handleBeingsDamageMessage(msg);
@@ -91,11 +106,15 @@ void BeingHandler::handleMessage(MessageIn &msg)
static void handleLooks(Being *being, MessageIn &msg)
{
- int lookChanges = msg.readInt8();
+ const int hairStyle = msg.readInt8();
+ const int hairColor = msg.readInt8();
+ being->setSprite(SPRITE_LAYER_HAIR, hairStyle * -1,
+ hairDB.getHairColor(hairColor));
- if (lookChanges <= 0)
+ if (msg.getUnreadLength() < 1)
return;
+ int lookChanges = msg.readInt8();
while (lookChanges-- > 0)
{
unsigned int slotTypeId = msg.readInt8();
@@ -113,14 +132,19 @@ void BeingHandler::handleBeingEnterMessage(MessageIn &msg)
int px = msg.readInt16();
int py = msg.readInt16();
auto direction = (BeingDirection)msg.readInt8();
- Gender gender;
- int genderAsInt = msg.readInt8();
- if (genderAsInt == GENDER_FEMALE)
- gender = Gender::FEMALE;
- else if (genderAsInt == GENDER_MALE)
+
+ Gender gender = Gender::UNSPECIFIED;
+ switch (getGender(msg.readInt8())) {
+ case GENDER_MALE:
gender = Gender::MALE;
- else
- gender = Gender::UNSPECIFIED;
+ break;
+ case GENDER_FEMALE:
+ gender = Gender::FEMALE;
+ break;
+ case GENDER_UNSPECIFIED:
+ break;
+ }
+
Being *being;
switch (type)
@@ -139,9 +163,7 @@ void BeingHandler::handleBeingEnterMessage(MessageIn &msg)
ActorSprite::PLAYER, 0);
being->setName(name);
}
- int hs = msg.readInt8(), hc = msg.readInt8();
- being->setSprite(SPRITE_LAYER_HAIR, hs * -1,
- hairDB.getHairColor(hc));
+
handleLooks(being, msg);
} break;
@@ -152,7 +174,8 @@ void BeingHandler::handleBeingEnterMessage(MessageIn &msg)
being = actorSpriteManager->createBeing(id, type == OBJECT_MONSTER
? ActorSprite::MONSTER : ActorSprite::NPC, subtype);
std::string name = msg.readString();
- if (name.length() > 0) being->setName(name);
+ if (!name.empty())
+ being->setName(name);
} break;
default:
@@ -175,6 +198,19 @@ void BeingHandler::handleBeingLeaveMessage(MessageIn &msg)
actorSpriteManager->destroyActor(being);
}
+void BeingHandler::handleBeingEmoteMessage(MessageIn &msg)
+{
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ if (!being)
+ return;
+
+ if (player_relations.hasPermission(being, PlayerPermissions::EMOTE))
+ {
+ const int fx = EmoteDB::get(msg.readInt8() - 1).effectId;
+ effectManager->trigger(fx, being);
+ }
+}
+
void BeingHandler::handleBeingsMoveMessage(MessageIn &msg)
{
while (msg.getUnreadLength())
@@ -235,18 +271,41 @@ void BeingHandler::handleBeingsMoveMessage(MessageIn &msg)
}
}
-void BeingHandler::handleBeingAttackMessage(MessageIn &msg)
+void BeingHandler::handleBeingAbilityPointMessage(MessageIn &msg)
{
Being *being = actorSpriteManager->findBeing(msg.readInt16());
- const auto direction = (BeingDirection) msg.readInt8();
- const int attackId = msg.readInt8();
+ if (!being)
+ return;
+
+ const int abilityId = msg.readInt8();
+ const int x = msg.readInt16();
+ const int y = msg.readInt16();
+
+ std::cout << "GPMSG_BEING_ABILITY_POINT(" << abilityId << ", " << x << ", " << y << ")" << std::endl;
+}
+void BeingHandler::handleBeingAbilityBeingMessage(MessageIn &msg)
+{
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
if (!being)
return;
- being->setDirection(direction);
+ const int abilityId = msg.readInt8();
+ const int targetId = msg.readInt16();
+
+ std::cout << "GPMSG_BEING_ABILITY_BEING(" << abilityId << ", " << targetId << ")" << std::endl;
+}
+
+void BeingHandler::handleBeingAbilityDirectionMessage(MessageIn &msg)
+{
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ if (!being)
+ return;
+
+ const int abilityId = msg.readInt8();
+ const int direction = msg.readInt8();
- being->setAction(Being::ATTACK, attackId);
+ std::cout << "GPMSG_BEING_ABILITY_DIRECTION(" << abilityId << ", " << direction << ")" << std::endl;
}
void BeingHandler::handleBeingsDamageMessage(MessageIn &msg)
@@ -306,14 +365,8 @@ void BeingHandler::handleBeingLooksChangeMessage(MessageIn &msg)
Being *being = actorSpriteManager->findBeing(msg.readInt16());
if (!being || being->getType() != ActorSprite::PLAYER)
return;
+
handleLooks(being, msg);
- if (msg.getUnreadLength())
- {
- int style = msg.readInt16();
- int color = msg.readInt16();
- being->setSprite(SPRITE_LAYER_HAIR, style * -1,
- hairDB.getHairColor(color));
- }
}
void BeingHandler::handleBeingDirChangeMessage(MessageIn &msg)
diff --git a/src/net/manaserv/beinghandler.h b/src/net/manaserv/beinghandler.h
index b906aedd..9580c284 100644
--- a/src/net/manaserv/beinghandler.h
+++ b/src/net/manaserv/beinghandler.h
@@ -43,10 +43,13 @@ class BeingHandler final : public MessageHandler
void handleMessage(MessageIn &msg) override;
private:
- void handleBeingAttackMessage(MessageIn &msg);
void handleBeingEnterMessage(MessageIn &msg);
void handleBeingLeaveMessage(MessageIn &msg);
+ void handleBeingEmoteMessage(MessageIn &msg);
void handleBeingsMoveMessage(MessageIn &msg);
+ void handleBeingAbilityPointMessage(MessageIn &msg);
+ void handleBeingAbilityBeingMessage(MessageIn &msg);
+ void handleBeingAbilityDirectionMessage(MessageIn &msg);
void handleBeingsDamageMessage(MessageIn &msg);
void handleBeingActionChangeMessage(MessageIn &msg);
void handleBeingLooksChangeMessage(MessageIn &msg);
diff --git a/src/net/manaserv/charhandler.cpp b/src/net/manaserv/charhandler.cpp
index 8a922e70..4d44aa93 100644
--- a/src/net/manaserv/charhandler.cpp
+++ b/src/net/manaserv/charhandler.cpp
@@ -99,28 +99,44 @@ void CharHandler::handleMessage(MessageIn &msg)
void CharHandler::handleCharacterInfo(MessageIn &msg)
{
- CachedCharacterInfo info;
- info.slot = msg.readInt8();
- info.name = msg.readString();
- info.gender = msg.readInt8() == ManaServ::GENDER_MALE ? Gender::MALE
- : Gender::FEMALE;
- info.hairStyle = msg.readInt8();
- info.hairColor = msg.readInt8();
- info.level = msg.readInt16();
- info.characterPoints = msg.readInt16();
- info.correctionPoints = msg.readInt16();
-
while (msg.getUnreadLength() > 0)
{
- int id = msg.readInt32();
- CachedAttrbiute attr;
- attr.base = msg.readInt32() / 256.0;
- attr.mod = msg.readInt32() / 256.0;
+ CachedCharacterInfo &info = mCachedCharacterInfos.emplace_back();
- info.attribute[id] = attr;
- }
+ info.slot = msg.readInt8();
+ info.name = msg.readString();
+ switch (getGender(msg.readInt8())) {
+ case GENDER_MALE:
+ info.gender = Gender::MALE;
+ break;
+ case GENDER_FEMALE:
+ info.gender = Gender::FEMALE;
+ break;
+ case GENDER_UNSPECIFIED:
+ info.gender = Gender::UNSPECIFIED;
+ break;
+ }
+ info.hairStyle = msg.readInt8();
+ info.hairColor = msg.readInt8();
+ info.characterPoints = msg.readInt16();
+ info.correctionPoints = msg.readInt16();
- mCachedCharacterInfos.push_back(info);
+ int equipmentCount = msg.readInt8();
+ while (equipmentCount--)
+ {
+ auto &slot = info.equipment.emplace_back();
+ slot.id = msg.readInt16();
+ slot.itemId = msg.readInt16();
+ }
+
+ int attributeCount = msg.readInt8();
+ while (attributeCount--)
+ {
+ CachedAttribute &attr = info.attributes[msg.readInt32()];
+ attr.base = msg.readInt32() / 256.0;
+ attr.mod = msg.readInt32() / 256.0;
+ }
+ }
updateCharacters();
}
@@ -182,6 +198,8 @@ void CharHandler::handleCharacterCreateResponse(MessageIn &msg)
}
else
{
+ handleCharacterInfo(msg);
+
// Close the character create dialog
if (mCharCreateDialog)
{
@@ -380,10 +398,8 @@ void CharHandler::updateCharacters()
return;
// Create new characters and initialize them from the cached infos
- for (unsigned i = 0; i < mCachedCharacterInfos.size(); ++i)
+ for (const auto &info : mCachedCharacterInfos)
{
- const CachedCharacterInfo &info = mCachedCharacterInfos.at(i);
-
auto *character = new Net::Character;
character->slot = info.slot;
LocalPlayer *player = character->dummy = new LocalPlayer;
@@ -391,14 +407,30 @@ void CharHandler::updateCharacters()
player->setGender(info.gender);
player->setSprite(SPRITE_LAYER_HAIR, info.hairStyle * -1,
hairDB.getHairColor(info.hairColor));
- character->data.mAttributes[LEVEL] = info.level;
+
+ for (auto &slot : info.equipment)
+ {
+ player->setSprite(slot.id + FIXED_SPRITE_LAYER_SIZE,
+ slot.itemId,
+ std::string(),
+ Net::getInventoryHandler()->isWeaponSlot(slot.id));
+ }
+
character->data.mAttributes[CHAR_POINTS] = info.characterPoints;
character->data.mAttributes[CORR_POINTS] = info.correctionPoints;
- for (const auto &it : info.attribute)
+ for (const auto &[id, attr] : info.attributes)
{
- character->data.mStats[i].base = it.second.base;
- character->data.mStats[i].mod = it.second.mod;
+ int playerInfoId = Attributes::getPlayerInfoIdFromAttrId(id);
+ if (playerInfoId > -1)
+ {
+ character->data.mAttributes[playerInfoId] = attr.mod;
+ }
+ else
+ {
+ character->data.mStats[id].base = attr.base;
+ character->data.mStats[id].mod = attr.mod;
+ }
}
mCharacters.push_back(character);
diff --git a/src/net/manaserv/charhandler.h b/src/net/manaserv/charhandler.h
index d83ce667..e962bdfa 100644
--- a/src/net/manaserv/charhandler.h
+++ b/src/net/manaserv/charhandler.h
@@ -88,12 +88,15 @@ class CharHandler final : public MessageHandler, public Net::CharHandler
* we have loaded the dynamic data, so we can't resolve load any
* sprites yet.
*/
- struct CachedAttrbiute {
+ struct CachedAttribute {
double base;
double mod;
};
- using CachedAttributes = std::map<int, CachedAttrbiute>;
+ struct EquipmentSlot {
+ int id;
+ int itemId;
+ };
struct CachedCharacterInfo {
int slot;
@@ -101,10 +104,10 @@ class CharHandler final : public MessageHandler, public Net::CharHandler
Gender gender;
int hairStyle;
int hairColor;
- int level;
int characterPoints;
int correctionPoints;
- CachedAttributes attribute;
+ std::vector<EquipmentSlot> equipment;
+ std::map<int, CachedAttribute> attributes;
};
void handleCharacterInfo(MessageIn &msg);
diff --git a/src/net/manaserv/gamehandler.cpp b/src/net/manaserv/gamehandler.cpp
index 1bf4d69f..3dae5640 100644
--- a/src/net/manaserv/gamehandler.cpp
+++ b/src/net/manaserv/gamehandler.cpp
@@ -44,6 +44,7 @@ extern ServerInfo chatServer;
GameHandler::GameHandler()
{
static const Uint16 _messages[] = {
+ GPMSG_CONNECT_RESPONSE,
GPMSG_DISCONNECT_RESPONSE,
0
};
@@ -55,6 +56,9 @@ void GameHandler::handleMessage(MessageIn &msg)
{
switch (msg.getId())
{
+ case GPMSG_CONNECT_RESPONSE:
+ break;
+
case GPMSG_DISCONNECT_RESPONSE:
{
int errMsg = msg.readInt8();
diff --git a/src/net/manaserv/generalhandler.cpp b/src/net/manaserv/generalhandler.cpp
index 1e443c66..b947cff4 100644
--- a/src/net/manaserv/generalhandler.cpp
+++ b/src/net/manaserv/generalhandler.cpp
@@ -182,7 +182,7 @@ void GeneralHandler::event(Event::Channel channel,
{
if (event.getType() == Event::GuiWindowsLoaded)
{
- inventoryWindow->setSplitAllowed(true);
+ inventoryWindow->setSplitAllowed(false);
skillDialog->loadSkills();
PlayerInfo::setAttribute(EXP_NEEDED, 100);
diff --git a/src/net/manaserv/inventoryhandler.cpp b/src/net/manaserv/inventoryhandler.cpp
index 9754beb0..0e822ca0 100644
--- a/src/net/manaserv/inventoryhandler.cpp
+++ b/src/net/manaserv/inventoryhandler.cpp
@@ -43,16 +43,6 @@ extern Net::InventoryHandler *inventoryHandler;
namespace ManaServ {
-struct EquipItemInfo
-{
-
- EquipItemInfo(int itemId, int slotTypeId, int amountUsed):
- mItemId(itemId), mSlotTypeId(slotTypeId), mAmountUsed(amountUsed)
- {}
-
- int mItemId, mSlotTypeId, mAmountUsed;
-};
-
extern Connection *gameServerConnection;
EquipBackend::EquipBackend()
@@ -69,7 +59,10 @@ EquipBackend::~EquipBackend()
Item *EquipBackend::getEquipment(int slotIndex) const
{
auto it = mSlots.find(slotIndex);
- return it == mSlots.end() ? nullptr : it->second.item;
+ if (it == mSlots.end())
+ return nullptr;
+
+ return PlayerInfo::getInventory()->getItem(it->second.inventorySlot);
}
std::string EquipBackend::getSlotName(int slotIndex) const
@@ -80,111 +73,54 @@ std::string EquipBackend::getSlotName(int slotIndex) const
void EquipBackend::triggerUnequip(int slotIndex) const
{
- // First get the itemInstance
- auto it = mSlots.find(slotIndex);
-
- if (it == mSlots.end() || it->second.itemInstance == 0 || !it->second.item)
+ auto item = getEquipment(slotIndex);
+ if (!item)
return;
Event event(Event::DoUnequip);
- event.setItem("item", it->second.item);
- event.setInt("itemInstance", it->second.itemInstance);
+ event.setItem("item", item);
event.trigger(Event::ItemChannel);
}
-
void EquipBackend::clear()
{
- for (auto &slot : mSlots)
- {
- if (slot.second.item)
- {
- delete slot.second.item;
- slot.second.item = nullptr;
- }
- }
mSlots.clear();
}
-void EquipBackend::equip(int itemId, int slotTypeId, int amountUsed,
- int itemInstance)
+void EquipBackend::equip(int inventorySlot, int equipmentSlot)
{
- if (itemInstance <= 0)
- {
- logger->log("ManaServ::EquipBackend: Equipment slot %i"
- " has an invalid item instance.", slotTypeId);
- return;
- }
-
- auto it = mSlots.begin();
- auto it_end = mSlots.end();
- bool slotTypeFound = false;
- for (; it != it_end; ++it)
- if (it->second.slotTypeId == (unsigned)slotTypeId)
- slotTypeFound = true;
-
- if (!slotTypeFound)
+ auto slotIt = mSlots.find(equipmentSlot);
+ if (slotIt == mSlots.end())
{
logger->log("ManaServ::EquipBackend: Equipment slot %i"
- " is not existing.", slotTypeId);
+ " is not existing.",
+ equipmentSlot);
return;
}
- if (!itemDb->exists(itemId))
- {
- logger->log("ManaServ::EquipBackend: No item with id %d",
- itemId);
- return;
- }
+ slotIt->second.inventorySlot = inventorySlot;
- // Place the item in the slots with corresponding id until
- // the capacity requested has been reached
- for (it = mSlots.begin(); it != it_end && amountUsed > 0; ++it)
- {
- // If we're on the right slot type and that its unit
- // isn't already equipped, we can equip there.
- // The slots are already sorted by id, and subId anyway.
- if (it->second.slotTypeId == (unsigned)slotTypeId
- && (!it->second.itemInstance) && (!it->second.item))
- {
- it->second.itemInstance = itemInstance;
- it->second.item = new Item(itemId, 1, true);
- --amountUsed;
- }
- }
+ if (auto item = PlayerInfo::getInventory()->getItem(inventorySlot))
+ item->setEquipped(true);
}
-void EquipBackend::unequip(int itemInstance)
+void EquipBackend::unequip(int inventorySlot)
{
- auto it = mSlots.begin();
- auto it_end = mSlots.end();
- bool itemInstanceFound = false;
- for (; it != it_end; ++it)
- if (it->second.itemInstance == (unsigned)itemInstance)
- itemInstanceFound = true;
-
- if (!itemInstanceFound)
+ for (auto &[_, slot] : mSlots)
{
- logger->log("ManaServ::EquipBackend: Equipment item instance %i"
- " is not existing. The item couldn't be unequipped!",
- itemInstance);
- return;
- }
+ if (slot.inventorySlot == inventorySlot)
+ {
+ slot.inventorySlot = -1;
- for (it = mSlots.begin(); it != it_end; ++it)
- {
- if (it->second.itemInstance != (unsigned)itemInstance)
- continue;
+ if (auto item = PlayerInfo::getInventory()->getItem(inventorySlot))
+ item->setEquipped(false);
- // We remove the item
- it->second.itemInstance = 0;
- // We also delete the item objects
- if (it->second.item)
- {
- delete it->second.item;
- it->second.item = nullptr;
+ return;
}
}
+
+ logger->log("ManaServ::EquipBackend: No equipped item found at inventory "
+ "slot %i!", inventorySlot);
}
void EquipBackend::event(Event::Channel, const Event &event)
@@ -245,7 +181,7 @@ void EquipBackend::readEquipFile()
}
slot.subId = i;
- mSlots.insert(std::make_pair(slotIndex, slot));
+ mSlots.insert(std::make_pair(slotIndex, std::move(slot)));
++slotIndex;
}
}
@@ -262,10 +198,10 @@ void EquipBackend::readBoxNode(XML::Node slotNode)
if (boxNode.name() != "box")
continue;
- int x = boxNode.getProperty("x" , 0);
- int y = boxNode.getProperty("y" , 0);
+ const int x = boxNode.getProperty("x" , 0);
+ const int y = boxNode.getProperty("y" , 0);
- mBoxesPositions.push_back(Position(x, y));
+ mBoxesPositions.emplace_back(x, y);
std::string backgroundFile =
boxNode.getProperty("background" , std::string());
@@ -313,6 +249,7 @@ InventoryHandler::InventoryHandler()
GPMSG_INVENTORY_FULL,
GPMSG_INVENTORY,
GPMSG_EQUIP,
+ GPMSG_UNEQUIP,
0
};
handledMessages = _messages;
@@ -331,43 +268,16 @@ void InventoryHandler::handleMessage(MessageIn &msg)
int count = msg.readInt16();
while (count--)
{
- int slot = msg.readInt16();
- int id = msg.readInt16();
- int amount = msg.readInt16();
- PlayerInfo::setInventoryItem(slot, id, amount);
- }
-
- // A map of { item instance, {slot type id, item id, amount used}}
- std::map<int, EquipItemInfo> equipItemsInfo;
- std::map<int, EquipItemInfo>::iterator it;
- while (msg.getUnreadLength())
- {
- int slotTypeId = msg.readInt16();
- int itemId = msg.readInt16();
- int itemInstance = msg.readInt16();
-
- // Turn the data received into a usable format
- it = equipItemsInfo.find(itemInstance);
- if (it == equipItemsInfo.end())
- {
- // Add a new entry
- equipItemsInfo.insert(std::make_pair(itemInstance,
- EquipItemInfo(itemId, slotTypeId, 1)));
- }
+ const int slot = msg.readInt16();
+ const int itemId = msg.readInt16();
+ const int amount = msg.readInt16();
+ const int equipmentSlot = msg.readInt16();
+ PlayerInfo::setInventoryItem(slot, itemId, amount);
+
+ if (equipmentSlot > 0)
+ mEquipBackend.equip(slot, equipmentSlot);
else
- {
- // Add amount to the existing entry
- it->second.mAmountUsed++;
- }
- }
-
- for (it = equipItemsInfo.begin(); it != equipItemsInfo.end();
- ++it)
- {
- mEquipBackend.equip(it->second.mItemId,
- it->second.mSlotTypeId,
- it->second.mAmountUsed,
- it->first);
+ mEquipBackend.unequip(slot);
}
}
break;
@@ -375,43 +285,24 @@ void InventoryHandler::handleMessage(MessageIn &msg)
case GPMSG_INVENTORY:
while (msg.getUnreadLength())
{
- unsigned int slot = msg.readInt16();
- int id = msg.readInt16();
- unsigned int amount = id ? msg.readInt16() : 0;
+ const unsigned int slot = msg.readInt16();
+ const int id = msg.readInt16();
+ const unsigned int amount = id ? msg.readInt16() : 0;
PlayerInfo::setInventoryItem(slot, id, amount);
}
break;
case GPMSG_EQUIP:
{
- int itemId = msg.readInt16();
- int equipSlotCount = msg.readInt16();
-
- if (equipSlotCount <= 0)
- break;
-
- // Otherwise equip the item in the given slots
- while (equipSlotCount--)
- {
- unsigned int parameter = msg.readInt16();
- unsigned int amountUsed = msg.readInt16();
-
- if (amountUsed == 0)
- {
- // No amount means to unequip this item
- // Note that in that case, the parameter is
- // in fact the itemInstanceId
- mEquipBackend.unequip(parameter);
- }
- else
- {
- int itemInstance = msg.readInt16();
- // The parameter is in that case the slot type id.
- mEquipBackend.equip(itemId, parameter,
- amountUsed, itemInstance);
- }
- }
+ const int inventorySlot = msg.readInt16();
+ const int equipmentSlot = msg.readInt16();
+ mEquipBackend.equip(inventorySlot, equipmentSlot);
+ }
+ case GPMSG_UNEQUIP:
+ {
+ const int inventorySlot = msg.readInt16();
+ mEquipBackend.unequip(inventorySlot);
}
break;
}
@@ -423,9 +314,7 @@ void InventoryHandler::event(Event::Channel channel,
if (channel == Event::ItemChannel)
{
Item *item = event.getItem("item");
- int itemInstance = event.getInt("itemInstance", 0);
-
- if (!item && itemInstance == 0)
+ if (!item)
return;
int index = item->getInvIndex();
@@ -439,7 +328,7 @@ void InventoryHandler::event(Event::Channel channel,
else if (event.getType() == Event::DoUnequip)
{
MessageOut msg(PGMSG_UNEQUIP);
- msg.writeInt16(itemInstance);
+ msg.writeInt16(index);
gameServerConnection->send(msg);
}
else if (event.getType() == Event::DoUse)
@@ -457,51 +346,12 @@ void InventoryHandler::event(Event::Channel channel,
msg.writeInt16(amount);
gameServerConnection->send(msg);
}
- else if (event.getType() == Event::DoSplit)
- {
- int amount = event.getInt("amount", 1);
-
- int newIndex = PlayerInfo::getInventory()->getFreeSlot();
- if (newIndex > Inventory::NO_SLOT_INDEX)
- {
- MessageOut msg(PGMSG_MOVE_ITEM);
- msg.writeInt16(index);
- msg.writeInt16(newIndex);
- msg.writeInt16(amount);
- gameServerConnection->send(msg);
- }
- }
- else if (event.getType() == Event::DoMove)
- {
- int newIndex = event.getInt("newIndex", -1);
-
- if (newIndex >= 0)
- {
- if (index == newIndex)
- return;
-
- MessageOut msg(PGMSG_MOVE_ITEM);
- msg.writeInt16(index);
- msg.writeInt16(newIndex);
- msg.writeInt16(item->getQuantity());
- gameServerConnection->send(msg);
- }
- else
- {
- /*int source = event.getInt("source");
- int destination = event.getInt("destination");
- int amount = event.getInt("amount", 1);*/
-
- // TODO Support drag'n'drop to the map ground, or with other
- // windows.
- }
- }
}
}
bool InventoryHandler::canSplit(const Item *item)
{
- return item && item->getQuantity() > 1;
+ return false;
}
size_t InventoryHandler::getSize(int type) const
diff --git a/src/net/manaserv/inventoryhandler.h b/src/net/manaserv/inventoryhandler.h
index 98e02391..9402f349 100644
--- a/src/net/manaserv/inventoryhandler.h
+++ b/src/net/manaserv/inventoryhandler.h
@@ -27,6 +27,7 @@
#include "net/manaserv/messagehandler.h"
+#include <map>
#include <vector>
namespace ManaServ {
@@ -35,16 +36,14 @@ class EquipBackend final : public Equipment::Backend, public EventListener
{
public:
EquipBackend();
-
~EquipBackend() override;
Item *getEquipment(int slotIndex) const override;
std::string getSlotName(int slotIndex) const override;
void clear() override;
- void equip(int itemId, int slotTypeId, int amountUsed = 1,
- int itemInstance = 0);
- void unequip(int slotTypeId);
+ void equip(int inventorySlot, int equipmentSlot);
+ void unequip(int inventorySlot);
void event(Event::Channel channel, const Event &event) override;
@@ -72,9 +71,7 @@ class EquipBackend final : public Equipment::Backend, public EventListener
// Generic info
std::string name;
- // The Item reference, used for graphical representation
- // and info.
- Item *item = nullptr;
+ int inventorySlot = 0;
// Manaserv specific info
@@ -88,10 +85,6 @@ class EquipBackend final : public Equipment::Backend, public EventListener
// This is used to sort the multimap along with the slot id.
unsigned int subId = 0;
- // This is the (per character) unique item Id, used especially when
- // equipping the same item multiple times on the same slot type.
- unsigned int itemInstance = 0;
-
// Tell whether the slot is a weapon slot
bool weaponSlot = false;
@@ -102,8 +95,7 @@ class EquipBackend final : public Equipment::Backend, public EventListener
unsigned int mVisibleSlots;
// slot client index, slot info
- using Slots = std::map<unsigned int, Slot>;
- Slots mSlots;
+ std::map<unsigned int, Slot> mSlots;
std::vector<Position> mBoxesPositions;
std::vector<std::string> mBoxesBackgroundFile;
};
diff --git a/src/net/manaserv/loginhandler.cpp b/src/net/manaserv/loginhandler.cpp
index b9a56834..1c398990 100644
--- a/src/net/manaserv/loginhandler.cpp
+++ b/src/net/manaserv/loginhandler.cpp
@@ -399,8 +399,6 @@ void LoginHandler::loginAccount(LoginData *loginData)
mTmpPassword = loginData->password;
MessageOut msg(PAMSG_LOGIN_RNDTRGR);
- msg.writeString(mLoginData->username);
-
accountServerConnection->send(msg);
}
diff --git a/src/net/manaserv/manaserv_protocol.h b/src/net/manaserv/manaserv_protocol.h
index ab81846b..cb27d6f4 100644
--- a/src/net/manaserv/manaserv_protocol.h
+++ b/src/net/manaserv/manaserv_protocol.h
@@ -24,8 +24,9 @@
namespace ManaServ {
enum {
- PROTOCOL_VERSION = 3,
- SUPPORTED_DB_VERSION = 22
+ PROTOCOL_VERSION = 9,
+ MIN_PROTOCOL_VERSION = 9,
+ SUPPORTED_DB_VERSION = 27
};
/**
@@ -68,19 +69,22 @@ enum {
PAMSG_REQUEST_REGISTER_INFO = 0x0005, //
APMSG_REGISTER_INFO_RESPONSE = 0x0006, // B byte registration Allowed, byte minNameLength, byte maxNameLength, string captchaURL, string captchaInstructions
PAMSG_LOGIN = 0x0010, // D version, S username, S password
- APMSG_LOGIN_RESPONSE = 0x0012, // B error, S updatehost, S Client data URL, B Character slots
+ APMSG_LOGIN_RESPONSE = 0x0012, // B error, S updatehost, S Client data URL, B Character slots, {content of APMSG_CHAR_CREATE_RESPONSE (without error code)}*
PAMSG_LOGOUT = 0x0013, // -
APMSG_LOGOUT_RESPONSE = 0x0014, // B error
- PAMSG_LOGIN_RNDTRGR = 0x0015, // S username
+ PAMSG_LOGIN_RNDTRGR = 0x0015, // -
APMSG_LOGIN_RNDTRGR_RESPONSE = 0x0016, // S random seed
+ PAMSG_STELLAR_LOGIN = 0x0017, // D version
+ APMSG_STELLAR_LOGIN_RESPONSE = 0x0018, // B error, S token, S url
PAMSG_CHAR_CREATE = 0x0020, // S name, B hair style, B hair color, B gender, B slot, {W stats}*
- APMSG_CHAR_CREATE_RESPONSE = 0x0021, // B error
+ APMSG_CHAR_CREATE_RESPONSE = 0x0021, // B error, on success: B slot, S name, B gender, B hair style, B hair color,
+ // W character points, W correction points, B amount of items equipped,
+ // { W slot, W itemId }*
+ // B attributeCount,
+ // {D attr id, D base value (in 1/256ths) D mod value (in 256ths) }*
PAMSG_CHAR_DELETE = 0x0022, // B slot
APMSG_CHAR_DELETE_RESPONSE = 0x0023, // B error
- // B slot, S name, B gender, B hair style, B hair color, W level,
- // W character points, W correction points,
- // {D attr id, D base value (in 1/256ths) D mod value (in 256ths) }*
- APMSG_CHAR_INFO = 0x0024, // ^
+ APMSG_CHAR_INFO = 0x0024, // {content of APMSG_CHAR_CREATE_RESPONSE (without error code)}*
PAMSG_CHAR_SELECT = 0x0026, // B slot
APMSG_CHAR_SELECT_RESPONSE = 0x0027, // B error, B*32 token, S game address, W game port, S chat address, W chat port
PAMSG_EMAIL_CHANGE = 0x0030, // S email
@@ -108,26 +112,28 @@ enum {
PGMSG_DROP = 0x0111, // W slot, W amount
PGMSG_EQUIP = 0x0112, // W inventory slot
PGMSG_UNEQUIP = 0x0113, // W item Instance id
- PGMSG_MOVE_ITEM = 0x0114, // W slot1, W slot2, W amount
GPMSG_INVENTORY = 0x0120, // { W slot, W item id [, W amount] (if item id is nonzero) }*
- GPMSG_INVENTORY_FULL = 0x0121, // W inventory slot count { W slot, W itemId, W amount }, { W equip slot, W item Id, W item Instance}*
- GPMSG_EQUIP = 0x0122, // W item Id, W equip slot type count //{ W equip slot, W capacity used}*//<- When equipping, //{ W item instance, W 0}*//<- When unequipping
+ GPMSG_INVENTORY_FULL = 0x0121, // W inventory slot count { W slot, W itemId, W amount, W equipmentSlot }
+ GPMSG_EQUIP = 0x0122, // W equipped inventory slot, W slot equipmentSlot
+ GPMSG_EQUIP_RESPONSE = 0x0123, // B error, W slot
+ GPMSG_UNEQUIP = 0x0124, // W equipped inventory slot
+ GPMSG_UNEQUIP_RESPONSE = 0x0125, // B error, W slot
GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { W attribute, D base value (in 1/256ths), D modified value (in 1/256ths)}*
- GPMSG_PLAYER_EXP_CHANGE = 0x0140, // { W skill, D exp got, D exp needed, W skill level }*
- GPMSG_LEVELUP = 0x0150, // W new level, W character points, W correction points
- GPMSG_LEVEL_PROGRESS = 0x0151, // B percent completed to next levelup
+ GPMSG_ATTRIBUTE_POINTS_STATUS = 0x0140, // W character points, W correction points
PGMSG_RAISE_ATTRIBUTE = 0x0160, // W attribute
GPMSG_RAISE_ATTRIBUTE_RESPONSE = 0x0161, // B error, W attribute
PGMSG_LOWER_ATTRIBUTE = 0x0170, // W attribute
GPMSG_LOWER_ATTRIBUTE_RESPONSE = 0x0171, // B error, W attribute
PGMSG_RESPAWN = 0x0180, // -
GPMSG_BEING_ENTER = 0x0200, // B type, W being id, B action, W*2 position, B direction, B gender
- // character: S name, B hair style, B hair color, B sprite layers changed, { B slot type, W item id }*
+ // character: S name, B hair style, B hair color [, B sprite layers changed, { B slot type, W item id }*]
// monster: W type id
// npc: W type id
GPMSG_BEING_LEAVE = 0x0201, // W being id
GPMSG_ITEM_APPEAR = 0x0202, // W item id, W*2 position
- GPMSG_BEING_LOOKS_CHANGE = 0x0210, // B sprite layers changed, { B slot type, W item id }*
+ GPMSG_BEING_LOOKS_CHANGE = 0x0210, // B hairstyle, B haircolor [, B sprite layers changed, { B slot type, W item id }*]
+ GPMSG_BEING_EMOTE = 0x0211, // W being id, W emote id
+ PGMSG_BEING_EMOTE = 0x0212, // W emoticon id
PGMSG_WALK = 0x0260, // W*2 destination
PGMSG_ACTION_CHANGE = 0x0270, // B Action
GPMSG_BEING_ACTION_CHANGE = 0x0271, // W being id, B action
@@ -136,46 +142,50 @@ enum {
GPMSG_BEING_HEALTH_CHANGE = 0x0274, // W being id, W hp, W max hp
GPMSG_BEINGS_MOVE = 0x0280, // { W being id, B flags [, [W*2 position,] W*2 destination, B speed] }*
GPMSG_ITEMS = 0x0281, // { W item id, W*2 position }*
- PGMSG_ATTACK = 0x0290, // W being id
- GPMSG_BEING_ATTACK = 0x0291, // W being id, B direction, B attack Id
- PGMSG_USE_ABILITY_ON_BEING = 0x0292, // B abilityID, W being id
- GPMSG_ABILITY_STATUS = 0x0293, // { B abilityID, D current, D max, D recharge }
- PGMSG_USE_ABILITY_ON_POINT = 0x0294, // B abilityID, W*2 position
- GPMSG_ABILITY_REMOVED = 0x0295, // B abilityID
- PGMSG_SAY = 0x02A0, // S text
- GPMSG_SAY = 0x02A1, // W being id, S text
- GPMSG_NPC_CHOICE = 0x02B0, // W being id, { S text }*
- GPMSG_NPC_MESSAGE = 0x02B1, // W being id, B* text
- PGMSG_NPC_TALK = 0x02B2, // W being id
- PGMSG_NPC_TALK_NEXT = 0x02B3, // W being id
- PGMSG_NPC_SELECT = 0x02B4, // W being id, B choice
- GPMSG_NPC_BUY = 0x02B5, // W being id, { W item id, W amount, W cost }*
- GPMSG_NPC_SELL = 0x02B6, // W being id, { W item id, W amount, W cost }*
- PGMSG_NPC_BUYSELL = 0x02B7, // W item id, W amount
- GPMSG_NPC_ERROR = 0x02B8, // B error
- GPMSG_NPC_CLOSE = 0x02B9, // W being id
+ GPMSG_BEING_ABILITY_POINT = 0x0282, // W being id, B abilityId, W*2 point
+ GPMSG_BEING_ABILITY_BEING = 0x0283, // W being id, B abilityId, W target being id
+ GPMSG_BEING_ABILITY_DIRECTION = 0x0284, // W being id, B abilityId, B direction
+ PGMSG_USE_ABILITY_ON_BEING = 0x0290, // B abilityID, W being id
+ PGMSG_USE_ABILITY_ON_POINT = 0x0291, // B abilityID, W*2 position
+ PGMSG_USE_ABILITY_ON_DIRECTION = 0x0292, // B abilityID, B direction
+ GPMSG_ABILITY_STATUS = 0x02A0, // { B abilityID, D remainingTicks }
+ GPMSG_ABILITY_REMOVED = 0x02A1, // B abilityID
+ GPMSG_ABILITY_COOLDOWN = 0x02A2, // W ticks to wait
+ PGMSG_SAY = 0x02B0, // S text
+ GPMSG_SAY = 0x02B1, // W being id, S text
+ GPMSG_NPC_CHOICE = 0x02C0, // W being id, { S text }*
+ GPMSG_NPC_MESSAGE = 0x02C1, // W being id, B* text
+ PGMSG_NPC_TALK = 0x02C2, // W being id
+ PGMSG_NPC_TALK_NEXT = 0x02C3, // W being id
+ PGMSG_NPC_SELECT = 0x02C4, // W being id, B choice
+ GPMSG_NPC_BUY = 0x02C5, // W being id, { W item id, W amount, W cost }*
+ GPMSG_NPC_SELL = 0x02C6, // W being id, { W item id, W amount, W cost }*
+ PGMSG_NPC_BUYSELL = 0x02C7, // W item id, W amount
+ GPMSG_NPC_ERROR = 0x02C8, // B error
+ GPMSG_NPC_CLOSE = 0x02C9, // W being id
GPMSG_NPC_POST = 0x02D0, // W being id
PGMSG_NPC_POST_SEND = 0x02D1, // W being id, { S name, S text, W item id }
GPMSG_NPC_POST_GET = 0x02D2, // W being id, { S name, S text, W item id }
PGMSG_NPC_NUMBER = 0x02D3, // W being id, D number
PGMSG_NPC_STRING = 0x02D4, // W being id, S string
- GPMSG_NPC_NUMBER = 0x02D5, // W being id, D max, D min, D default
+ GPMSG_NPC_NUMBER = 0x02D5, // W being id, D min, D max, D default
GPMSG_NPC_STRING = 0x02D6, // W being id
- PGMSG_TRADE_REQUEST = 0x02C0, // W being id
- GPMSG_TRADE_REQUEST = 0x02C1, // W being id
- GPMSG_TRADE_START = 0x02C2, // -
- GPMSG_TRADE_COMPLETE = 0x02C3, // -
- PGMSG_TRADE_CANCEL = 0x02C4, // -
- GPMSG_TRADE_CANCEL = 0x02C5, // -
- PGMSG_TRADE_AGREED = 0x02C6, // -
- GPMSG_TRADE_AGREED = 0x02C7, // -
- PGMSG_TRADE_CONFIRM = 0x02C8, // -
- GPMSG_TRADE_CONFIRM = 0x02C9, // -
- PGMSG_TRADE_ADD_ITEM = 0x02CA, // B slot, B amount
- GPMSG_TRADE_ADD_ITEM = 0x02CB, // W item id, B amount
- PGMSG_TRADE_SET_MONEY = 0x02CC, // D amount
- GPMSG_TRADE_SET_MONEY = 0x02CD, // D amount
- GPMSG_TRADE_BOTH_CONFIRM = 0x02CE, // -
+ GPMSG_NPC_BUYSELL_RESPONSE = 0x02D7, // B error, W item id, W amount
+ PGMSG_TRADE_REQUEST = 0x02E0, // W being id
+ GPMSG_TRADE_REQUEST = 0x02E1, // W being id
+ GPMSG_TRADE_START = 0x02E2, // -
+ GPMSG_TRADE_COMPLETE = 0x02E3, // -
+ PGMSG_TRADE_CANCEL = 0x02E4, // -
+ GPMSG_TRADE_CANCEL = 0x02E5, // -
+ PGMSG_TRADE_AGREED = 0x02E6, // -
+ GPMSG_TRADE_AGREED = 0x02E7, // -
+ PGMSG_TRADE_CONFIRM = 0x02E8, // -
+ GPMSG_TRADE_CONFIRM = 0x02E9, // -
+ PGMSG_TRADE_ADD_ITEM = 0x02EA, // B slot, B amount
+ GPMSG_TRADE_ADD_ITEM = 0x02EB, // W item id, B amount
+ PGMSG_TRADE_SET_MONEY = 0x02EC, // D amount
+ GPMSG_TRADE_SET_MONEY = 0x02ED, // D amount
+ GPMSG_TRADE_BOTH_CONFIRM = 0x02EE, // -
PGMSG_USE_ITEM = 0x0300, // B slot
GPMSG_USE_RESPONSE = 0x0301, // B error
GPMSG_BEINGS_DAMAGE = 0x0310, // { W being id, W amount }*
@@ -243,8 +253,11 @@ enum {
PCMSG_USER_MODE = 0x0465, // W channel id, S name, B mode
PCMSG_KICK_USER = 0x0466, // W channel id, S name
+ // -- Questlog
+ GPMSG_QUESTLOG_STATUS = 0x0470, // {W quest id, B flags, [B status], [S questname], [S questdescription]}*
+
// Inter-server
- GAMSG_REGISTER = 0x0500, // S address, W port, S password, D items db revision, { W map id }*
+ GAMSG_REGISTER = 0x0500, // S address, W port, S password, D items db revision
AGMSG_REGISTER_RESPONSE = 0x0501, // W item version, W password response, { S globalvar_key, S globalvar_value }
AGMSG_ACTIVE_MAP = 0x0502, // W map id, W Number of mapvar_key mapvar_value sent, { S mapvar_key, S mapvar_value }, W Number of map items, { D item Id, W amount, W posX, W posY }
AGMSG_PLAYER_ENTER = 0x0510, // B*32 token, D id, S name, serialised character data
@@ -263,7 +276,6 @@ enum {
GAMSG_SET_VAR_WORLD = 0x0547, // S name, S value
AGMSG_SET_VAR_WORLD = 0x0548, // S name, S value
GAMSG_BAN_PLAYER = 0x0550, // D id, W duration
- GAMSG_CHANGE_PLAYER_LEVEL = 0x0555, // D id, W level
GAMSG_CHANGE_ACCOUNT_LEVEL = 0x0556, // D id, W level
GAMSG_STATISTICS = 0x0560, // { W map id, W entity nb, W monster nb, W player nb, { D character id }* }*
CGMSG_CHANGED_PARTY = 0x0590, // D character id, D party id
@@ -295,7 +307,8 @@ enum {
ERRMSG_TIME_OUT, // data failed to arrive in due time
ERRMSG_LIMIT_REACHED, // limit reached
ERRMSG_ADMINISTRATIVE_LOGOFF, // kicked by server administrator
- ERRMSG_ALREADY_MEMBER // is already member of guild/party
+ ERRMSG_ALREADY_MEMBER, // is already member of guild/party
+ ERRMSG_LOGIN_WAS_TAKEN_OVER // a different connection took over
};
// used in AGMSG_REGISTER_RESPONSE to show state of item db
@@ -314,7 +327,6 @@ enum {
enum {
SYNC_CHARACTER_POINTS = 0x01, // D charId, D charPoints, D corrPoints
SYNC_CHARACTER_ATTRIBUTE = 0x02, // D charId, D attrId, DF base, DF mod
- SYNC_CHARACTER_SKILL = 0x03, // D charId, B skillId, D skill value
SYNC_ONLINE_STATUS = 0x04 // D charId, B 0 = offline, 1 = online
};
@@ -358,21 +370,18 @@ enum AttribmodResponseCode {
enum EntityType
{
// A simple item.
- OBJECT_ITEM = 0,
- // An item that toggle map/quest actions (doors, switchs, ...)
- // and can speak (map panels).
- OBJECT_ACTOR,
+ OBJECT_ITEM = 0,
// Non-Playable-Character is an actor capable of movement and maybe actions.
- OBJECT_NPC,
+ OBJECT_NPC = 2,
// A monster (moving actor with AI. Should be able to toggle map/quest
// actions, too).
- OBJECT_MONSTER,
+ OBJECT_MONSTER = 3,
// A normal being.
- OBJECT_CHARACTER,
+ OBJECT_CHARACTER = 4,
// A effect to be shown.
- OBJECT_EFFECT,
+ OBJECT_EFFECT = 5,
// Server-only object.
- OBJECT_OTHER
+ OBJECT_OTHER = 6
};
// Moving object flags
@@ -406,6 +415,13 @@ enum {
GUILD_EVENT_OFFLINE_PLAYER
};
+enum {
+ QUESTLOG_UPDATE_STATE = 1,
+ QUESTLOG_UPDATE_TITLE = 2,
+ QUESTLOG_UPDATE_DESCRIPTION = 4,
+ QUESTLOG_SHOW_NOTIFICATION = 8
+};
+
/**
* Moves enum for beings and actors for others players vision.
* WARNING: Has to be in sync with the same enum in the Being class
@@ -415,27 +431,12 @@ enum BeingAction
{
STAND,
WALK,
- ATTACK,
SIT,
DEAD,
HURT
};
/**
- * Moves enum for beings and actors for others players attack types.
- * WARNING: Has to be in sync with the same enum in the Being class
- * of the client!
- */
-enum AttackType
-{
- HIT = 0x00,
- CRITICAL = 0x0a,
- MULTI = 0x08,
- REFLECT = 0x04,
- FLEE = 0x0b
-};
-
-/**
* Beings and actors directions
* WARNING: Has to be in sync with the same enum in the Being class
* of the client!
@@ -458,6 +459,55 @@ enum BeingGender
GENDER_UNSPECIFIED
};
+// Helper functions for gender
+
+/**
+* Helper function for getting gender by int
+*/
+inline ManaServ::BeingGender getGender(int gender)
+{
+ switch (gender)
+ {
+ case 0:
+ return ManaServ::GENDER_MALE;
+ case 1:
+ return ManaServ::GENDER_FEMALE;
+ default:
+ return ManaServ::GENDER_UNSPECIFIED;
+ }
+}
+
+/**
+ * Quest states
+ */
+enum QuestStatus
+{
+ STATUS_OPEN = 0,
+ STATUS_STARTED,
+ STATUS_FINISHED,
+ STATUS_INVALID
+};
+
+/**
+ * Helper function for getting quest status by id
+ * @param status id of the status
+ * @return the status as enum value
+ */
+inline ManaServ::QuestStatus getQuestStatus(int status)
+{
+ switch (status)
+ {
+ case 0:
+ return ManaServ::STATUS_OPEN;
+ case 1:
+ return ManaServ::STATUS_STARTED;
+ case 2:
+ return ManaServ::STATUS_FINISHED;
+ default:
+ return ManaServ::STATUS_INVALID;
+ }
+}
+
/** The permited range to pick up an item */
const int PICKUP_RANGE = 32 + 16;
diff --git a/src/net/manaserv/npchandler.cpp b/src/net/manaserv/npchandler.cpp
index f19bf134..44729654 100644
--- a/src/net/manaserv/npchandler.cpp
+++ b/src/net/manaserv/npchandler.cpp
@@ -47,6 +47,7 @@ NpcHandler::NpcHandler()
GPMSG_NPC_CLOSE,
GPMSG_NPC_NUMBER,
GPMSG_NPC_STRING,
+ GPMSG_NPC_BUYSELL_RESPONSE,
0
};
handledMessages = _messages;
@@ -122,6 +123,9 @@ void NpcHandler::handleMessage(MessageIn &msg)
event->setInt("id", npcId);
event->trigger(Event::NpcChannel);
break;
+
+ case GPMSG_NPC_BUYSELL_RESPONSE:
+ break;
}
delete event;
diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp
index e0d4e783..02712214 100644
--- a/src/net/manaserv/playerhandler.cpp
+++ b/src/net/manaserv/playerhandler.cpp
@@ -70,9 +70,7 @@ PlayerHandler::PlayerHandler()
GPMSG_PLAYER_MAP_CHANGE,
GPMSG_PLAYER_SERVER_CHANGE,
GPMSG_PLAYER_ATTRIBUTE_CHANGE,
- GPMSG_PLAYER_EXP_CHANGE,
- GPMSG_LEVELUP,
- GPMSG_LEVEL_PROGRESS,
+ GPMSG_ATTRIBUTE_POINTS_STATUS,
GPMSG_RAISE_ATTRIBUTE_RESPONSE,
GPMSG_LOWER_ATTRIBUTE_RESPONSE,
GPMSG_ABILITY_STATUS,
@@ -130,39 +128,10 @@ void PlayerHandler::handleMessage(MessageIn &msg)
}
} break;
- case GPMSG_PLAYER_EXP_CHANGE:
- {
- logger->log("EXP Update");
- while (msg.getUnreadLength())
- {
- int skill = msg.readInt16();
- int current = msg.readInt32();
- int next = msg.readInt32();
- int level = msg.readInt16();
-
- PlayerInfo::setStatExperience(skill, current, next);
- PlayerInfo::setStatBase(skill, level);
- }
- } break;
-
- case GPMSG_LEVELUP:
- {
- PlayerInfo::setAttribute(LEVEL, msg.readInt16());
+ case GPMSG_ATTRIBUTE_POINTS_STATUS:
PlayerInfo::setAttribute(CHAR_POINTS, msg.readInt16());
PlayerInfo::setAttribute(CORR_POINTS, msg.readInt16());
- Particle* effect = particleEngine->addEffect(
- paths.getStringValue("particles")
- + paths.getStringValue("levelUpEffectFile")
- ,0, 0);
- local_player->controlParticle(effect);
- } break;
-
-
- case GPMSG_LEVEL_PROGRESS:
- {
- PlayerInfo::setAttribute(EXP, msg.readInt8());
- } break;
-
+ break;
case GPMSG_RAISE_ATTRIBUTE_RESPONSE:
{
@@ -321,9 +290,9 @@ void PlayerHandler::handleMapChangeMessage(MessageIn &msg)
void PlayerHandler::attack(int id)
{
- MessageOut msg(PGMSG_ATTACK);
- msg.writeInt16(id);
- gameServerConnection->send(msg);
+ // MessageOut msg(PGMSG_ATTACK);
+ // msg.writeInt16(id);
+ // gameServerConnection->send(msg);
}
void PlayerHandler::emote(int emoteId)
diff --git a/src/net/tmwa/abilityhandler.cpp b/src/net/tmwa/abilityhandler.cpp
index e221039c..e3e5d3bc 100644
--- a/src/net/tmwa/abilityhandler.cpp
+++ b/src/net/tmwa/abilityhandler.cpp
@@ -223,15 +223,15 @@ void AbilityHandler::use(int id)
{
}
-void AbilityHandler::use(int id, int level, int beingId)
+void AbilityHandler::useOn(int id, int beingId)
{
}
-void AbilityHandler::use(int id, int level, int x, int y)
+void AbilityHandler::useAt(int id, int x, int y)
{
}
-void AbilityHandler::use(int id, const std::string &map)
+void AbilityHandler::useInDirection(int id, int direction)
{
}
diff --git a/src/net/tmwa/abilityhandler.h b/src/net/tmwa/abilityhandler.h
index 822ed737..171f7d41 100644
--- a/src/net/tmwa/abilityhandler.h
+++ b/src/net/tmwa/abilityhandler.h
@@ -37,11 +37,11 @@ class AbilityHandler final : public MessageHandler, public Net::AbilityHandler
void use(int id) override;
- void use(int id, int level, int beingId) override;
+ void useOn(int id, int beingId) override;
- void use(int id, int level, int x, int y) override;
+ void useAt(int id, int x, int y) override;
- void use(int id, const std::string &map) override;
+ void useInDirection(int id, int direction) override;
};
} // namespace TmwAthena