some rework on gameprotocol class

This commit is contained in:
Eduardo Bart 2012-01-09 03:23:39 -02:00
parent 4c539cbbe3
commit 81e378cc22
13 changed files with 179 additions and 194 deletions

View File

@ -5,7 +5,8 @@ local SpeakTypes = {
say = { color = '#FFFF00' },
whisper = { color = '#FFFF00' },
yell = { color = '#FFFF00' },
monsterSay = { color = '#FE6500', hideInConsole = false},
monsterSay = { color = '#FE6500', hideInConsole = true},
monsterYell = { color = '#FE6500', hideInConsole = true},
npcToPlayer = { color = '#5FF7F7' },
channelYellow = { color = '#FFFF00' },
channelWhite = { color = '#FFFFFF' },
@ -46,7 +47,7 @@ end
-- hooked events
local function onCreatureSpeak(name, level, speaktypedesc, message, channelId, creaturePos)
speaktype = SpeakTypes[speaktypedesc]
if speaktype == SpeakTypes.monsterSay then return end
if speaktype.hideInConsole then return end
if name then
if Options.showLevelsInConsole and level > 0 then

View File

@ -37,6 +37,9 @@ void UILayout::updateLater()
if(m_updateScheduled)
return;
if(!getParentWidget())
return;
auto self = asUILayout();
g_dispatcher.addEvent([self] {
self->m_updateScheduled = false;

View File

@ -72,6 +72,7 @@ public:
bool getPassable() { return m_passable; }
ThingType *getType();
//virtual void walk(const Position& oldPos, const Position& newPos, bool inverse = true);
virtual void walk(const Position& position, bool inverse = true);
void turn(Otc::Direction direction);
virtual void cancelWalk(Otc::Direction direction, bool force = false);
@ -107,4 +108,14 @@ protected:
Otc::Direction m_turnDirection;
};
class Npc : public Creature {
public:
NpcPtr asNpc() { return std::static_pointer_cast<Npc>(shared_from_this()); }
};
class Monster : public Creature {
public:
MonsterPtr asMonster() { return std::static_pointer_cast<Monster>(shared_from_this()); }
};
#endif

View File

@ -29,10 +29,12 @@ class Tile;
class Thing;
class Item;
class Creature;
class Effect;
class Missile;
class Monster;
class Npc;
class Player;
class LocalPlayer;
class Effect;
class Missile;
class AnimatedText;
class StaticText;
@ -40,10 +42,12 @@ typedef std::shared_ptr<Tile> TilePtr;
typedef std::shared_ptr<Thing> ThingPtr;
typedef std::shared_ptr<Item> ItemPtr;
typedef std::shared_ptr<Creature> CreaturePtr;
typedef std::shared_ptr<Effect> EffectPtr;
typedef std::shared_ptr<Missile> MissilePtr;
typedef std::shared_ptr<Monster> MonsterPtr;
typedef std::shared_ptr<Npc> NpcPtr;
typedef std::shared_ptr<Player> PlayerPtr;
typedef std::shared_ptr<LocalPlayer> LocalPlayerPtr;
typedef std::shared_ptr<Effect> EffectPtr;
typedef std::shared_ptr<Missile> MissilePtr;
typedef std::shared_ptr<AnimatedText> AnimatedTextPtr;
typedef std::shared_ptr<StaticText> StaticTextPtr;

View File

@ -36,6 +36,9 @@ void Game::loginWorld(const std::string& account, const std::string& password, c
{
m_online = false;
m_dead = false;
m_walkFeedback = true;
m_ping = 0;
m_pingTimer.restart();
m_protocolGame = ProtocolGamePtr(new ProtocolGame);
m_protocolGame->login(account, password, worldHost, (uint16)worldPort, characterName);
}
@ -72,11 +75,15 @@ void Game::processConnectionError(const boost::system::error_code& error)
}
}
void Game::processLogin(const LocalPlayerPtr& localPlayer)
void Game::processLogin(const LocalPlayerPtr& localPlayer, int serverBeat)
{
updatePing();
m_localPlayer = localPlayer;
m_online = true;
g_lua.callGlobalField("Game", "onLogin", m_localPlayer);
m_serverBeat = serverBeat;
// NOTE: the entire map description is not known yet
g_lua.callGlobalField("Game", "onLogin", localPlayer);
}
void Game::processLogout()
@ -127,12 +134,42 @@ void Game::processInventoryChange(int slot, const ItemPtr& item)
g_lua.callGlobalField("Game","onInventoryChange", slot, item);
}
void Game::processCreatureMove(const CreaturePtr& creature, const Position& oldPos, const Position& newPos)
{
/*
// walk
if(oldPos.isInRange(newPos, 1, 1, 0)) {
Otc::Direction direction = oldPos.getDirectionFromPosition(newPos);
creature->setDirection(direction);
// teleport
} else {
// stop animation on teleport
if(creature->isWalking())
creature->cancelWalk();
}
*/
if(!m_walkFeedback) {
updatePing();
m_walkFeedback = true;
}
creature->walk(newPos);
}
void Game::processAttackCancel()
{
if(m_localPlayer->isAttacking())
m_localPlayer->setAttackingCreature(nullptr);
}
void Game::processWalkCancel(Otc::Direction direction)
{
if(!m_walkFeedback) {
updatePing();
m_walkFeedback = true;
}
m_localPlayer->cancelWalk(direction, true);
}
void Game::walk(Otc::Direction direction)
{
if(m_localPlayer->isFollowing()) {
@ -145,6 +182,9 @@ void Game::walk(Otc::Direction direction)
m_localPlayer->clientWalk(direction);
// ping calculation restarts when the local players try to walk one tile
m_pingTimer.restart();
switch(direction) {
case Otc::North:
m_protocolGame->sendWalkNorth();
@ -171,6 +211,8 @@ void Game::walk(Otc::Direction direction)
m_protocolGame->sendWalkNorthWest();
break;
}
m_walkFeedback = false;
}
void Game::turn(Otc::Direction direction)
@ -343,3 +385,9 @@ bool Game::checkBotProtection()
#endif
return true;
}
void Game::updatePing()
{
m_ping = m_pingTimer.ticksElapsed();
g_lua.callGlobalField("Game", "onPingUpdate", m_ping);
}

