diff --git a/modules/gamelib/game.lua b/modules/gamelib/game.lua index fe1945b4..1d90fbf7 100644 --- a/modules/gamelib/game.lua +++ b/modules/gamelib/game.lua @@ -37,7 +37,8 @@ function g_game.getSupportedProtocols() 810, 811, 840, 842, 850, 853, 854, 860, 861, 862, 870, 910, 940, 944, 953, 954, 960, 961, 963, 970, 971, - 973, 974 + 973, 974, 975, 976, 977, 978, 979, + 980, 1010 } end @@ -45,7 +46,13 @@ function g_game.getSupportedClients(protocol) clients = { [971] = {980}, [973] = {981}, - [974] = {982} + [974] = {982}, + [975] = {983}, + [976] = {984}, + [977] = {985}, + [978] = {986}, + [979] = {1001}, + [980] = {1002} } return clients[protocol] or {protocol} end diff --git a/src/client/const.h b/src/client/const.h index 7a649608..7e243085 100644 --- a/src/client/const.h +++ b/src/client/const.h @@ -353,6 +353,8 @@ namespace Otc GameForceFirstAutoWalkStep = 37, GameMinimapRemove = 38, GameDoubleShopSellAmount = 39, + GameContainerPagination = 40, + GameThingMarks = 41, // 51-100 reserved to be defined in lua LastGameFeature = 101 }; diff --git a/src/client/game.cpp b/src/client/game.cpp index 3b4dfcab..53b7779e 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -1150,7 +1150,7 @@ void Game::removeVip(int playerId) { if(!canPerformGameAction()) return; - + auto it = m_vips.find(playerId); if(it == m_vips.end()) return; @@ -1400,7 +1400,7 @@ void Game::setProtocolVersion(int version) if(isOnline()) stdext::throw_exception("Unable to change protocol version while online"); - if(version != 0 && (version < 810 || version > 974)) + if(version != 0 && (version < 810 || version > 1010)) stdext::throw_exception(stdext::format("Protocol version %d not supported", version)); m_features.reset(); @@ -1464,6 +1464,14 @@ void Game::setProtocolVersion(int version) enableFeature(Otc::GameNewSpeedLaw); } + if(version >= 976) { + enableFeature(Otc::GameContainerPagination); + } + + if(version >= 979) { + enableFeature(Otc::GameThingMarks); + } + m_protocolVersion = version; Proto::buildMessageModesMap(version); @@ -1479,7 +1487,7 @@ void Game::setClientVersion(int version) if(isOnline()) stdext::throw_exception("Unable to change client version while online"); - if(version != 0 && (version < 810 || version > 982)) + if(version != 0 && (version < 810 || version > 1010)) stdext::throw_exception(stdext::format("Client version %d not supported", version)); m_clientVersion = version; diff --git a/src/client/protocolgameparse.cpp b/src/client/protocolgameparse.cpp index f2b4ca5a..263a8f3c 100644 --- a/src/client/protocolgameparse.cpp +++ b/src/client/protocolgameparse.cpp @@ -603,6 +603,14 @@ void ProtocolGame::parseOpenContainer(const InputMessagePtr& msg) std::string name = msg->getString(); int capacity = msg->getU8(); bool hasParent = (msg->getU8() != 0); + + if(g_game.getFeature(Otc::GameContainerPagination)) { + msg->getU8(); // drag and drop + msg->getU8(); // pagination + msg->getU16(); // container size + msg->getU16(); // first index + } + int itemCount = msg->getU8(); std::vector items(itemCount); @@ -622,13 +630,21 @@ void ProtocolGame::parseContainerAddItem(const InputMessagePtr& msg) { int containerId = msg->getU8(); ItemPtr item = getItem(msg); + if(g_game.getFeature(Otc::GameContainerPagination)) { + msg->getU16(); // slot + } g_game.processContainerAddItem(containerId, item); } void ProtocolGame::parseContainerUpdateItem(const InputMessagePtr& msg) { int containerId = msg->getU8(); - int slot = msg->getU8(); + int slot; + if(g_game.getFeature(Otc::GameContainerPagination)) { + slot = msg->getU16(); + } else { + slot = msg->getU8(); + } ItemPtr item = getItem(msg); g_game.processContainerUpdateItem(containerId, slot, item); } @@ -636,7 +652,13 @@ void ProtocolGame::parseContainerUpdateItem(const InputMessagePtr& msg) void ProtocolGame::parseContainerRemoveItem(const InputMessagePtr& msg) { int containerId = msg->getU8(); - int slot = msg->getU8(); + int slot; + if(g_game.getFeature(Otc::GameContainerPagination)) { + slot = msg->getU16(); + getItem(msg); + } else { + slot = msg->getU8(); + } g_game.processContainerRemoveItem(containerId, slot); } @@ -1808,6 +1830,12 @@ CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type) if(g_game.getFeature(Otc::GameCreatureEmblems) && !known) emblem = msg->getU8(); + if(g_game.getFeature(Otc::GameThingMarks)) { + msg->getU8(); // creature type for summons + msg->getU8(); // mark + msg->getU16(); // helpers + } + if(g_game.getProtocolVersion() >= 854) unpass = msg->getU8(); @@ -1860,6 +1888,10 @@ ItemPtr ProtocolGame::getItem(const InputMessagePtr& msg, int id) if(item->getId() == 0) stdext::throw_exception(stdext::format("unable to create item with invalid id %d", id)); + if(g_game.getFeature(Otc::GameThingMarks)) { + msg->getU8(); // mark + } + if(item->isStackable() || item->isFluidContainer() || item->isSplash() || item->isChargeable()) item->setCountOrSubType(msg->getU8()); diff --git a/src/client/thingtype.cpp b/src/client/thingtype.cpp index 94f5d523..8bc46062 100644 --- a/src/client/thingtype.cpp +++ b/src/client/thingtype.cpp @@ -67,6 +67,17 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS attr -= 1; } + if(g_game.getProtocolVersion() >= 1010) { + /* In 10.10 all attributes from 16 and up were + * incremented by 1 to make space for 16 as + * "No Movement Animation" flag. + */ + if(attr == 16) + attr = ThingAttrNoMoveAnimation; + else if(attr > 16) + attr -= 1; + } + switch(attr) { case ThingAttrDisplacement: { m_displacement.x = fin->getU16(); @@ -126,8 +137,8 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS int totalSprites = m_size.area() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * m_animationPhases; - if(totalSprites == 0) - stdext::throw_exception("a thing type has no sprites"); + // if(totalSprites == 0) + // stdext::throw_exception("a thing type has no sprites"); if(totalSprites > 4096) stdext::throw_exception("a thing type has more than 4096 sprites"); diff --git a/src/client/thingtype.h b/src/client/thingtype.h index 61432c76..f3c28a60 100644 --- a/src/client/thingtype.h +++ b/src/client/thingtype.h @@ -81,6 +81,7 @@ enum ThingAttr : uint8 { ThingAttrOpacity = 100, ThingAttrNotPreWalkable = 101, + ThingAttrNoMoveAnimation = 253, // real value is 16, but we need to do this for backwards compatibility ThingAttrChargeable = 254, // deprecated ThingLastAttr = 255 };