summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/net/ea/beinghandler.cpp240
-rw-r--r--src/net/ea/beinghandler.h3
-rw-r--r--src/net/eathena/beinghandler.cpp7
-rw-r--r--src/net/eathena/beinghandler.h5
-rw-r--r--src/net/tmwa/beinghandler.cpp249
-rw-r--r--src/net/tmwa/beinghandler.h2
6 files changed, 256 insertions, 250 deletions
diff --git a/src/net/ea/beinghandler.cpp b/src/net/ea/beinghandler.cpp
index 7ee755a5f..cd8158781 100644
--- a/src/net/ea/beinghandler.cpp
+++ b/src/net/ea/beinghandler.cpp
@@ -95,246 +95,6 @@ void BeingHandler::setSprite(Being *const being, const unsigned int slot,
being->updateSprite(slot, id, color, colorId, isWeapon, isTempSprite);
}
-void BeingHandler::processBeingVisibleOrMove(Net::MessageIn &msg,
- const bool visible)
-{
- BLOCK_START("BeingHandler::processBeingVisibleOrMove")
- if (!actorManager)
- {
- BLOCK_END("BeingHandler::processBeingVisibleOrMove")
- return;
- }
-
- int spawnId;
-
- // Information about a being in range
- const int id = msg.readInt32();
- if (id == mSpawnId)
- spawnId = mSpawnId;
- else
- spawnId = 0;
- mSpawnId = 0;
- int16_t speed = msg.readInt16();
- const uint16_t stunMode = msg.readInt16(); // opt1
- uint32_t statusEffects = msg.readInt16(); // opt2
- statusEffects |= (static_cast<uint32_t>(msg.readInt16())) << 16; // option
- const int16_t job = msg.readInt16(); // class
- int disguiseId = 0;
- if (id == localPlayer->getId() && job >= 1000)
- disguiseId = job;
-
- Being *dstBeing = actorManager->findBeing(id);
-
- if (dstBeing && dstBeing->getType() == ActorType::MONSTER
- && !dstBeing->isAlive())
- {
- actorManager->destroy(dstBeing);
- actorManager->erase(dstBeing);
- dstBeing = nullptr;
- }
-
- if (!dstBeing)
- {
- // Being with id >= 110000000 and job 0 are better
- // known as ghosts, so don't create those.
- if (job == 0 && id >= 110000000)
- {
- BLOCK_END("BeingHandler::processBeingVisibleOrMove")
- return;
- }
-
- if (actorManager->isBlocked(id) == true)
- {
- BLOCK_END("BeingHandler::processBeingVisibleOrMove")
- return;
- }
-
- dstBeing = createBeing(id, job);
-
- if (!dstBeing)
- {
- BLOCK_END("BeingHandler::processBeingVisibleOrMove")
- return;
- }
-
- if (job == 1022 && killStats)
- killStats->jackoAlive(dstBeing->getId());
- }
- else
- {
- if (dstBeing->getType() == ActorType::NPC)
- {
- actorManager->undelete(dstBeing);
- if (serverVersion < 1)
- requestNameById(id);
- }
- }
-
- if (dstBeing->getType() == ActorType::PLAYER)
- dstBeing->setMoveTime();
-
- if (spawnId)
- {
- dstBeing->setAction(BeingAction::SPAWN, 0);
- }
- else if (visible)
- {
- dstBeing->clearPath();
- dstBeing->setActionTime(tick_time);
- dstBeing->setAction(BeingAction::STAND, 0);
- }
-
- // Prevent division by 0 when calculating frame
- if (speed == 0)
- speed = 150;
-
- const uint8_t hairStyle = msg.readUInt8();
- const uint8_t look = msg.readUInt8();
- dstBeing->setSubtype(job, look);
- if (dstBeing->getType() == ActorType::MONSTER && localPlayer)
- localPlayer->checkNewName(dstBeing);
- dstBeing->setWalkSpeed(Vector(speed, speed, 0));
- const uint16_t weapon = msg.readInt16();
- const uint16_t headBottom = msg.readInt16();
-
- if (!visible)
- msg.readInt32(); // server tick
-
- const uint16_t shield = msg.readInt16();
- const uint16_t headTop = msg.readInt16();
- const uint16_t headMid = msg.readInt16();
- const uint8_t hairColor = msg.readUInt8();
- msg.readUInt8(); // free
- const uint16_t shoes = msg.readInt16(); // clothes color
-
- uint16_t gloves;
- if (dstBeing->getType() == ActorType::MONSTER)
- {
- if (serverVersion > 0 || tmwServerVersion >= 0x0E0701)
- {
- const int hp = msg.readInt32();
- const int maxHP = msg.readInt32();
- if (hp && maxHP)
- {
- dstBeing->setMaxHP(maxHP);
- const int oldHP = dstBeing->getHP();
- if (!oldHP || oldHP > hp)
- dstBeing->setHP(hp);
- }
- }
- else
- {
- msg.readInt32();
- msg.readInt32();
- }
- gloves = 0;
- }
- else
- {
- gloves = msg.readInt16(); // head dir - "abused" as gloves
- msg.readInt32(); // guild
- msg.readInt16(); // guild emblem
- }
-// logger->log("being guild: " + toString(guild));
-
- msg.readInt16(); // manner
- dstBeing->setStatusEffectBlock(32, msg.readInt16()); // opt3
- if (serverVersion > 0 && dstBeing->getType() == ActorType::MONSTER)
- {
- const int attackRange = static_cast<int>(msg.readUInt8()); // karma
- dstBeing->setAttackRange(attackRange);
- }
- else
- {
- msg.readUInt8(); // karma
- }
- uint8_t gender = msg.readUInt8();
-
- if (!disguiseId && dstBeing->getType() == ActorType::PLAYER)
- {
- // reserving bits for future usage
- gender &= 3;
- dstBeing->setGender(Being::intToGender(gender));
- // Set these after the gender, as the sprites may be gender-specific
- setSprite(dstBeing, EA_SPRITE_HAIR, hairStyle * -1,
- ItemDB::get(-hairStyle).getDyeColorsString(hairColor));
- dstBeing->setHairColor(hairColor);
- setSprite(dstBeing, EA_SPRITE_BOTTOMCLOTHES, headBottom);
- setSprite(dstBeing, EA_SPRITE_TOPCLOTHES, headMid);
- setSprite(dstBeing, EA_SPRITE_HAT, headTop);
- setSprite(dstBeing, EA_SPRITE_SHOE, shoes);
- setSprite(dstBeing, EA_SPRITE_GLOVES, gloves);
- setSprite(dstBeing, EA_SPRITE_WEAPON, weapon, "", 1, true);
- if (!mHideShield)
- setSprite(dstBeing, EA_SPRITE_SHIELD, shield);
- }
- else if (dstBeing->getType() == ActorType::NPC)
- {
- switch (gender)
- {
- case 2:
- dstBeing->setGender(Gender::FEMALE);
- break;
- case 3:
- dstBeing->setGender(Gender::MALE);
- break;
- case 4:
- dstBeing->setGender(Gender::OTHER);
- break;
- default:
- dstBeing->setGender(Gender::UNSPECIFIED);
- break;
- }
- }
-
- if (!visible)
- {
- uint16_t srcX, srcY, dstX, dstY;
- msg.readCoordinatePair(srcX, srcY, dstX, dstY);
- if (!disguiseId)
- {
- dstBeing->setAction(BeingAction::STAND, 0);
- dstBeing->setTileCoords(srcX, srcY);
- if (serverVersion < 10)
- dstBeing->setDestination(dstX, dstY);
- }
- }
- else
- {
- uint8_t dir;
- uint16_t x, y;
- msg.readCoordinates(x, y, dir);
- dstBeing->setTileCoords(x, y);
-
- if (job == 45 && socialWindow && outfitWindow)
- {
- const int num = socialWindow->getPortalIndex(x, y);
- if (num >= 0)
- {
- dstBeing->setName(keyboard.getKeyShortString(
- outfitWindow->keyName(num)));
- }
- else
- {
- dstBeing->setName("");
- }
- }
-
- dstBeing->setDirection(dir);
- }
-
- msg.readUInt8(); // unknown
- msg.readUInt8(); // unknown
- msg.readInt16();
-
- dstBeing->setStunMode(stunMode);
- dstBeing->setStatusEffectBlock(0, static_cast<uint16_t>(
- (statusEffects >> 16) & 0xffff));
- dstBeing->setStatusEffectBlock(16, static_cast<uint16_t>(
- statusEffects & 0xffff));
- BLOCK_END("BeingHandler::processBeingVisibleOrMove")
-}
-
void BeingHandler::processBeingMove2(Net::MessageIn &msg) const
{
BLOCK_START("BeingHandler::processBeingMove2")
diff --git a/src/net/ea/beinghandler.h b/src/net/ea/beinghandler.h
index b460ae358..293ef92e1 100644
--- a/src/net/ea/beinghandler.h
+++ b/src/net/ea/beinghandler.h
@@ -46,9 +46,6 @@ class BeingHandler notfinal : public Net::BeingHandler
const bool isWeapon = false,
const bool isTempSprite = false) const;
- virtual void processBeingVisibleOrMove(Net::MessageIn &msg,
- const bool visible);
-
virtual void processBeingMove2(Net::MessageIn &msg) const;
virtual void processBeingSpawn(Net::MessageIn &msg);
diff --git a/src/net/eathena/beinghandler.cpp b/src/net/eathena/beinghandler.cpp
index fe153a474..35c183569 100644
--- a/src/net/eathena/beinghandler.cpp
+++ b/src/net/eathena/beinghandler.cpp
@@ -109,7 +109,7 @@ void BeingHandler::handleMessage(Net::MessageIn &msg)
{
case SMSG_BEING_VISIBLE: // changed
case SMSG_BEING_MOVE:
- processBeingVisibleOrMove(msg, msg.getId() == SMSG_BEING_VISIBLE);
+ processBeingVisibleOrMove(msg);
break;
case SMSG_BEING_MOVE2:
@@ -628,12 +628,13 @@ void BeingHandler::processPlayerMoveUpdate(Net::MessageIn &msg,
dstBeing->setMoveTime();
}
-void BeingHandler::processBeingVisibleOrMove(Net::MessageIn &msg,
- const bool visible)
+void BeingHandler::processBeingVisibleOrMove(Net::MessageIn &msg)
{
if (!actorManager)
return;
+ const bool visible = msg.getId() == SMSG_BEING_VISIBLE;
+
if (visible)
msg.readUInt8(); // padding?
diff --git a/src/net/eathena/beinghandler.h b/src/net/eathena/beinghandler.h
index 54271edff..fdbde2afa 100644
--- a/src/net/eathena/beinghandler.h
+++ b/src/net/eathena/beinghandler.h
@@ -43,10 +43,9 @@ class BeingHandler final : public MessageHandler, public Ea::BeingHandler
void undress(Being *const being) const override final;
- void processBeingVisibleOrMove(Net::MessageIn &msg,
- const bool visible) override final;
-
protected:
+ void processBeingVisibleOrMove(Net::MessageIn &msg);
+
void processBeingChangeLook(Net::MessageIn &msg,
const bool look2) const;
diff --git a/src/net/tmwa/beinghandler.cpp b/src/net/tmwa/beinghandler.cpp
index 2ea77d925..a9c98d295 100644
--- a/src/net/tmwa/beinghandler.cpp
+++ b/src/net/tmwa/beinghandler.cpp
@@ -30,6 +30,12 @@
#include "being/localplayer.h"
+#include "input/keyboardconfig.h"
+
+#include "gui/windows/killstats.h"
+#include "gui/windows/outfitwindow.h"
+#include "gui/windows/socialwindow.h"
+
#include "net/tmwa/messageout.h"
#include "net/tmwa/protocol.h"
#include "net/tmwa/sprite.h"
@@ -46,6 +52,7 @@
extern Net::BeingHandler *beingHandler;
extern int serverVersion;
+extern unsigned int tmwServerVersion;
namespace TmwAthena
{
@@ -106,7 +113,7 @@ void BeingHandler::handleMessage(Net::MessageIn &msg)
{
case SMSG_BEING_VISIBLE:
case SMSG_BEING_MOVE:
- processBeingVisibleOrMove(msg, msg.getId() == SMSG_BEING_VISIBLE);
+ processBeingVisibleOrMove(msg);
break;
case SMSG_BEING_MOVE2:
@@ -727,4 +734,244 @@ void BeingHandler::processBeingMove3(Net::MessageIn &msg)
BLOCK_END("BeingHandler::processBeingMove3")
}
+void BeingHandler::processBeingVisibleOrMove(Net::MessageIn &msg)
+{
+ BLOCK_START("BeingHandler::processBeingVisibleOrMove")
+ if (!actorManager)
+ {
+ BLOCK_END("BeingHandler::processBeingVisibleOrMove")
+ return;
+ }
+
+ const bool visible = msg.getId() == SMSG_BEING_VISIBLE;
+ int spawnId;
+
+ // Information about a being in range
+ const int id = msg.readInt32();
+ if (id == mSpawnId)
+ spawnId = mSpawnId;
+ else
+ spawnId = 0;
+ mSpawnId = 0;
+ int16_t speed = msg.readInt16();
+ const uint16_t stunMode = msg.readInt16(); // opt1
+ uint32_t statusEffects = msg.readInt16(); // opt2
+ statusEffects |= (static_cast<uint32_t>(msg.readInt16())) << 16; // option
+ const int16_t job = msg.readInt16(); // class
+ int disguiseId = 0;
+ if (id == localPlayer->getId() && job >= 1000)
+ disguiseId = job;
+
+ Being *dstBeing = actorManager->findBeing(id);
+
+ if (dstBeing && dstBeing->getType() == ActorType::MONSTER
+ && !dstBeing->isAlive())
+ {
+ actorManager->destroy(dstBeing);
+ actorManager->erase(dstBeing);
+ dstBeing = nullptr;
+ }
+
+ if (!dstBeing)
+ {
+ // Being with id >= 110000000 and job 0 are better
+ // known as ghosts, so don't create those.
+ if (job == 0 && id >= 110000000)
+ {
+ BLOCK_END("BeingHandler::processBeingVisibleOrMove")
+ return;
+ }
+
+ if (actorManager->isBlocked(id) == true)
+ {
+ BLOCK_END("BeingHandler::processBeingVisibleOrMove")
+ return;
+ }
+
+ dstBeing = createBeing(id, job);
+
+ if (!dstBeing)
+ {
+ BLOCK_END("BeingHandler::processBeingVisibleOrMove")
+ return;
+ }
+
+ if (job == 1022 && killStats)
+ killStats->jackoAlive(dstBeing->getId());
+ }
+ else
+ {
+ if (dstBeing->getType() == ActorType::NPC)
+ {
+ actorManager->undelete(dstBeing);
+ if (serverVersion < 1)
+ requestNameById(id);
+ }
+ }
+
+ if (dstBeing->getType() == ActorType::PLAYER)
+ dstBeing->setMoveTime();
+
+ if (spawnId)
+ {
+ dstBeing->setAction(BeingAction::SPAWN, 0);
+ }
+ else if (visible)
+ {
+ dstBeing->clearPath();
+ dstBeing->setActionTime(tick_time);
+ dstBeing->setAction(BeingAction::STAND, 0);
+ }
+
+ // Prevent division by 0 when calculating frame
+ if (speed == 0)
+ speed = 150;
+
+ const uint8_t hairStyle = msg.readUInt8();
+ const uint8_t look = msg.readUInt8();
+ dstBeing->setSubtype(job, look);
+ if (dstBeing->getType() == ActorType::MONSTER && localPlayer)
+ localPlayer->checkNewName(dstBeing);
+ dstBeing->setWalkSpeed(Vector(speed, speed, 0));
+ const uint16_t weapon = msg.readInt16();
+ const uint16_t headBottom = msg.readInt16();
+
+ if (!visible)
+ msg.readInt32(); // server tick
+
+ const uint16_t shield = msg.readInt16();
+ const uint16_t headTop = msg.readInt16();
+ const uint16_t headMid = msg.readInt16();
+ const uint8_t hairColor = msg.readUInt8();
+ msg.readUInt8(); // free
+ const uint16_t shoes = msg.readInt16(); // clothes color
+
+ uint16_t gloves;
+ if (dstBeing->getType() == ActorType::MONSTER)
+ {
+ if (serverVersion > 0 || tmwServerVersion >= 0x0E0701)
+ {
+ const int hp = msg.readInt32();
+ const int maxHP = msg.readInt32();
+ if (hp && maxHP)
+ {
+ dstBeing->setMaxHP(maxHP);
+ const int oldHP = dstBeing->getHP();
+ if (!oldHP || oldHP > hp)
+ dstBeing->setHP(hp);
+ }
+ }
+ else
+ {
+ msg.readInt32();
+ msg.readInt32();
+ }
+ gloves = 0;
+ }
+ else
+ {
+ gloves = msg.readInt16(); // head dir - "abused" as gloves
+ msg.readInt32(); // guild
+ msg.readInt16(); // guild emblem
+ }
+// logger->log("being guild: " + toString(guild));
+
+ msg.readInt16(); // manner
+ dstBeing->setStatusEffectBlock(32, msg.readInt16()); // opt3
+ if (serverVersion > 0 && dstBeing->getType() == ActorType::MONSTER)
+ {
+ const int attackRange = static_cast<int>(msg.readUInt8()); // karma
+ dstBeing->setAttackRange(attackRange);
+ }
+ else
+ {
+ msg.readUInt8(); // karma
+ }
+ uint8_t gender = msg.readUInt8();
+
+ if (!disguiseId && dstBeing->getType() == ActorType::PLAYER)
+ {
+ // reserving bits for future usage
+ gender &= 3;
+ dstBeing->setGender(Being::intToGender(gender));
+ // Set these after the gender, as the sprites may be gender-specific
+ setSprite(dstBeing, SPRITE_HAIR, hairStyle * -1,
+ ItemDB::get(-hairStyle).getDyeColorsString(hairColor));
+ dstBeing->setHairColor(hairColor);
+ setSprite(dstBeing, SPRITE_BOTTOMCLOTHES, headBottom);
+ setSprite(dstBeing, SPRITE_TOPCLOTHES, headMid);
+ setSprite(dstBeing, SPRITE_HAT, headTop);
+ setSprite(dstBeing, SPRITE_SHOE, shoes);
+ setSprite(dstBeing, SPRITE_GLOVES, gloves);
+ setSprite(dstBeing, SPRITE_WEAPON, weapon, "", 1, true);
+ if (!mHideShield)
+ setSprite(dstBeing, SPRITE_SHIELD, shield);
+ }
+ else if (dstBeing->getType() == ActorType::NPC)
+ {
+ switch (gender)
+ {
+ case 2:
+ dstBeing->setGender(Gender::FEMALE);
+ break;
+ case 3:
+ dstBeing->setGender(Gender::MALE);
+ break;
+ case 4:
+ dstBeing->setGender(Gender::OTHER);
+ break;
+ default:
+ dstBeing->setGender(Gender::UNSPECIFIED);
+ break;
+ }
+ }
+
+ if (!visible)
+ {
+ uint16_t srcX, srcY, dstX, dstY;
+ msg.readCoordinatePair(srcX, srcY, dstX, dstY);
+ if (!disguiseId)
+ {
+ dstBeing->setAction(BeingAction::STAND, 0);
+ dstBeing->setTileCoords(srcX, srcY);
+ if (serverVersion < 10)
+ dstBeing->setDestination(dstX, dstY);
+ }
+ }
+ else
+ {
+ uint8_t dir;
+ uint16_t x, y;
+ msg.readCoordinates(x, y, dir);
+ dstBeing->setTileCoords(x, y);
+
+ if (job == 45 && socialWindow && outfitWindow)
+ {
+ const int num = socialWindow->getPortalIndex(x, y);
+ if (num >= 0)
+ {
+ dstBeing->setName(keyboard.getKeyShortString(
+ outfitWindow->keyName(num)));
+ }
+ else
+ {
+ dstBeing->setName("");
+ }
+ }
+
+ dstBeing->setDirection(dir);
+ }
+
+ msg.readUInt8(); // unknown
+ msg.readUInt8(); // unknown
+ msg.readInt16();
+
+ dstBeing->setStunMode(stunMode);
+ dstBeing->setStatusEffectBlock(0, static_cast<uint16_t>(
+ (statusEffects >> 16) & 0xffff));
+ dstBeing->setStatusEffectBlock(16, static_cast<uint16_t>(
+ statusEffects & 0xffff));
+ BLOCK_END("BeingHandler::processBeingVisibleOrMove")
+}
+
} // namespace TmwAthena
diff --git a/src/net/tmwa/beinghandler.h b/src/net/tmwa/beinghandler.h
index f3b57b023..870ea4a1a 100644
--- a/src/net/tmwa/beinghandler.h
+++ b/src/net/tmwa/beinghandler.h
@@ -47,6 +47,8 @@ class BeingHandler final : public MessageHandler, public Ea::BeingHandler
void processBeingChangeLook(Net::MessageIn &msg,
const bool look2) const;
+ void processBeingVisibleOrMove(Net::MessageIn &msg);
+
static void processNameResponse2(Net::MessageIn &msg);
void processPlayerMoveUpdate(Net::MessageIn &msg,