diff --git a/src/client/const.h b/src/client/const.h index d637148a..e1b9e421 100644 --- a/src/client/const.h +++ b/src/client/const.h @@ -363,6 +363,7 @@ namespace Otc GameNewFluids = 47, GamePlayerStateU16 = 48, GameNewOutfitProtocol = 49, + GamePVPMode = 50, // 51-100 reserved to be defined in lua LastGameFeature = 101 diff --git a/src/client/game.cpp b/src/client/game.cpp index 34ce22b1..3e1bde4a 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -239,6 +239,17 @@ void Game::processPlayerHelpers(int helpers) g_lua.callGlobalField("g_game", "onPlayerHelpersUpdate", helpers); } +void Game::processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode) +{ + m_fightMode = fightMode; + m_chaseMode = chaseMode; + m_safeFight = safeMode; + + g_lua.callGlobalField("g_game", "onFightModeChange", fightMode); + g_lua.callGlobalField("g_game", "onChaseModeChange", chaseMode); + g_lua.callGlobalField("g_game", "onSafeFightChange", safeMode); +} + void Game::processPing() { g_lua.callGlobalField("g_game", "onPing"); @@ -1507,6 +1518,10 @@ void Game::setProtocolVersion(int version) enableFeature(Otc::GameThingMarks); } + if(version >= 1000) { + enableFeature(Otc::GamePVPMode); + } + m_protocolVersion = version; Proto::buildMessageModesMap(version); diff --git a/src/client/game.h b/src/client/game.h index d6dc2d04..a142374b 100644 --- a/src/client/game.h +++ b/src/client/game.h @@ -74,6 +74,7 @@ protected: void processWalkCancel(Otc::Direction direction); void processPlayerHelpers(int helpers); + void processPlayerModes(Otc::FightModes fightMode, Otc::ChaseModes chaseMode, bool safeMode); // message related void processTextMessage(Otc::MessageMode mode, const std::string& text); diff --git a/src/client/protocolcodes.h b/src/client/protocolcodes.h index 524ed97d..515e0a89 100644 --- a/src/client/protocolcodes.h +++ b/src/client/protocolcodes.h @@ -110,6 +110,7 @@ namespace Proto { GameServerPlayerSkills = 161, GameServerPlayerState = 162, GameServerClearTarget = 163, + GameServerPlayerModes = 167, GameServerSpellDelay = 164, // 870 GameServerSpellGroupDelay = 165, // 870 GameServerMultiUseDelay = 166, // 870 diff --git a/src/client/protocolgame.h b/src/client/protocolgame.h index e42eb4f8..634c1633 100644 --- a/src/client/protocolgame.h +++ b/src/client/protocolgame.h @@ -179,6 +179,7 @@ private: void parsePlayerSkills(const InputMessagePtr& msg); void parsePlayerState(const InputMessagePtr& msg); void parsePlayerCancelAttack(const InputMessagePtr& msg); + void parsePlayerModes(const InputMessagePtr& msg); void parseSpellCooldown(const InputMessagePtr& msg); void parseSpellGroupCooldown(const InputMessagePtr& msg); void parseMultiUseCooldown(const InputMessagePtr& msg); diff --git a/src/client/protocolgameparse.cpp b/src/client/protocolgameparse.cpp index d5b13b5c..626000ef 100644 --- a/src/client/protocolgameparse.cpp +++ b/src/client/protocolgameparse.cpp @@ -219,6 +219,9 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg) case Proto::GameServerClearTarget: parsePlayerCancelAttack(msg); break; + case Proto::GameServerPlayerModes: + parsePlayerModes(msg); + break; case Proto::GameServerTalk: parseTalk(msg); break; @@ -326,6 +329,7 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg) case Proto::GameServerPlayerHelpers: parsePlayerHelpers(msg); break; + break; // otclient ONLY case Proto::GameServerExtendedOpcode: parseExtendedOpcode(msg); @@ -333,6 +337,10 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg) case Proto::GameServerChangeMapAwareRange: parseChangeMapAwareRange(msg); break; + // unknown + case 147: // proto >= 1000 ? + for(int i=0;i<19;++i) + msg->getU8(); default: stdext::throw_exception(stdext::format("unhandled opcode %d", (int)opcode)); break; @@ -1144,6 +1152,20 @@ void ProtocolGame::parsePlayerCancelAttack(const InputMessagePtr& msg) g_game.processAttackCancel(seq); } + +void ProtocolGame::parsePlayerModes(const InputMessagePtr& msg) +{ + int fightMode = msg->getU8(); + int chaseMode = msg->getU8(); + bool safeMode = msg->getU8(); + + //TODO: implement pvp modes + if(g_game.getFeature(Otc::GamePVPMode)) + msg->getU8(); // pvp mode + + g_game.processPlayerModes((Otc::FightModes)fightMode, (Otc::ChaseModes)chaseMode, safeMode); +} + void ProtocolGame::parseSpellCooldown(const InputMessagePtr& msg) { int spellId = msg->getU8(); diff --git a/src/client/protocolgamesend.cpp b/src/client/protocolgamesend.cpp index 6a2da0d5..35d7075a 100644 --- a/src/client/protocolgamesend.cpp +++ b/src/client/protocolgamesend.cpp @@ -580,6 +580,11 @@ void ProtocolGame::sendChangeFightModes(Otc::FightModes fightMode, Otc::ChaseMod msg->addU8(fightMode); msg->addU8(chaseMode); msg->addU8(safeFight ? 0x01: 0x00); + + //TODO: implement pvp modes + if(g_game.getFeature(Otc::GamePVPMode)) + msg->addU8(0); // pvp mode + send(msg); }