mirror of
https://github.com/edubart/otclient.git
synced 2025-10-19 14:03:26 +02:00
Started 1050 implementation and fix ups:
* Dat now loads (new animations aren't yet functional). * Fixed the way we reference client versions. TODO: Write new animation functionality & find out protocol changes.
This commit is contained in:
@@ -389,6 +389,7 @@ namespace Otc
|
||||
GameSpritesAlphaChannel = 56,
|
||||
GamePremiumExpiration = 57,
|
||||
GameBrowseField = 58,
|
||||
GameEnhancedAnimations = 59,
|
||||
|
||||
LastGameFeature = 101
|
||||
};
|
||||
|
@@ -846,11 +846,11 @@ int Creature::getStepDuration(bool ignoreDiagonal, Otc::Direction dir)
|
||||
else
|
||||
interval /= speed;
|
||||
|
||||
if(g_game.getProtocolVersion() >= 900)
|
||||
if(g_game.getClientVersion() >= 900)
|
||||
interval = (interval / g_game.getServerBeat()) * g_game.getServerBeat();
|
||||
|
||||
float factor = 3;
|
||||
if(g_game.getProtocolVersion() <= 810)
|
||||
if(g_game.getClientVersion() <= 810)
|
||||
factor = 2;
|
||||
|
||||
interval = std::max<int>(interval, g_game.getServerBeat());
|
||||
|
@@ -1475,9 +1475,27 @@ void Game::setProtocolVersion(int version)
|
||||
if(isOnline())
|
||||
stdext::throw_exception("Unable to change protocol version while online");
|
||||
|
||||
if(version != 0 && (version < 740 || version > 1041))
|
||||
if(version != 0 && (version < 740 || version > 1051))
|
||||
stdext::throw_exception(stdext::format("Protocol version %d not supported", version));
|
||||
|
||||
m_protocolVersion = version;
|
||||
|
||||
Proto::buildMessageModesMap(version);
|
||||
|
||||
g_lua.callGlobalField("g_game", "onProtocolVersionChange", version);
|
||||
}
|
||||
|
||||
void Game::setClientVersion(int version)
|
||||
{
|
||||
if(m_clientVersion == version)
|
||||
return;
|
||||
|
||||
if(isOnline())
|
||||
stdext::throw_exception("Unable to change client version while online");
|
||||
|
||||
if(version != 0 && (version < 740 || version > 1051))
|
||||
stdext::throw_exception(stdext::format("Client version %d not supported", version));
|
||||
|
||||
m_features.reset();
|
||||
enableFeature(Otc::GameFormatCreatureName);
|
||||
|
||||
@@ -1585,28 +1603,14 @@ void Game::setProtocolVersion(int version)
|
||||
enableFeature(Otc::GameCreatureIcons);
|
||||
enableFeature(Otc::GameHideNpcNames);
|
||||
}
|
||||
|
||||
|
||||
if(version >= 1038) {
|
||||
enableFeature(Otc::GamePremiumExpiration);
|
||||
}
|
||||
|
||||
m_protocolVersion = version;
|
||||
|
||||
Proto::buildMessageModesMap(version);
|
||||
|
||||
g_lua.callGlobalField("g_game", "onProtocolVersionChange", version);
|
||||
}
|
||||
|
||||
void Game::setClientVersion(int version)
|
||||
{
|
||||
if(m_clientVersion == version)
|
||||
return;
|
||||
|
||||
if(isOnline())
|
||||
stdext::throw_exception("Unable to change client version while online");
|
||||
|
||||
if(version != 0 && (version < 740 || version > 1041))
|
||||
stdext::throw_exception(stdext::format("Client version %d not supported", version));
|
||||
if(version >= 1050) {
|
||||
enableFeature(Otc::GameEnhancedAnimations);
|
||||
}
|
||||
|
||||
m_clientVersion = version;
|
||||
|
||||
|
@@ -241,7 +241,7 @@ int Item::getSubType()
|
||||
{
|
||||
if(isSplash() || isFluidContainer())
|
||||
return m_countOrSubType;
|
||||
if(g_game.getProtocolVersion() > 862)
|
||||
if(g_game.getClientVersion() > 862)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@@ -51,7 +51,7 @@ void ItemType::unserialize(const BinaryTreePtr& node)
|
||||
switch(attr) {
|
||||
case ItemTypeAttrServerId: {
|
||||
uint16 serverId = node->getU16();
|
||||
if(g_game.getProtocolVersion() < 960) {
|
||||
if(g_game.getClientVersion() < 960) {
|
||||
if(serverId > 20000 && serverId < 20100) {
|
||||
serverId -= 20000;
|
||||
} else if(lastId > 99 && lastId != serverId - 1) {
|
||||
|
@@ -491,7 +491,7 @@ void Map::saveOtcm(const std::string& fileName)
|
||||
// version 1 header
|
||||
fin->addString("OTCM 1.0"); // map description
|
||||
fin->addU32(g_things.getDatSignature());
|
||||
fin->addU16(g_game.getProtocolVersion());
|
||||
fin->addU16(g_game.getClientVersion());
|
||||
fin->addString(g_game.getWorldName());
|
||||
|
||||
// go back and rewrite where the map data starts
|
||||
|
@@ -56,7 +56,7 @@ void ProtocolGame::onRecv(const InputMessagePtr& inputMessage)
|
||||
if(m_firstRecv) {
|
||||
m_firstRecv = false;
|
||||
|
||||
if(g_game.getProtocolVersion() >= 841) { // not sure since which version this is, but it seems to be after 8.40
|
||||
if(g_game.getClientVersion() >= 841) { // not sure since which version this is, but it seems to be after 8.40
|
||||
int size = inputMessage->getU16();
|
||||
if(size != inputMessage->getUnreadSize()) {
|
||||
g_logger.traceError("invalid message size");
|
||||
|
@@ -410,9 +410,9 @@ void ProtocolGame::parseGMActions(const InputMessagePtr& msg)
|
||||
|
||||
int numViolationReasons;
|
||||
|
||||
if(g_game.getProtocolVersion() >= 850)
|
||||
if(g_game.getClientVersion() >= 850)
|
||||
numViolationReasons = 20;
|
||||
else if(g_game.getProtocolVersion() >= 840)
|
||||
else if(g_game.getClientVersion() >= 840)
|
||||
numViolationReasons = 23;
|
||||
else
|
||||
numViolationReasons = 32;
|
||||
@@ -562,7 +562,7 @@ void ProtocolGame::parseTileAddThing(const InputMessagePtr& msg)
|
||||
Position pos = getPosition(msg);
|
||||
int stackPos = -1;
|
||||
|
||||
if(g_game.getProtocolVersion() >= 841)
|
||||
if(g_game.getClientVersion() >= 841)
|
||||
stackPos = msg->getU8();
|
||||
|
||||
ThingPtr thing = getThing(msg);
|
||||
@@ -722,7 +722,7 @@ void ProtocolGame::parseOpenNpcTrade(const InputMessagePtr& msg)
|
||||
|
||||
int listCount;
|
||||
|
||||
if(g_game.getProtocolVersion() >= 900)
|
||||
if(g_game.getClientVersion() >= 900)
|
||||
listCount = msg->getU16();
|
||||
else
|
||||
listCount = msg->getU8();
|
||||
@@ -749,7 +749,7 @@ void ProtocolGame::parsePlayerGoods(const InputMessagePtr& msg)
|
||||
std::vector<std::tuple<ItemPtr, int>> goods;
|
||||
|
||||
int money;
|
||||
if(g_game.getProtocolVersion() >= 973)
|
||||
if(g_game.getClientVersion() >= 973)
|
||||
money = msg->getU64();
|
||||
else
|
||||
money = msg->getU32();
|
||||
@@ -992,7 +992,7 @@ void ProtocolGame::parseEditText(const InputMessagePtr& msg)
|
||||
uint id = msg->getU32();
|
||||
|
||||
int itemId;
|
||||
if(g_game.getProtocolVersion() >= 1010) {
|
||||
if(g_game.getClientVersion() >= 1010) {
|
||||
// TODO: processEditText with ItemPtr as parameter
|
||||
ItemPtr item = getItem(msg);
|
||||
itemId = item->getId();
|
||||
@@ -1640,7 +1640,7 @@ void ProtocolGame::parseModalDialog(const InputMessagePtr& msg)
|
||||
}
|
||||
|
||||
int enterButton, escapeButton;
|
||||
if(g_game.getProtocolVersion() > 970) {
|
||||
if(g_game.getClientVersion() > 970) {
|
||||
escapeButton = msg->getU8();
|
||||
enterButton = msg->getU8();
|
||||
}
|
||||
@@ -1685,7 +1685,7 @@ void ProtocolGame::parseChangeMapAwareRange(const InputMessagePtr& msg)
|
||||
void ProtocolGame::parseCreaturesMark(const InputMessagePtr& msg)
|
||||
{
|
||||
int len;
|
||||
if (g_game.getProtocolVersion() >= 1035) {
|
||||
if (g_game.getClientVersion() >= 1035) {
|
||||
len = 1;
|
||||
} else {
|
||||
len = msg->getU8();
|
||||
@@ -1895,7 +1895,7 @@ CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type)
|
||||
uint id = msg->getU32();
|
||||
|
||||
int creatureType;
|
||||
if(g_game.getProtocolVersion() >= 910)
|
||||
if(g_game.getClientVersion() >= 910)
|
||||
creatureType = msg->getU8();
|
||||
else {
|
||||
if(id >= Proto::PlayerStartId && id < Proto::PlayerEndId)
|
||||
@@ -1973,7 +1973,7 @@ CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type)
|
||||
}
|
||||
}
|
||||
|
||||
if(g_game.getProtocolVersion() >= 854)
|
||||
if(g_game.getClientVersion() >= 854)
|
||||
unpass = msg->getU8();
|
||||
|
||||
if(creature) {
|
||||
@@ -2004,7 +2004,7 @@ CreaturePtr ProtocolGame::getCreature(const InputMessagePtr& msg, int type)
|
||||
if(creature)
|
||||
creature->turn(direction);
|
||||
|
||||
if(g_game.getProtocolVersion() >= 953) {
|
||||
if(g_game.getClientVersion() >= 953) {
|
||||
bool unpass = msg->getU8();
|
||||
|
||||
if(creature)
|
||||
|
@@ -65,7 +65,7 @@ void ProtocolGame::sendLoginPacket(uint challengeTimestamp, uint8 challengeRando
|
||||
|
||||
msg->addU8(0); // first RSA byte must be 0
|
||||
|
||||
if(g_game.getProtocolVersion() >= 770)
|
||||
if(g_game.getClientVersion() >= 770)
|
||||
{
|
||||
// xtea key
|
||||
generateXteaKey();
|
||||
@@ -99,7 +99,7 @@ void ProtocolGame::sendLoginPacket(uint challengeTimestamp, uint8 challengeRando
|
||||
msg->addPaddingBytes(paddingBytes);
|
||||
|
||||
// encrypt with RSA
|
||||
if(g_game.getProtocolVersion() >= 770)
|
||||
if(g_game.getClientVersion() >= 770)
|
||||
msg->encryptRsa();
|
||||
|
||||
if(g_game.getFeature(Otc::GameProtocolChecksum))
|
||||
@@ -107,7 +107,7 @@ void ProtocolGame::sendLoginPacket(uint challengeTimestamp, uint8 challengeRando
|
||||
|
||||
send(msg);
|
||||
|
||||
if(g_game.getProtocolVersion() >= 770)
|
||||
if(g_game.getClientVersion() >= 770)
|
||||
enableXteaEncryption();
|
||||
}
|
||||
|
||||
@@ -642,7 +642,7 @@ void ProtocolGame::sendShareExperience(bool active)
|
||||
msg->addU8(Proto::ClientShareExperience);
|
||||
msg->addU8(active ? 0x01 : 0x00);
|
||||
|
||||
if(g_game.getProtocolVersion() < 910)
|
||||
if(g_game.getClientVersion() < 910)
|
||||
msg->addU8(0);
|
||||
|
||||
send(msg);
|
||||
|
@@ -53,12 +53,12 @@ void ThingType::serialize(const FileStreamPtr& fin)
|
||||
continue;
|
||||
|
||||
int attr = i;
|
||||
if(g_game.getProtocolVersion() >= 780) {
|
||||
if(g_game.getClientVersion() >= 780) {
|
||||
if(attr == ThingAttrChargeable)
|
||||
attr = ThingAttrWritable;
|
||||
else if(attr >= ThingAttrWritable)
|
||||
attr += 1;
|
||||
} else if(g_game.getProtocolVersion() >= 1010) {
|
||||
} else if(g_game.getClientVersion() >= 1010) {
|
||||
if(attr == ThingAttrNoMoveAnimation)
|
||||
attr = 16;
|
||||
else if(attr >= ThingAttrPickupable)
|
||||
@@ -116,6 +116,19 @@ void ThingType::serialize(const FileStreamPtr& fin)
|
||||
fin->addU8(m_numPatternZ);
|
||||
fin->addU8(m_animationPhases);
|
||||
|
||||
if(g_game.getFeature(Otc::GameEnhancedAnimations)) {
|
||||
if(m_animationPhases > 1) {
|
||||
fin->addU8(m_animation.async ? 0 : 1);
|
||||
fin->add32(m_animation.loopCount);
|
||||
fin->addU8(m_animation.startIndex);
|
||||
|
||||
for(std::tuple<int, int> frame : m_animation.frames) {
|
||||
fin->addU32(std::get<0>(frame));
|
||||
fin->addU32(std::get<1>(frame));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(uint i = 0; i < m_spritesIndex.size(); i++) {
|
||||
if(g_game.getFeature(Otc::GameSpritesU32))
|
||||
fin->addU32(m_spritesIndex[i]);
|
||||
@@ -130,15 +143,17 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS
|
||||
m_id = clientId;
|
||||
m_category = category;
|
||||
|
||||
int count = 0, attr = -1;
|
||||
bool done = false;
|
||||
for(int i = 0 ; i < ThingLastAttr;++i) {
|
||||
int attr = fin->getU8();
|
||||
count++;
|
||||
attr = fin->getU8();
|
||||
if(attr == ThingLastAttr) {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(g_game.getProtocolVersion() >= 1010) {
|
||||
if(g_game.getClientVersion() >= 1010) {
|
||||
/* In 10.10+ all attributes from 16 and up were
|
||||
* incremented by 1 to make space for 16 as
|
||||
* "No Movement Animation" flag.
|
||||
@@ -147,12 +162,12 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS
|
||||
attr = ThingAttrNoMoveAnimation;
|
||||
else if(attr > 16)
|
||||
attr -= 1;
|
||||
} else if(g_game.getProtocolVersion() >= 860) {
|
||||
} else if(g_game.getClientVersion() >= 860) {
|
||||
/* Default attribute values follow
|
||||
* the format of 8.6-9.86.
|
||||
* Therefore no changes here.
|
||||
*/
|
||||
} else if(g_game.getProtocolVersion() >= 780) {
|
||||
} else if(g_game.getClientVersion() >= 780) {
|
||||
/* In 7.80-8.54 all attributes from 8 and higher were
|
||||
* incremented by 1 to make space for 8 as
|
||||
* "Item Charges" flag.
|
||||
@@ -162,11 +177,11 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS
|
||||
continue;
|
||||
} else if(attr > 8)
|
||||
attr -= 1;
|
||||
} else if(g_game.getProtocolVersion() >= 755) {
|
||||
} else if(g_game.getClientVersion() >= 755) {
|
||||
/* In 7.55-7.72 attributes 23 is "Floor Change". */
|
||||
if(attr == 23)
|
||||
attr = ThingAttrFloorChange;
|
||||
} else if(g_game.getProtocolVersion() >= 740) {
|
||||
} else if(g_game.getClientVersion() >= 740) {
|
||||
/* In 7.4-7.5 attribute "Ground Border" did not exist
|
||||
* attributes 1-15 have to be adjusted.
|
||||
* Several other changes in the format.
|
||||
@@ -207,7 +222,7 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS
|
||||
|
||||
switch(attr) {
|
||||
case ThingAttrDisplacement: {
|
||||
if(g_game.getProtocolVersion() >= 755) {
|
||||
if(g_game.getClientVersion() >= 755) {
|
||||
m_displacement.x = fin->getU16();
|
||||
m_displacement.y = fin->getU16();
|
||||
} else {
|
||||
@@ -256,7 +271,8 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS
|
||||
}
|
||||
|
||||
if(!done)
|
||||
stdext::throw_exception("corrupt data");
|
||||
stdext::throw_exception(stdext::format("corrupt data (id: %d, category: %d, count: %d, lastAttr: %d)",
|
||||
m_id, m_category, count, attr));
|
||||
|
||||
uint8 width = fin->getU8();
|
||||
uint8 height = fin->getU8();
|
||||
@@ -271,12 +287,27 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS
|
||||
m_layers = fin->getU8();
|
||||
m_numPatternX = fin->getU8();
|
||||
m_numPatternY = fin->getU8();
|
||||
if(g_game.getProtocolVersion() >= 755)
|
||||
if(g_game.getClientVersion() >= 755)
|
||||
m_numPatternZ = fin->getU8();
|
||||
else
|
||||
m_numPatternZ = 1;
|
||||
m_animationPhases = fin->getU8();
|
||||
|
||||
if(g_game.getFeature(Otc::GameEnhancedAnimations)) {
|
||||
if(m_animationPhases > 1) {
|
||||
m_animation.async = fin->getU8() == 0;
|
||||
m_animation.loopCount = fin->get32();
|
||||
m_animation.startIndex = fin->getU8();
|
||||
|
||||
for(int i = 0; i < m_animationPhases; i++) {
|
||||
int minDuration = fin->getU32();
|
||||
int maxDuration = fin->getU32();
|
||||
|
||||
m_animation.frames.push_back(std::make_tuple(minDuration, maxDuration));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int totalSprites = m_size.area() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * m_animationPhases;
|
||||
|
||||
// if(totalSprites == 0)
|
||||
|
@@ -110,6 +110,15 @@ struct Light {
|
||||
uint8 color;
|
||||
};
|
||||
|
||||
struct Animation {
|
||||
Animation() { startIndex = 0; loopCount = 0; async = false; }
|
||||
|
||||
int startIndex;
|
||||
int loopCount;
|
||||
bool async;
|
||||
std::vector<std::tuple<int, int> > frames;
|
||||
};
|
||||
|
||||
class ThingType : public LuaObject
|
||||
{
|
||||
public:
|
||||
@@ -138,6 +147,7 @@ public:
|
||||
int getNumPatternY() { return m_numPatternY; }
|
||||
int getNumPatternZ() { return m_numPatternZ; }
|
||||
int getAnimationPhases() { return m_animationPhases; }
|
||||
Animation getAnimation() { return m_animation; }
|
||||
Point getDisplacement() { return m_displacement; }
|
||||
int getDisplacementX() { return getDisplacement().x; }
|
||||
int getDisplacementY() { return getDisplacement().y; }
|
||||
@@ -204,10 +214,11 @@ private:
|
||||
|
||||
Size m_size;
|
||||
Point m_displacement;
|
||||
Animation m_animation;
|
||||
int m_animationPhases;
|
||||
int m_exactSize;
|
||||
int m_realSize;
|
||||
int m_numPatternX, m_numPatternY, m_numPatternZ;
|
||||
int m_animationPhases;
|
||||
int m_layers;
|
||||
int m_elevation;
|
||||
float m_opacity;
|
||||
|
@@ -276,7 +276,7 @@ void ThingTypeManager::parseItemType(uint16 serverId, TiXmlElement* elem)
|
||||
bool s;
|
||||
int d;
|
||||
|
||||
if(g_game.getProtocolVersion() < 960) {
|
||||
if(g_game.getClientVersion() < 960) {
|
||||
s = serverId > 20000 && serverId < 20100;
|
||||
d = 20000;
|
||||
} else {
|
||||
|
@@ -217,7 +217,7 @@ void Tile::addThing(const ThingPtr& thing, int stackPos)
|
||||
append = (priority <= 3);
|
||||
|
||||
// newer protocols does not store creatures in reverse order
|
||||
if(g_game.getProtocolVersion() >= 854 && priority == 4)
|
||||
if(g_game.getClientVersion() >= 854 && priority == 4)
|
||||
append = !append;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user