View File

@ -27,6 +27,7 @@
#include <otclient/net/declarations.h>
#include <otclient/core/item.h>
#include <otclient/core/outfit.h>
#include <framework/core/timer.h>
class Game
{
@ -41,14 +42,16 @@ public:
void cleanLogout() { logout(false); }
void processLoginError(const std::string& error);
void processConnectionError(const boost::system::error_code& error);
void processLogin(const LocalPlayerPtr& localPlayer);
void processLogin(const LocalPlayerPtr& localPlayer, int serverBeat);
void processLogout();
void processDeath();
void processTextMessage(const std::string& type, const std::string& message);
void processCreatureSpeak(const std::string& name, int level, const std::string& type, const std::string& message, int channelId, const Position& creaturePos);
void processInventoryChange(int slot, const ItemPtr& item);
void processCreatureMove(const CreaturePtr& creature, const Position& oldPos, const Position& newPos);
void processAttackCancel();
void processWalkCancel(Otc::Direction direction);
void walk(Otc::Direction direction);
void turn(Otc::Direction direction);
@ -80,15 +83,19 @@ public:
LocalPlayerPtr getLocalPlayer() { return m_localPlayer; }
ProtocolGamePtr getProtocolGame() { return m_protocolGame; }
int getProtocolVersion() { return PROTOCOL; }
int getPing() { return m_ping; }
private:
void updatePing();
LocalPlayerPtr m_localPlayer;
ProtocolGamePtr m_protocolGame;
bool m_online;
bool m_dead;
bool m_walkFeedback;
Timer m_pingTimer;
int m_ping;
int m_serverBeat;
};
extern Game g_game;

View File

