summaryrefslogtreecommitdiff
path: root/src/net/manaserv/beinghandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/manaserv/beinghandler.cpp')
-rw-r--r--src/net/manaserv/beinghandler.cpp171
1 files changed, 83 insertions, 88 deletions
diff --git a/src/net/manaserv/beinghandler.cpp b/src/net/manaserv/beinghandler.cpp
index 8df9a8ab..4d45da8a 100644
--- a/src/net/manaserv/beinghandler.cpp
+++ b/src/net/manaserv/beinghandler.cpp
@@ -21,13 +21,12 @@
#include "net/manaserv/beinghandler.h"
+#include "actorspritemanager.h"
#include "being.h"
-#include "beingmanager.h"
#include "client.h"
#include "game.h"
#include "localplayer.h"
#include "log.h"
-#include "npc.h"
#include "particle.h"
#include "gui/okdialog.h"
@@ -35,12 +34,14 @@
#include "net/messagein.h"
#include "net/manaserv/playerhandler.h"
-#include "net/manaserv/protocol.h"
+#include "net/manaserv/manaserv_protocol.h"
#include "resources/colordb.h"
#include "utils/gettext.h"
+#define POSITION_DIFF_TOLERANCE 48
+
namespace ManaServ {
BeingHandler::BeingHandler()
@@ -90,38 +91,7 @@ void BeingHandler::handleMessage(Net::MessageIn &msg)
}
}
-Vector BeingHandler::giveSpeedInPixelsPerTicks(float speedInTilesPerSeconds)
-{
- Vector speedInTicks;
- Game *game = Game::instance();
- Map *map = 0;
- if (game)
- {
- map = game->getCurrentMap();
- if (map)
- {
- speedInTicks.x = speedInTilesPerSeconds
- * (float)map->getTileWidth()
- / 1000 * (float) MILLISECONDS_IN_A_TICK;
- speedInTicks.y = speedInTilesPerSeconds
- * (float)map->getTileHeight()
- / 1000 * (float) MILLISECONDS_IN_A_TICK;
- }
- }
-
- if (!game || !map)
- {
- speedInTicks.x = speedInTicks.y = 0;
- logger->log("Manaserv::BeingHandler: Speed wasn't given back"
- " because game/Map not initialized.");
- }
- // We don't use z for now.
- speedInTicks.z = 0;
-
- return speedInTicks;
-}
-
-static void handleLooks(Player *being, Net::MessageIn &msg)
+static void handleLooks(Being *being, Net::MessageIn &msg)
{
// Order of sent slots. Has to be in sync with the server code.
static int const nb_slots = 4;
@@ -145,7 +115,7 @@ static void handleLooks(Player *being, Net::MessageIn &msg)
{
if (!(mask & (1 << i))) continue;
int id = msg.readInt16();
- being->setSprite(slots[i], id);
+ being->setSprite(slots[i], id,"", (slots[i] == SPRITE_WEAPON));
}
}
@@ -156,8 +126,17 @@ void BeingHandler::handleBeingEnterMessage(Net::MessageIn &msg)
Being::Action action = (Being::Action)msg.readInt8();
int px = msg.readInt16();
int py = msg.readInt16();
+ BeingDirection direction = (BeingDirection)msg.readInt8();
Being *being;
+ if (!Game::instance()->getCurrentMap()->containsPixel(px, py))
+ {
+ logger->log("Warning: Received GPMSG_BEING_ENTER for being id %i "
+ "with position outside the map boundaries "
+ "(x = %i, y = %i)", id, px, py);
+ return;
+ }
+
switch (type)
{
case OBJECT_CHARACTER:
@@ -170,23 +149,23 @@ void BeingHandler::handleBeingEnterMessage(Net::MessageIn &msg)
}
else
{
- being = beingManager->createBeing(id, Being::PLAYER, 0);
+ being = actorSpriteManager->createBeing(id,
+ ActorSprite::PLAYER, 0);
being->setName(name);
}
- Player *p = static_cast< Player * >(being);
int hs = msg.readInt8(), hc = msg.readInt8();
- p->setSprite(SPRITE_HAIR, hs * -1, ColorDB::get(hc));
- p->setGender(msg.readInt8() == GENDER_MALE ?
- GENDER_MALE : GENDER_FEMALE);
- handleLooks(p, msg);
+ being->setSprite(SPRITE_HAIR, hs * -1, ColorDB::get(hc));
+ being->setGender(msg.readInt8() == GENDER_MALE ?
+ GENDER_MALE : GENDER_FEMALE);
+ handleLooks(being, msg);
} break;
case OBJECT_MONSTER:
case OBJECT_NPC:
{
int subtype = msg.readInt16();
- being = beingManager->createBeing(id, type == OBJECT_MONSTER ?
- Being::MONSTER : Being::NPC, subtype);
+ being = actorSpriteManager->createBeing(id, type == OBJECT_MONSTER
+ ? ActorSprite::MONSTER : ActorSprite::NPC, subtype);
std::string name = msg.readString();
if (name.length() > 0) being->setName(name);
} break;
@@ -197,16 +176,17 @@ void BeingHandler::handleBeingEnterMessage(Net::MessageIn &msg)
being->setPosition(px, py);
being->setDestination(px, py);
+ being->setDirection(direction);
being->setAction(action);
}
void BeingHandler::handleBeingLeaveMessage(Net::MessageIn &msg)
{
- Being *being = beingManager->findBeing(msg.readInt16());
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
if (!being)
return;
- beingManager->destroyBeing(being);
+ actorSpriteManager->destroy(being);
}
void BeingHandler::handleBeingsMoveMessage(Net::MessageIn &msg)
@@ -215,71 +195,96 @@ void BeingHandler::handleBeingsMoveMessage(Net::MessageIn &msg)
{
int id = msg.readInt16();
int flags = msg.readInt8();
- Being *being = beingManager->findBeing(id);
- int sx = 0;
- int sy = 0;
- int speed = 0;
+ Being *being = actorSpriteManager->findBeing(id);
+ int sx = 0, sy = 0, dx = 0, dy = 0, speed = 0;
+
+ if ((!flags & (MOVING_POSITION | MOVING_DESTINATION)))
+ continue;
if (flags & MOVING_POSITION)
{
sx = msg.readInt16();
sy = msg.readInt16();
- speed = msg.readInt8();
}
- if (!being || !(flags & (MOVING_POSITION | MOVING_DESTINATION)))
+
+ if (flags & MOVING_DESTINATION)
{
- continue;
+ dx = msg.readInt16();
+ dy = msg.readInt16();
+ speed = msg.readInt8();
}
+
+ if (!being)
+ continue;
+
if (speed)
{
/*
* The being's speed is transfered in tiles per second * 10
* to keep it transferable in a Byte.
* We set it back to tiles per second and in a float.
- * Then, we translate it in pixels per ticks, to correspond
- * with the Being::logic() function calls
- * @see MILLISECONDS_IN_A_TICK
*/
- being->setWalkSpeed(
- giveSpeedInPixelsPerTicks((float) speed / 10));
+ float speedTilesSeconds = (float) speed / 10;
+ being->setMoveSpeed(Vector(speedTilesSeconds, speedTilesSeconds,
+ 0));
}
// Ignore messages from the server for the local player
if (being == player_node)
continue;
+ // If the position differs too much from the actual one, we resync
+ // the being position
if (flags & MOVING_POSITION)
{
- being->setDestination(sx, sy);
+ if (!being->getMap()->containsPixel(sx, sy))
+ {
+ logger->log("Warning: Received GPMSG_BEINGS_MOVE for being id "
+ "%i with position outside the map boundaries "
+ "(x = %i, y = %i)", id, sx, sy);
+ continue;
+ }
+
+ Vector serverPos(sx, sy);
+ if (serverPos.length()
+ - being->getPosition().length() > POSITION_DIFF_TOLERANCE)
+ being->setPosition(serverPos);
+ }
+
+ if (flags & MOVING_DESTINATION)
+ {
+ if (!being->getMap()->containsPixel(dx, dy))
+ {
+ logger->log("Warning: Received GPMSG_BEINGS_MOVE for being id "
+ "%i with destination outside the map boundaries "
+ "(x = %i, y = %i)", id, dx, dy);
+ continue;
+ }
+
+ being->setDestination(dx, dy);
}
}
}
void BeingHandler::handleBeingAttackMessage(Net::MessageIn &msg)
{
- Being *being = beingManager->findBeing(msg.readInt16());
- const int direction = msg.readInt8();
- const int attackType = msg.readInt8();
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ const BeingDirection direction = (BeingDirection) msg.readInt8();
+ const int attackId = msg.readInt8();
if (!being)
return;
- switch (direction)
- {
- case DIRECTION_UP: being->setDirection(Being::UP); break;
- case DIRECTION_DOWN: being->setDirection(Being::DOWN); break;
- case DIRECTION_LEFT: being->setDirection(Being::LEFT); break;
- case DIRECTION_RIGHT: being->setDirection(Being::RIGHT); break;
- }
+ being->setDirection(direction);
- being->setAction(Being::ATTACK, attackType);
+ being->setAction(Being::ATTACK, attackId);
}
void BeingHandler::handleBeingsDamageMessage(Net::MessageIn &msg)
{
while (msg.getUnreadLength())
{
- Being *being = beingManager->findBeing(msg.readInt16());
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
int damage = msg.readInt16();
if (being)
{
@@ -290,7 +295,7 @@ void BeingHandler::handleBeingsDamageMessage(Net::MessageIn &msg)
void BeingHandler::handleBeingActionChangeMessage(Net::MessageIn &msg)
{
- Being *being = beingManager->findBeing(msg.readInt16());
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
Being::Action action = (Being::Action) msg.readInt8();
if (!being)
return;
@@ -329,38 +334,28 @@ void BeingHandler::handleBeingActionChangeMessage(Net::MessageIn &msg)
void BeingHandler::handleBeingLooksChangeMessage(Net::MessageIn &msg)
{
- Being *being = beingManager->findBeing(msg.readInt16());
- if (!being || being->getType() != Being::PLAYER)
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
+ if (!being || being->getType() != ActorSprite::PLAYER)
return;
- Player *player = static_cast<Player *>(being);
- handleLooks(player, msg);
+ handleLooks(being, msg);
if (msg.getUnreadLength())
{
int style = msg.readInt16();
int color = msg.readInt16();
- player->setSprite(SPRITE_HAIR, style * -1, ColorDB::get(color));
+ being->setSprite(SPRITE_HAIR, style * -1, ColorDB::get(color));
}
}
void BeingHandler::handleBeingDirChangeMessage(Net::MessageIn &msg)
{
- Being *being = beingManager->findBeing(msg.readInt16());
+ Being *being = actorSpriteManager->findBeing(msg.readInt16());
if (!being)
return;
int data = msg.readInt8();
// The direction for the player's character is handled on client side.
if (being != player_node)
- {
- switch (data)
- {
- case DIRECTION_UP: being->setDirection(Being::UP); break;
- case DIRECTION_DOWN: being->setDirection(Being::DOWN); break;
- case DIRECTION_LEFT: being->setDirection(Being::LEFT); break;
- case DIRECTION_RIGHT: being->setDirection(Being::RIGHT); break;
- default: break;
- }
- }
+ being->setDirection((BeingDirection) data);
}
} // namespace ManaServ