diff --git a/modules/game_console/console.lua b/modules/game_console/console.lua index 3f7ab859..3b9db163 100644 --- a/modules/game_console/console.lua +++ b/modules/game_console/console.lua @@ -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 diff --git a/src/framework/ui/uilayout.cpp b/src/framework/ui/uilayout.cpp index 8d1460de..8b80f73a 100644 --- a/src/framework/ui/uilayout.cpp +++ b/src/framework/ui/uilayout.cpp @@ -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; diff --git a/src/otclient/core/creature.h b/src/otclient/core/creature.h index 9b219d88..ff0ebcfa 100644 --- a/src/otclient/core/creature.h +++ b/src/otclient/core/creature.h @@ -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(shared_from_this()); } +}; + +class Monster : public Creature { +public: + MonsterPtr asMonster() { return std::static_pointer_cast(shared_from_this()); } +}; + #endif diff --git a/src/otclient/core/declarations.h b/src/otclient/core/declarations.h index 3f786661..b2375c70 100644 --- a/src/otclient/core/declarations.h +++ b/src/otclient/core/declarations.h @@ -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 TilePtr; typedef std::shared_ptr ThingPtr; typedef std::shared_ptr ItemPtr; typedef std::shared_ptr CreaturePtr; -typedef std::shared_ptr EffectPtr; -typedef std::shared_ptr MissilePtr; +typedef std::shared_ptr MonsterPtr; +typedef std::shared_ptr NpcPtr; typedef std::shared_ptr PlayerPtr; typedef std::shared_ptr LocalPlayerPtr; +typedef std::shared_ptr EffectPtr; +typedef std::shared_ptr MissilePtr; typedef std::shared_ptr AnimatedTextPtr; typedef std::shared_ptr StaticTextPtr; diff --git a/src/otclient/core/game.cpp b/src/otclient/core/game.cpp index e3ad73a4..b22ec1e8 100644 --- a/src/otclient/core/game.cpp +++ b/src/otclient/core/game.cpp @@ -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); +} diff --git a/src/otclient/core/game.h b/src/otclient/core/game.h index 9d50cb4e..431cf218 100644 --- a/src/otclient/core/game.h +++ b/src/otclient/core/game.h @@ -27,6 +27,7 @@ #include #include #include +#include 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; diff --git a/src/otclient/core/item.cpp b/src/otclient/core/item.cpp index 108647da..3c929717 100644 --- a/src/otclient/core/item.cpp +++ b/src/otclient/core/item.cpp @@ -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) diff --git a/src/otclient/core/item.h b/src/otclient/core/item.h index 201e8bf7..277a2443 100644 --- a/src/otclient/core/item.h +++ b/src/otclient/core/item.h @@ -31,6 +31,8 @@ class Item : public Thing public: Item(); + static ItemPtr create(int id = 0); + enum { TICKS_PER_FRAME = 500 }; diff --git a/src/otclient/core/localplayer.cpp b/src/otclient/core/localplayer.cpp index 68b92b9b..4c7723f2 100644 --- a/src/otclient/core/localplayer.cpp +++ b/src/otclient/core/localplayer.cpp @@ -34,11 +34,10 @@ LocalPlayer::LocalPlayer() void LocalPlayer::clientWalk(Otc::Direction direction) { // We're not walking, so start a client walk. - if(!m_walking) { - Position newPos = m_position + Position::getPosFromDirection(direction); - Creature::walk(newPos, false); - m_clientWalking = true; - } + 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) diff --git a/src/otclient/core/thing.cpp b/src/otclient/core/thing.cpp index 7f7328db..a5908c6f 100644 --- a/src/otclient/core/thing.cpp +++ b/src/otclient/core/thing.cpp @@ -25,8 +25,9 @@ #include "thingstype.h" #include -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]; -} diff --git a/src/otclient/core/thing.h b/src/otclient/core/thing.h index fcf493d8..0a86c0f1 100644 --- a/src/otclient/core/thing.h +++ b/src/otclient/core/thing.h @@ -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(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); diff --git a/src/otclient/luafunctions.cpp b/src/otclient/luafunctions.cpp index abd13dc0..c59db202 100644 --- a/src/otclient/luafunctions.cpp +++ b/src/otclient/luafunctions.cpp @@ -128,19 +128,19 @@ void OTClient::registerLuaFunctions() g_lua.bindClassMemberFunction("setShieldTexture", &Creature::setShieldTexture); g_lua.bindClassMemberFunction("setEmblemTexture", &Creature::setEmblemTexture); - g_lua.registerClass(); - + g_lua.registerClass(); g_lua.registerClass(); g_lua.registerClass(); g_lua.registerClass(); g_lua.registerClass(); + g_lua.registerClass(); + g_lua.registerClass(); + g_lua.registerClass(); g_lua.registerClass(); g_lua.bindClassMemberFunction("getAttackingCreature", &LocalPlayer::getAttackingCreature); g_lua.bindClassMemberFunction("getFollowingCreature", &LocalPlayer::getFollowingCreature); - g_lua.registerClass(); - g_lua.registerClass(); g_lua.bindClassMemberFunction("clean", &Tile::clean); g_lua.bindClassMemberFunction("addThing", &Tile::addThing); diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index 5debd8a3..740cb11d 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -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)); - }); + 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)); - }); + 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)); - }); + 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)); - }); + 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)); - }); + 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)); - }); + 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)); - }); + 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)); - }); + 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]); - }); + 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); - }); + 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); - }); + 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); - }); + 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); - }); + 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); - }); + 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); - }); + 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); - }); + 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,29 +1078,23 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg) bool passable = (msg.getU8() == 0); - creature->setHealthPercent(healthPercent); - creature->setDirection(direction); - creature->setOutfit(outfit); - creature->setLight(light); - creature->setSpeed(speed); - creature->setSkull(skull); - creature->setShield(shield); - creature->setEmblem(emblem); - creature->setPassable(passable); - creature->cancelWalk(direction); + if(creature) { + creature->setHealthPercent(healthPercent); + creature->setDirection(direction); + creature->setOutfit(outfit); + creature->setLight(light); + creature->setSpeed(speed); + creature->setSkull(skull); + creature->setShield(shield); + 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;