@ -32,6 +32,13 @@ Item::Item() : Thing()
m_data = 0;
}
ItemPtr Item::create(int id)
{
ItemPtr item = ItemPtr(new Item);
item->setId(id);
return item;
}
void Item::draw(const Point& p, const Rect&)
{
if(m_type->dimensions[ThingType::AnimationPhases] > 1)

View File

@ -31,6 +31,8 @@ class Item : public Thing
public:
Item();
static ItemPtr create(int id = 0);
enum {
TICKS_PER_FRAME = 500
};

View File

@ -34,11 +34,10 @@ LocalPlayer::LocalPlayer()
void LocalPlayer::clientWalk(Otc::Direction direction)
{
// We're not walking, so start a client walk.
if(!m_walking) {
assert(!m_walking);
Position newPos = m_position + Position::getPosFromDirection(direction);
Creature::walk(newPos, false);
m_clientWalking = true;
}
}
void LocalPlayer::walk(const Position& position, bool inverse)

View File

@ -25,8 +25,9 @@
#include "thingstype.h"
#include <framework/graphics/graphics.h>
Thing::Thing() : m_id(0)
Thing::Thing()
{
m_id = 0;
m_xPattern = 0;
m_yPattern = 0;
m_zPattern = 0;
@ -52,7 +53,7 @@ void Thing::internalDraw(const Point& p, int layer)
}
}
void Thing::setId(int id)
void Thing::setId(uint32 id)
{
m_id = id;
m_type = getType();
@ -78,62 +79,4 @@ ThingType *Thing::getType()
return g_thingsType.getEmptyThingType();
}
bool Thing::isGround()
{
return m_type->properties[ThingType::IsGround];
}
bool Thing::isGroundBorder()
{
return m_type->properties[ThingType::IsGroundBorder];
}
bool Thing::isOnBottom()
{
return m_type->properties[ThingType::IsOnBottom];
}
bool Thing::isOnTop()
{
return m_type->properties[ThingType::IsOnTop];
}
bool Thing::isContainer()
{
return m_type->properties[ThingType::IsContainer];
}
bool Thing::isForceUse()
{
return m_type->properties[ThingType::IsForceUse];
}
bool Thing::isMultiUse()
{
return m_type->properties[ThingType::IsMultiUse];
}
bool Thing::isRotateable()
{
return m_type->properties[ThingType::IsRotateable];
}
bool Thing::isNotMoveable()
{
return m_type->properties[ThingType::IsNotMovable];
}
bool Thing::isPickupable()
{
return m_type->properties[ThingType::IsPickupable];
}
bool Thing::ignoreLook()
{
return m_type->properties[ThingType::IgnoreLook];
}
bool Thing::isStackable()
{
return m_type->properties[ThingType::IsStackable];
}

View File

@ -43,10 +43,10 @@ public:
virtual void draw(const Point& p, const Rect&) = 0;
void setId(int id);
void setId(uint32 id);
virtual void setPos(const Position& position) { m_position = position; }
int getId() const { return m_id; }
uint32 getId() const { return m_id; }
Position getPos() const { return m_position; }
int getStackPriority();
virtual ThingType *getType();
@ -58,26 +58,30 @@ public:
ThingPtr asThing() { return std::static_pointer_cast<Thing>(shared_from_this()); }
virtual ItemPtr asItem() { return nullptr; }
virtual CreaturePtr asCreature() { return nullptr; }
virtual EffectPtr asEffect() { return nullptr; }
virtual MissilePtr asMissile() { return nullptr; }
virtual CreaturePtr asCreature() { return nullptr; }
virtual NpcPtr asNpc() { return nullptr; }
virtual MonsterPtr asMonster() { return nullptr; }
virtual PlayerPtr asPlayer() { return nullptr; }
virtual LocalPlayerPtr asLocalPlayer() { return nullptr; }
virtual AnimatedTextPtr asAnimatedText() { return nullptr; }
virtual StaticTextPtr asStaticText() { return nullptr; }
bool isGround();
bool isGroundBorder();
bool isOnBottom();
bool isOnTop();
bool isContainer();
bool isForceUse();
bool isMultiUse();
bool isRotateable();
bool isNotMoveable();
bool isPickupable();
bool ignoreLook();
bool isStackable();
bool isGround() { return m_type->properties[ThingType::IsGround]; }
bool isGroundBorder() { return m_type->properties[ThingType::IsGroundBorder]; }
bool isOnBottom() { return m_type->properties[ThingType::IsOnBottom]; }
bool isOnTop() { return m_type->properties[ThingType::IsOnTop]; }
bool isContainer() { return m_type->properties[ThingType::IsContainer]; }
bool isForceUse() { return m_type->properties[ThingType::IsForceUse]; }
bool isMultiUse() { return m_type->properties[ThingType::IsMultiUse]; }
bool isRotateable() { return m_type->properties[ThingType::IsRotateable]; }
bool isNotMoveable() { return m_type->properties[ThingType::IsNotMovable]; }
bool isPickupable() { return m_type->properties[ThingType::IsPickupable]; }
bool ignoreLook() { return m_type->properties[ThingType::IgnoreLook]; }
bool isStackable() { return m_type->properties[ThingType::IsStackable]; }
bool isFluid() { return m_type->properties[ThingType::IsFluid]; }
bool isFluidContainer() { return m_type->properties[ThingType::IsFluidContainer]; }
protected:
void internalDraw(const Point& p, int layer);

