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

View File

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

View File

@ -72,6 +72,7 @@ public:
bool getPassable() { return m_passable; } bool getPassable() { return m_passable; }
ThingType *getType(); ThingType *getType();
//virtual void walk(const Position& oldPos, const Position& newPos, bool inverse = true);
virtual void walk(const Position& position, bool inverse = true); virtual void walk(const Position& position, bool inverse = true);
void turn(Otc::Direction direction); void turn(Otc::Direction direction);
virtual void cancelWalk(Otc::Direction direction, bool force = false); virtual void cancelWalk(Otc::Direction direction, bool force = false);
@ -107,4 +108,14 @@ protected:
Otc::Direction m_turnDirection; 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 #endif

View File

@ -29,10 +29,12 @@ class Tile;
class Thing; class Thing;
class Item; class Item;
class Creature; class Creature;
class Effect; class Monster;
class Missile; class Npc;
class Player; class Player;
class LocalPlayer; class LocalPlayer;
class Effect;
class Missile;
class AnimatedText; class AnimatedText;
class StaticText; class StaticText;
@ -40,10 +42,12 @@ typedef std::shared_ptr<Tile> TilePtr;
typedef std::shared_ptr<Thing> ThingPtr; typedef std::shared_ptr<Thing> ThingPtr;
typedef std::shared_ptr<Item> ItemPtr; typedef std::shared_ptr<Item> ItemPtr;
typedef std::shared_ptr<Creature> CreaturePtr; typedef std::shared_ptr<Creature> CreaturePtr;
typedef std::shared_ptr<Effect> EffectPtr; typedef std::shared_ptr<Monster> MonsterPtr;
typedef std::shared_ptr<Missile> MissilePtr; typedef std::shared_ptr<Npc> NpcPtr;
typedef std::shared_ptr<Player> PlayerPtr; typedef std::shared_ptr<Player> PlayerPtr;
typedef std::shared_ptr<LocalPlayer> LocalPlayerPtr; 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<AnimatedText> AnimatedTextPtr;
typedef std::shared_ptr<StaticText> StaticTextPtr; 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_online = false;
m_dead = false; m_dead = false;
m_walkFeedback = true;
m_ping = 0;
m_pingTimer.restart();
m_protocolGame = ProtocolGamePtr(new ProtocolGame); m_protocolGame = ProtocolGamePtr(new ProtocolGame);
m_protocolGame->login(account, password, worldHost, (uint16)worldPort, characterName); 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_localPlayer = localPlayer;
m_online = true; 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() void Game::processLogout()
@ -127,12 +134,42 @@ void Game::processInventoryChange(int slot, const ItemPtr& item)
g_lua.callGlobalField("Game","onInventoryChange", slot, 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() void Game::processAttackCancel()
{ {
if(m_localPlayer->isAttacking()) if(m_localPlayer->isAttacking())
m_localPlayer->setAttackingCreature(nullptr); 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) void Game::walk(Otc::Direction direction)
{ {
if(m_localPlayer->isFollowing()) { if(m_localPlayer->isFollowing()) {
@ -145,6 +182,9 @@ void Game::walk(Otc::Direction direction)
m_localPlayer->clientWalk(direction); m_localPlayer->clientWalk(direction);
// ping calculation restarts when the local players try to walk one tile
m_pingTimer.restart();
switch(direction) { switch(direction) {
case Otc::North: case Otc::North:
m_protocolGame->sendWalkNorth(); m_protocolGame->sendWalkNorth();
@ -171,6 +211,8 @@ void Game::walk(Otc::Direction direction)
m_protocolGame->sendWalkNorthWest(); m_protocolGame->sendWalkNorthWest();
break; break;
} }
m_walkFeedback = false;
} }
void Game::turn(Otc::Direction direction) void Game::turn(Otc::Direction direction)
@ -343,3 +385,9 @@ bool Game::checkBotProtection()
#endif #endif
return true; 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/net/declarations.h>
#include <otclient/core/item.h> #include <otclient/core/item.h>
#include <otclient/core/outfit.h> #include <otclient/core/outfit.h>
#include <framework/core/timer.h>
class Game class Game
{ {
@ -41,14 +42,16 @@ public:
void cleanLogout() { logout(false); } void cleanLogout() { logout(false); }
void processLoginError(const std::string& error); void processLoginError(const std::string& error);
void processConnectionError(const boost::system::error_code& error); void processConnectionError(const boost::system::error_code& error);
void processLogin(const LocalPlayerPtr& localPlayer); void processLogin(const LocalPlayerPtr& localPlayer, int serverBeat);
void processLogout(); void processLogout();
void processDeath(); void processDeath();
void processTextMessage(const std::string& type, const std::string& message); 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 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 processInventoryChange(int slot, const ItemPtr& item);
void processCreatureMove(const CreaturePtr& creature, const Position& oldPos, const Position& newPos);
void processAttackCancel(); void processAttackCancel();
void processWalkCancel(Otc::Direction direction);
void walk(Otc::Direction direction); void walk(Otc::Direction direction);
void turn(Otc::Direction direction); void turn(Otc::Direction direction);
@ -80,15 +83,19 @@ public:
LocalPlayerPtr getLocalPlayer() { return m_localPlayer; } LocalPlayerPtr getLocalPlayer() { return m_localPlayer; }
ProtocolGamePtr getProtocolGame() { return m_protocolGame; } ProtocolGamePtr getProtocolGame() { return m_protocolGame; }
int getProtocolVersion() { return PROTOCOL; } int getProtocolVersion() { return PROTOCOL; }
int getPing() { return m_ping; }
private: private:
void updatePing();
LocalPlayerPtr m_localPlayer; LocalPlayerPtr m_localPlayer;
ProtocolGamePtr m_protocolGame; ProtocolGamePtr m_protocolGame;
bool m_online; bool m_online;
bool m_dead; bool m_dead;
bool m_walkFeedback;
Timer m_pingTimer;
int m_ping;
int m_serverBeat; int m_serverBeat;
}; };
extern Game g_game; extern Game g_game;

View File

@ -32,6 +32,13 @@ Item::Item() : Thing()
m_data = 0; 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&) void Item::draw(const Point& p, const Rect&)
{ {
if(m_type->dimensions[ThingType::AnimationPhases] > 1) if(m_type->dimensions[ThingType::AnimationPhases] > 1)

View File

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

View File

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

View File

@ -25,8 +25,9 @@
#include "thingstype.h" #include "thingstype.h"
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
Thing::Thing() : m_id(0) Thing::Thing()
{ {
m_id = 0;
m_xPattern = 0; m_xPattern = 0;
m_yPattern = 0; m_yPattern = 0;
m_zPattern = 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_id = id;
m_type = getType(); m_type = getType();
@ -78,62 +79,4 @@ ThingType *Thing::getType()
return g_thingsType.getEmptyThingType(); 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; 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; } 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; } Position getPos() const { return m_position; }
int getStackPriority(); int getStackPriority();
virtual ThingType *getType(); virtual ThingType *getType();
@ -58,26 +58,30 @@ public:
ThingPtr asThing() { return std::static_pointer_cast<Thing>(shared_from_this()); } ThingPtr asThing() { return std::static_pointer_cast<Thing>(shared_from_this()); }
virtual ItemPtr asItem() { return nullptr; } virtual ItemPtr asItem() { return nullptr; }
virtual CreaturePtr asCreature() { return nullptr; }
virtual EffectPtr asEffect() { return nullptr; } virtual EffectPtr asEffect() { return nullptr; }
virtual MissilePtr asMissile() { 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 PlayerPtr asPlayer() { return nullptr; }
virtual LocalPlayerPtr asLocalPlayer() { return nullptr; } virtual LocalPlayerPtr asLocalPlayer() { return nullptr; }
virtual AnimatedTextPtr asAnimatedText() { return nullptr; } virtual AnimatedTextPtr asAnimatedText() { return nullptr; }
virtual StaticTextPtr asStaticText() { return nullptr; } virtual StaticTextPtr asStaticText() { return nullptr; }
bool isGround(); bool isGround() { return m_type->properties[ThingType::IsGround]; }
bool isGroundBorder(); bool isGroundBorder() { return m_type->properties[ThingType::IsGroundBorder]; }
bool isOnBottom(); bool isOnBottom() { return m_type->properties[ThingType::IsOnBottom]; }
bool isOnTop(); bool isOnTop() { return m_type->properties[ThingType::IsOnTop]; }
bool isContainer(); bool isContainer() { return m_type->properties[ThingType::IsContainer]; }
bool isForceUse(); bool isForceUse() { return m_type->properties[ThingType::IsForceUse]; }
bool isMultiUse(); bool isMultiUse() { return m_type->properties[ThingType::IsMultiUse]; }
bool isRotateable(); bool isRotateable() { return m_type->properties[ThingType::IsRotateable]; }
bool isNotMoveable(); bool isNotMoveable() { return m_type->properties[ThingType::IsNotMovable]; }
bool isPickupable(); bool isPickupable() { return m_type->properties[ThingType::IsPickupable]; }
bool ignoreLook(); bool ignoreLook() { return m_type->properties[ThingType::IgnoreLook]; }
bool isStackable(); 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: protected:
void internalDraw(const Point& p, int layer); 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>("setShieldTexture", &Creature::setShieldTexture);
g_lua.bindClassMemberFunction<Creature>("setEmblemTexture", &Creature::setEmblemTexture); 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<Effect, Thing>();
g_lua.registerClass<Missile, Thing>(); g_lua.registerClass<Missile, Thing>();
g_lua.registerClass<StaticText, Thing>(); g_lua.registerClass<StaticText, Thing>();
g_lua.registerClass<AnimatedText, 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.registerClass<LocalPlayer, Player>();
g_lua.bindClassMemberFunction<LocalPlayer>("getAttackingCreature", &LocalPlayer::getAttackingCreature); g_lua.bindClassMemberFunction<LocalPlayer>("getAttackingCreature", &LocalPlayer::getAttackingCreature);
g_lua.bindClassMemberFunction<LocalPlayer>("getFollowingCreature", &LocalPlayer::getFollowingCreature); g_lua.bindClassMemberFunction<LocalPlayer>("getFollowingCreature", &LocalPlayer::getFollowingCreature);
g_lua.registerClass<Item, Thing>();
g_lua.registerClass<Tile>(); g_lua.registerClass<Tile>();
g_lua.bindClassMemberFunction<Tile>("clean", &Tile::clean); g_lua.bindClassMemberFunction<Tile>("clean", &Tile::clean);
g_lua.bindClassMemberFunction<Tile>("addThing", &Tile::addThing); 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 = LocalPlayerPtr(new LocalPlayer);
m_localPlayer->setId(playerId); m_localPlayer->setId(playerId);
g_game.setServerBeat(serverBeat);
m_localPlayer->setCanReportBugs(playerCanReportBugs); m_localPlayer->setCanReportBugs(playerCanReportBugs);
g_game.processLogin(m_localPlayer, serverBeat);
} }
void ProtocolGame::parseGMActions(InputMessage& msg) void ProtocolGame::parseGMActions(InputMessage& msg)
@ -281,7 +281,7 @@ void ProtocolGame::parseGMActions(InputMessage& msg)
void ProtocolGame::parseLoginError(InputMessage& msg) void ProtocolGame::parseLoginError(InputMessage& msg)
{ {
std::string error = msg.getString(); std::string error = msg.getString();
g_dispatcher.addEvent(std::bind(&Game::processLoginError, &g_game, error)); g_game.processLoginError(error);
} }
void ProtocolGame::parseFYIMessage(InputMessage& msg) void ProtocolGame::parseFYIMessage(InputMessage& msg)
@ -303,7 +303,7 @@ void ProtocolGame::parsePing(InputMessage&)
void ProtocolGame::parseDeath(InputMessage& msg) void ProtocolGame::parseDeath(InputMessage& msg)
{ {
msg.getU8(); // 100 is a fair death. < 100 is a unfair death. 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) void ProtocolGame::parseMapDescription(InputMessage& msg)
@ -355,14 +355,9 @@ void ProtocolGame::parseUpdateTile(InputMessage& msg)
uint16 thingId = msg.getU16(true); uint16 thingId = msg.getU16(true);
if(thingId == 0xFF01) { if(thingId == 0xFF01) {
msg.getU16(); msg.getU16();
/*msg->AddByte(0); } else {
msg->AddByte(0xFF);*/
}
else {
setTileDescription(msg, tilePos); setTileDescription(msg, tilePos);
msg.getU16(); 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); ThingPtr thing = g_map.getTile(oldPos)->getThing(oldStackpos);
if(!thing) { if(!thing) {
logError("could not get thing"); logTraceError("could not get thing");
return; return;
} }
CreaturePtr creature = thing->asCreature(); CreaturePtr creature = thing->asCreature();
if(!creature) { if(!creature) {
logError("thing is not a creature"); logTraceError("thing is not a creature");
return; return;
} }
creature->walk(newPos); g_game.processCreatureMove(creature, oldPos, newPos);
// update map tiles // update map tiles
g_map.removeThing(thing); g_map.removeThing(thing);
g_map.addThing(thing, newPos); g_map.addThing(thing, newPos);
//g_game.processCreatureMove(creature, oldPos, newPos);
} }
void ProtocolGame::parseOpenContainer(InputMessage& msg) void ProtocolGame::parseOpenContainer(InputMessage& msg)
@ -465,13 +462,13 @@ void ProtocolGame::parseAddInventoryItem(InputMessage& msg)
{ {
uint8 slot = msg.getU8(); uint8 slot = msg.getU8();
ItemPtr item = internalGetItem(msg, 0xFFFF); 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) void ProtocolGame::parseRemoveInventoryItem(InputMessage& msg)
{ {
uint8 slot = msg.getU8(); 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) 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::Health, msg.getU16());
m_localPlayer->setStatistic(Otc::MaxHealth, 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));
g_lua.callGlobalField("Game", "onHealthChange", m_localPlayer->getStatistic(Otc::Health), m_localPlayer->getStatistic(Otc::MaxHealth));
});
m_localPlayer->setStatistic(Otc::FreeCapacity, msg.getU32() / 100.0); m_localPlayer->setStatistic(Otc::FreeCapacity, msg.getU32() / 100.0);
g_dispatcher.addEvent([=] { g_lua.callGlobalField("Game", "onFreeCapacityChange", m_localPlayer->getStatistic(Otc::FreeCapacity));
g_lua.callGlobalField("Game", "onFreeCapacityChange", m_localPlayer->getStatistic(Otc::FreeCapacity));
});
m_localPlayer->setStatistic(Otc::Experience, msg.getU32()); m_localPlayer->setStatistic(Otc::Experience, msg.getU32());
g_dispatcher.addEvent([=] { g_lua.callGlobalField("Game", "onExperienceChange", m_localPlayer->getStatistic(Otc::Experience));
g_lua.callGlobalField("Game", "onExperienceChange", m_localPlayer->getStatistic(Otc::Experience));
});
m_localPlayer->setStatistic(Otc::Level, msg.getU16()); m_localPlayer->setStatistic(Otc::Level, msg.getU16());
m_localPlayer->setStatistic(Otc::LevelPercent, msg.getU8()); 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));
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::Mana, msg.getU16());
m_localPlayer->setStatistic(Otc::MaxMana, 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));
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::MagicLevel, msg.getU8());
m_localPlayer->setStatistic(Otc::MagicLevelPercent, 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));
g_lua.callGlobalField("Game", "onMagicLevelChange", m_localPlayer->getStatistic(Otc::MagicLevel), m_localPlayer->getStatistic(Otc::MagicLevelPercent));
});
m_localPlayer->setStatistic(Otc::Soul, msg.getU8()); m_localPlayer->setStatistic(Otc::Soul, msg.getU8());
g_dispatcher.addEvent([=] { g_lua.callGlobalField("Game", "onSoulChange", m_localPlayer->getStatistic(Otc::Soul));
g_lua.callGlobalField("Game", "onSoulChange", m_localPlayer->getStatistic(Otc::Soul));
});
m_localPlayer->setStatistic(Otc::Stamina, msg.getU16()); m_localPlayer->setStatistic(Otc::Stamina, msg.getU16());
g_dispatcher.addEvent([=] { g_lua.callGlobalField("Game", "onStaminaChange", m_localPlayer->getStatistic(Otc::Stamina));
g_lua.callGlobalField("Game", "onStaminaChange", m_localPlayer->getStatistic(Otc::Stamina));
});
} }
void ProtocolGame::parsePlayerSkills(InputMessage& msg) 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]); 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]);
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) void ProtocolGame::parsePlayerCancelAttack(InputMessage& msg)
{ {
msg.getU32(); // unknown msg.getU32(); // unknown
g_dispatcher.addEvent(std::bind(&Game::processAttackCancel, &g_game)); g_game.processAttackCancel();
} }
void ProtocolGame::parseCreatureSpeak(InputMessage& msg) void ProtocolGame::parseCreatureSpeak(InputMessage& msg)
@ -775,9 +754,7 @@ void ProtocolGame::parseCreatureSpeak(InputMessage& msg)
std::string message = msg.getString(); std::string message = msg.getString();
std::string typeDesc = Proto::translateSpeakType(type); std::string typeDesc = Proto::translateSpeakType(type);
g_dispatcher.addEvent([=] { g_game.processCreatureSpeak(name, level, typeDesc, message, channelId, creaturePos);
g_game.processCreatureSpeak(name, level, typeDesc, message, channelId, creaturePos);
});
} }
void ProtocolGame::parseChannelList(InputMessage& msg) void ProtocolGame::parseChannelList(InputMessage& msg)
@ -790,9 +767,7 @@ void ProtocolGame::parseChannelList(InputMessage& msg)
channelList.push_back(std::make_tuple(id, name)); channelList.push_back(std::make_tuple(id, name));
} }
g_dispatcher.addEvent([=] { g_lua.callGlobalField("Game", "onChannelList", channelList);
g_lua.callGlobalField("Game", "onChannelList", channelList);
});
} }
void ProtocolGame::parseOpenChannel(InputMessage& msg) void ProtocolGame::parseOpenChannel(InputMessage& msg)
@ -800,9 +775,7 @@ void ProtocolGame::parseOpenChannel(InputMessage& msg)
int channelId = msg.getU16(); int channelId = msg.getU16();
std::string name = msg.getString(); std::string name = msg.getString();
g_dispatcher.addEvent([=] { g_lua.callGlobalField("Game", "onOpenChannel", channelId, name);
g_lua.callGlobalField("Game", "onOpenChannel", channelId, name);
});
} }
void ProtocolGame::parseOpenPrivatePlayerChat(InputMessage& msg) void ProtocolGame::parseOpenPrivatePlayerChat(InputMessage& msg)
@ -833,13 +806,14 @@ void ProtocolGame::parseTextMessage(InputMessage& msg)
std::string typeDesc = Proto::translateTextMessageType(type); std::string typeDesc = Proto::translateTextMessageType(type);
std::string message = msg.getString(); 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) void ProtocolGame::parseCancelWalk(InputMessage& msg)
{ {
Otc::Direction direction = (Otc::Direction)msg.getU8(); Otc::Direction direction = (Otc::Direction)msg.getU8();
m_localPlayer->cancelWalk(direction, true);
g_game.processWalkCancel(direction);
} }
void ProtocolGame::parseFloorChangeUp(InputMessage& msg) void ProtocolGame::parseFloorChangeUp(InputMessage& msg)
@ -898,9 +872,7 @@ void ProtocolGame::parseOutfitWindow(InputMessage& msg)
creature->setXPattern(2); creature->setXPattern(2);
creature->setOutfit(outfit); creature->setOutfit(outfit);
g_dispatcher.addEvent([=] { g_lua.callGlobalField("Game", "onOpenOutfitWindow", creature, outfitList);
g_lua.callGlobalField("Game", "onOpenOutfitWindow", creature, outfitList);
});
} }
void ProtocolGame::parseVipState(InputMessage& msg) void ProtocolGame::parseVipState(InputMessage& msg)
@ -909,27 +881,21 @@ void ProtocolGame::parseVipState(InputMessage& msg)
std::string name = msg.getString(); std::string name = msg.getString();
bool online = msg.getU8() != 0; bool online = msg.getU8() != 0;
g_dispatcher.addEvent([=] { g_lua.callGlobalField("Game", "onAddVip", id, name, online);
g_lua.callGlobalField("Game", "onAddVip", id, name, online);
});
} }
void ProtocolGame::parseVipLogin(InputMessage& msg) void ProtocolGame::parseVipLogin(InputMessage& msg)
{ {
int id = msg.getU32(); int id = msg.getU32();
g_dispatcher.addEvent([=] { g_lua.callGlobalField("Game", "onVipStateChange", id, true);
g_lua.callGlobalField("Game", "onVipStateChange", id, true);
});
} }
void ProtocolGame::parseVipLogout(InputMessage& msg) void ProtocolGame::parseVipLogout(InputMessage& msg)
{ {
int id = msg.getU32(); int id = msg.getU32();
g_dispatcher.addEvent([=] { g_lua.callGlobalField("Game", "onVipStateChange", id, false);
g_lua.callGlobalField("Game", "onVipStateChange", id, false);
});
} }
void ProtocolGame::parseShowTutorial(InputMessage& msg) void ProtocolGame::parseShowTutorial(InputMessage& msg)
@ -1068,9 +1034,8 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg)
if(knownCreature) if(knownCreature)
creature = knownCreature; creature = knownCreature;
else else
logFatal("Server says creature is known, but its not on creatures list."); logTraceError("server says creature is known, but its not on creatures list");
} } else if(thingId == 0x0061) { //creature is not known
else if(thingId == 0x0061) { //creature is not known
uint32 removeId = msg.getU32(); uint32 removeId = msg.getU32();
uint32 id = msg.getU32(); uint32 id = msg.getU32();
std::string name = msg.getString(); std::string name = msg.getString();
@ -1080,16 +1045,16 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg)
g_map.removeCreatureById(removeId); g_map.removeCreatureById(removeId);
if(id == (uint32)m_localPlayer->getId()) if(id == m_localPlayer->getId())
creature = m_localPlayer->asCreature(); creature = m_localPlayer;
else if(id >= Proto::PlayerStartId && id < Proto::PlayerEndId) 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) else if(id >= Proto::MonsterStartId && id < Proto::MonsterEndId)
creature = CreaturePtr(new Creature); creature = MonsterPtr(new Monster);
else if(id >= Proto::NpcStartId && id < Proto::NpcEndId) else if(id >= Proto::NpcStartId && id < Proto::NpcEndId)
creature = CreaturePtr(new Creature); creature = NpcPtr(new Npc);
else else
logFatal("creature id is invalid"); logTraceError("creature id is invalid");
creature->setId(id); creature->setId(id);
creature->setName(name); creature->setName(name);
@ -1113,29 +1078,23 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg)
bool passable = (msg.getU8() == 0); bool passable = (msg.getU8() == 0);
creature->setHealthPercent(healthPercent); if(creature) {
creature->setDirection(direction); creature->setHealthPercent(healthPercent);
creature->setOutfit(outfit); creature->setDirection(direction);
creature->setLight(light); creature->setOutfit(outfit);
creature->setSpeed(speed); creature->setLight(light);
creature->setSkull(skull); creature->setSpeed(speed);
creature->setShield(shield); creature->setSkull(skull);
creature->setEmblem(emblem); creature->setShield(shield);
creature->setPassable(passable); creature->setEmblem(emblem);
creature->cancelWalk(direction); creature->setPassable(passable);
creature->cancelWalk(direction);
}
thing = creature; thing = creature;
} else if(thingId == 0x0063) { // creature turn
// 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
parseCreatureTurn(msg); parseCreatureTurn(msg);
} } else // item
else // item
thing = internalGetItem(msg, thingId); thing = internalGetItem(msg, thingId);
return thing; return thing;
@ -1143,14 +1102,11 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg)
ItemPtr ProtocolGame::internalGetItem(InputMessage& msg, uint16 id) ItemPtr ProtocolGame::internalGetItem(InputMessage& msg, uint16 id)
{ {
ItemPtr item = ItemPtr(new Item());
if(id == 0xFFFF) if(id == 0xFFFF)
id = msg.getU16(); id = msg.getU16();
item->setId(id);
ThingType *itemType = item->getType(); ItemPtr item = Item::create(id);
if(itemType->properties[ThingType::IsStackable] || itemType->properties[ThingType::IsFluidContainer] || itemType->properties[ThingType::IsFluid]) if(item->isStackable() || item->isFluidContainer() || item->isFluid())
item->setData(msg.getU8()); item->setData(msg.getU8());
return item; return item;