summaryrefslogtreecommitdiff
path: root/src/net/tmwa/beinghandler.cpp
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2014-08-30 17:24:51 +0300
committerAndrei Karas <akaras@inbox.ru>2014-08-30 17:24:51 +0300
commit7e4752efe67acd3668724c2be69b445e2019c268 (patch)
treea5bde9a7883da7096b39b6cf69286bd034f9a58a /src/net/tmwa/beinghandler.cpp
parente46cf607a4da55fc77b6b2ea7fca53d69ec6e56b (diff)
downloadmv-7e4752efe67acd3668724c2be69b445e2019c268.tar.gz
mv-7e4752efe67acd3668724c2be69b445e2019c268.tar.bz2
mv-7e4752efe67acd3668724c2be69b445e2019c268.tar.xz
mv-7e4752efe67acd3668724c2be69b445e2019c268.zip
Remove additional parameters from processBeingVisibleOrMove function.
Diffstat (limited to 'src/net/tmwa/beinghandler.cpp')
-rw-r--r--src/net/tmwa/beinghandler.cpp249
1 files changed, 248 insertions, 1 deletions
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