View File

@ -128,19 +128,19 @@ void OTClient::registerLuaFunctions()
g_lua.bindClassMemberFunction<Creature>("setShieldTexture", &Creature::setShieldTexture);
g_lua.bindClassMemberFunction<Creature>("setEmblemTexture", &Creature::setEmblemTexture);
g_lua.registerClass<Player, Creature>();
g_lua.registerClass<Item, Thing>();
g_lua.registerClass<Effect, Thing>();
g_lua.registerClass<Missile, Thing>();
g_lua.registerClass<StaticText, Thing>();
g_lua.registerClass<AnimatedText, Thing>();
g_lua.registerClass<Player, Creature>();
g_lua.registerClass<Npc, Creature>();
g_lua.registerClass<Monster, Creature>();
g_lua.registerClass<LocalPlayer, Player>();
g_lua.bindClassMemberFunction<LocalPlayer>("getAttackingCreature", &LocalPlayer::getAttackingCreature);
g_lua.bindClassMemberFunction<LocalPlayer>("getFollowingCreature", &LocalPlayer::getFollowingCreature);
g_lua.registerClass<Item, Thing>();
g_lua.registerClass<Tile>();
g_lua.bindClassMemberFunction<Tile>("clean", &Tile::clean);
g_lua.bindClassMemberFunction<Tile>("addThing", &Tile::addThing);

View File

@ -268,8 +268,8 @@ void ProtocolGame::parsePlayerLogin(InputMessage& msg)
m_localPlayer = LocalPlayerPtr(new LocalPlayer);
m_localPlayer->setId(playerId);
g_game.setServerBeat(serverBeat);
m_localPlayer->setCanReportBugs(playerCanReportBugs);
g_game.processLogin(m_localPlayer, serverBeat);
}
void ProtocolGame::parseGMActions(InputMessage& msg)
@ -281,7 +281,7 @@ void ProtocolGame::parseGMActions(InputMessage& msg)
void ProtocolGame::parseLoginError(InputMessage& msg)
{
std::string error = msg.getString();
g_dispatcher.addEvent(std::bind(&Game::processLoginError, &g_game, error));
g_game.processLoginError(error);
}
void ProtocolGame::parseFYIMessage(InputMessage& msg)
@ -303,7 +303,7 @@ void ProtocolGame::parsePing(InputMessage&)
void ProtocolGame::parseDeath(InputMessage& msg)
{
msg.getU8(); // 100 is a fair death. < 100 is a unfair death.
g_dispatcher.addEvent(std::bind(&Game::processDeath, &g_game));
g_game.processDeath();
}
void ProtocolGame::parseMapDescription(InputMessage& msg)
@ -355,14 +355,9 @@ void ProtocolGame::parseUpdateTile(InputMessage& msg)
uint16 thingId = msg.getU16(true);
if(thingId == 0xFF01) {
msg.getU16();
/*msg->AddByte(0);
msg->AddByte(0xFF);*/
}
else {
} else {
setTileDescription(msg, tilePos);
msg.getU16();
/*msg->AddByte(0x01);
msg->AddByte(0xFF);*/
}
}
@ -407,21 +402,23 @@ void ProtocolGame::parseCreatureMove(InputMessage& msg)
ThingPtr thing = g_map.getTile(oldPos)->getThing(oldStackpos);
if(!thing) {
logError("could not get thing");
logTraceError("could not get thing");
return;
}
CreaturePtr creature = thing->asCreature();
if(!creature) {
logError("thing is not a creature");
logTraceError("thing is not a creature");
return;
}
creature->walk(newPos);
g_game.processCreatureMove(creature, oldPos, newPos);
// update map tiles
g_map.removeThing(thing);
g_map.addThing(thing, newPos);
//g_game.processCreatureMove(creature, oldPos, newPos);
}
void ProtocolGame::parseOpenContainer(InputMessage& msg)
@ -465,13 +462,13 @@ void ProtocolGame::parseAddInventoryItem(InputMessage& msg)
{
uint8 slot = msg.getU8();
ItemPtr item = internalGetItem(msg, 0xFFFF);
g_dispatcher.addEvent(std::bind(&Game::processInventoryChange, &g_game, slot, item));
g_game.processInventoryChange(slot, item);
}
void ProtocolGame::parseRemoveInventoryItem(InputMessage& msg)
{
uint8 slot = msg.getU8();
g_dispatcher.addEvent(std::bind(&Game::processInventoryChange, &g_game, slot, ItemPtr()));
g_game.processInventoryChange(slot, ItemPtr());
}
void ProtocolGame::parseOpenShopWindow(InputMessage& msg)
@ -664,47 +661,31 @@ void ProtocolGame::parsePlayerStats(InputMessage& msg)
{
m_localPlayer->setStatistic(Otc::Health, msg.getU16());
m_localPlayer->setStatistic(Otc::MaxHealth, msg.getU16());
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onHealthChange", m_localPlayer->getStatistic(Otc::Health), m_localPlayer->getStatistic(Otc::MaxHealth));
});
m_localPlayer->setStatistic(Otc::FreeCapacity, msg.getU32() / 100.0);
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onFreeCapacityChange", m_localPlayer->getStatistic(Otc::FreeCapacity));
});
m_localPlayer->setStatistic(Otc::Experience, msg.getU32());
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onExperienceChange", m_localPlayer->getStatistic(Otc::Experience));
});
m_localPlayer->setStatistic(Otc::Level, msg.getU16());
m_localPlayer->setStatistic(Otc::LevelPercent, msg.getU8());
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onLevelChange", m_localPlayer->getStatistic(Otc::Level), m_localPlayer->getStatistic(Otc::LevelPercent));
});
m_localPlayer->setStatistic(Otc::Mana, msg.getU16());
m_localPlayer->setStatistic(Otc::MaxMana, msg.getU16());
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onManaChange", m_localPlayer->getStatistic(Otc::Mana), m_localPlayer->getStatistic(Otc::MaxMana));
});
m_localPlayer->setStatistic(Otc::MagicLevel, msg.getU8());
m_localPlayer->setStatistic(Otc::MagicLevelPercent, msg.getU8());
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onMagicLevelChange", m_localPlayer->getStatistic(Otc::MagicLevel), m_localPlayer->getStatistic(Otc::MagicLevelPercent));
});
m_localPlayer->setStatistic(Otc::Soul, msg.getU8());
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onSoulChange", m_localPlayer->getStatistic(Otc::Soul));
});
m_localPlayer->setStatistic(Otc::Stamina, msg.getU16());
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onStaminaChange", m_localPlayer->getStatistic(Otc::Stamina));
});
}
void ProtocolGame::parsePlayerSkills(InputMessage& msg)
@ -716,9 +697,7 @@ void ProtocolGame::parsePlayerSkills(InputMessage& msg)
m_localPlayer->setSkill((Otc::Skill)skill, (Otc::SkillType)skillType, values[skillType]);
}
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onSkillChange", skill, values[Otc::SkillLevel], values[Otc::SkillPercent]);
});
}
}
@ -731,7 +710,7 @@ void ProtocolGame::parsePlayerIcons(InputMessage& msg)
void ProtocolGame::parsePlayerCancelAttack(InputMessage& msg)
{
msg.getU32(); // unknown
g_dispatcher.addEvent(std::bind(&Game::processAttackCancel, &g_game));
g_game.processAttackCancel();
}
void ProtocolGame::parseCreatureSpeak(InputMessage& msg)
@ -775,9 +754,7 @@ void ProtocolGame::parseCreatureSpeak(InputMessage& msg)
std::string message = msg.getString();
std::string typeDesc = Proto::translateSpeakType(type);
g_dispatcher.addEvent([=] {
g_game.processCreatureSpeak(name, level, typeDesc, message, channelId, creaturePos);
});
}
void ProtocolGame::parseChannelList(InputMessage& msg)
@ -790,9 +767,7 @@ void ProtocolGame::parseChannelList(InputMessage& msg)
channelList.push_back(std::make_tuple(id, name));
}
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onChannelList", channelList);
});
}
void ProtocolGame::parseOpenChannel(InputMessage& msg)
@ -800,9 +775,7 @@ void ProtocolGame::parseOpenChannel(InputMessage& msg)
int channelId = msg.getU16();
std::string name = msg.getString();
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onOpenChannel", channelId, name);
});
}
void ProtocolGame::parseOpenPrivatePlayerChat(InputMessage& msg)
@ -833,13 +806,14 @@ void ProtocolGame::parseTextMessage(InputMessage& msg)
std::string typeDesc = Proto::translateTextMessageType(type);
std::string message = msg.getString();
g_dispatcher.addEvent(std::bind(&Game::processTextMessage, &g_game, typeDesc, message));
g_game.processTextMessage(typeDesc, message);
}
void ProtocolGame::parseCancelWalk(InputMessage& msg)
{
Otc::Direction direction = (Otc::Direction)msg.getU8();
m_localPlayer->cancelWalk(direction, true);
g_game.processWalkCancel(direction);
}
void ProtocolGame::parseFloorChangeUp(InputMessage& msg)
@ -898,9 +872,7 @@ void ProtocolGame::parseOutfitWindow(InputMessage& msg)
creature->setXPattern(2);
creature->setOutfit(outfit);
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onOpenOutfitWindow", creature, outfitList);
});
}
void ProtocolGame::parseVipState(InputMessage& msg)
@ -909,27 +881,21 @@ void ProtocolGame::parseVipState(InputMessage& msg)
std::string name = msg.getString();
bool online = msg.getU8() != 0;
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onAddVip", id, name, online);
});
}
void ProtocolGame::parseVipLogin(InputMessage& msg)
{
int id = msg.getU32();
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onVipStateChange", id, true);
});
}
void ProtocolGame::parseVipLogout(InputMessage& msg)
{
int id = msg.getU32();
g_dispatcher.addEvent([=] {
g_lua.callGlobalField("Game", "onVipStateChange", id, false);
});
}
void ProtocolGame::parseShowTutorial(InputMessage& msg)
@ -1068,9 +1034,8 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg)
if(knownCreature)
creature = knownCreature;
else
logFatal("Server says creature is known, but its not on creatures list.");
}
else if(thingId == 0x0061) { //creature is not known
logTraceError("server says creature is known, but its not on creatures list");
} else if(thingId == 0x0061) { //creature is not known
uint32 removeId = msg.getU32();
uint32 id = msg.getU32();
std::string name = msg.getString();
@ -1080,16 +1045,16 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg)
g_map.removeCreatureById(removeId);
if(id == (uint32)m_localPlayer->getId())
creature = m_localPlayer->asCreature();
if(id == m_localPlayer->getId())
creature = m_localPlayer;
else if(id >= Proto::PlayerStartId && id < Proto::PlayerEndId)
creature = PlayerPtr(new Player)->asCreature();
creature = PlayerPtr(new Player);
else if(id >= Proto::MonsterStartId && id < Proto::MonsterEndId)
creature = CreaturePtr(new Creature);
creature = MonsterPtr(new Monster);
else if(id >= Proto::NpcStartId && id < Proto::NpcEndId)
creature = CreaturePtr(new Creature);
creature = NpcPtr(new Npc);
else
logFatal("creature id is invalid");
logTraceError("creature id is invalid");
creature->setId(id);
creature->setName(name);
@ -1113,6 +1078,7 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg)
bool passable = (msg.getU8() == 0);
if(creature) {
creature->setHealthPercent(healthPercent);
creature->setDirection(direction);
creature->setOutfit(outfit);
@ -1123,19 +1089,12 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg)
creature->setEmblem(emblem);
creature->setPassable(passable);
creature->cancelWalk(direction);
}
thing = creature;
// login event is generated the first time that local player gets known
if(!g_game.isOnline() && creature == m_localPlayer) {
// this event must be scheduled because the entire map description is not known yet
g_dispatcher.addEvent(std::bind(&Game::processLogin, &g_game, m_localPlayer));
}
}
else if(thingId == 0x0063) { // creature turn
} else if(thingId == 0x0063) { // creature turn
parseCreatureTurn(msg);
}
else // item
} else // item
thing = internalGetItem(msg, thingId);
return thing;
@ -1143,14 +1102,11 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg)
ItemPtr ProtocolGame::internalGetItem(InputMessage& msg, uint16 id)
{
ItemPtr item = ItemPtr(new Item());
if(id == 0xFFFF)
id = msg.getU16();
item->setId(id);
ThingType *itemType = item->getType();
if(itemType->properties[ThingType::IsStackable] || itemType->properties[ThingType::IsFluidContainer] || itemType->properties[ThingType::IsFluid])
ItemPtr item = Item::create(id);
if(item->isStackable() || item->isFluidContainer() || item->isFluid())
item->setData(msg.getU8());
return item;