mirror of
https://github.com/edubart/otclient.git
synced 2025-10-16 12:34:55 +02:00
Support for Protocols up to 10.71, Adventurer Blessing
This commit is contained in:
@@ -328,7 +328,8 @@ namespace Otc
|
||||
MessageRVRChannel = 46,
|
||||
MessageRVRAnswer = 47,
|
||||
MessageRVRContinue = 48,
|
||||
LastMessage = 49,
|
||||
MessageGameHighlight = 49,
|
||||
LastMessage = 50,
|
||||
MessageInvalid = 255
|
||||
};
|
||||
|
||||
@@ -390,6 +391,13 @@ namespace Otc
|
||||
GamePremiumExpiration = 57,
|
||||
GameBrowseField = 58,
|
||||
GameEnhancedAnimations = 59,
|
||||
GameOGLInformation = 60,
|
||||
GameMessageSizeCheck = 61,
|
||||
GamePreviewState = 62,
|
||||
GameLoginPacketEncryption = 63,
|
||||
GameClientVersion = 64,
|
||||
GameContentRevision = 65,
|
||||
GameExperienceBonus = 66,
|
||||
|
||||
LastGameFeature = 101
|
||||
};
|
||||
@@ -450,6 +458,16 @@ namespace Otc
|
||||
PhaseRandom = 254,
|
||||
PhaseAsync = 255
|
||||
};
|
||||
|
||||
enum Blessings {
|
||||
BlessingNone = 0,
|
||||
BlessingAdventurer = 1,
|
||||
BlessingSpiritualShielding = 1 << 1,
|
||||
BlessingEmbraceOfTibia = 1 << 2,
|
||||
BlessingFireOfSuns = 1 << 3,
|
||||
BlessingWisdomOfSolitude = 1 << 4,
|
||||
BlessingSparkOfPhoenix = 1 << 5
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1425,7 +1425,7 @@ void Game::setProtocolVersion(int version)
|
||||
if(isOnline())
|
||||
stdext::throw_exception("Unable to change protocol version while online");
|
||||
|
||||
if(version != 0 && (version < 740 || version > 1051))
|
||||
if(version != 0 && (version < 740 || version > 1071))
|
||||
stdext::throw_exception(stdext::format("Protocol version %d not supported", version));
|
||||
|
||||
m_protocolVersion = version;
|
||||
@@ -1443,7 +1443,7 @@ void Game::setClientVersion(int version)
|
||||
if(isOnline())
|
||||
stdext::throw_exception("Unable to change client version while online");
|
||||
|
||||
if(version != 0 && (version < 740 || version > 1051))
|
||||
if(version != 0 && (version < 740 || version > 1071))
|
||||
stdext::throw_exception(stdext::format("Client version %d not supported", version));
|
||||
|
||||
m_features.reset();
|
||||
@@ -1452,6 +1452,7 @@ void Game::setClientVersion(int version)
|
||||
if(version >= 770) {
|
||||
enableFeature(Otc::GameLooktypeU16);
|
||||
enableFeature(Otc::GameMessageStatements);
|
||||
enableFeature(Otc::GameLoginPacketEncryption);
|
||||
}
|
||||
|
||||
if(version >= 780) {
|
||||
@@ -1475,6 +1476,7 @@ void Game::setClientVersion(int version)
|
||||
|
||||
if(version >= 841) {
|
||||
enableFeature(Otc::GameChallengeOnLogin);
|
||||
enableFeature(Otc::GameMessageSizeCheck);
|
||||
}
|
||||
|
||||
if(version >= 854) {
|
||||
@@ -1523,6 +1525,11 @@ void Game::setClientVersion(int version)
|
||||
enableFeature(Otc::GameAdditionalVipInfo);
|
||||
}
|
||||
|
||||
if(version >= 980) {
|
||||
enableFeature(Otc::GamePreviewState);
|
||||
enableFeature(Otc::GameClientVersion);
|
||||
}
|
||||
|
||||
if(version >= 981) {
|
||||
enableFeature(Otc::GameLoginPending);
|
||||
enableFeature(Otc::GameNewSpeedLaw);
|
||||
@@ -1538,7 +1545,7 @@ void Game::setClientVersion(int version)
|
||||
enableFeature(Otc::GamePVPMode);
|
||||
}
|
||||
|
||||
if (version >= 1035) {
|
||||
if(version >= 1035) {
|
||||
enableFeature(Otc::GameDoubleSkills);
|
||||
enableFeature(Otc::GameBaseSkillU16);
|
||||
}
|
||||
@@ -1556,6 +1563,18 @@ void Game::setClientVersion(int version)
|
||||
enableFeature(Otc::GameEnhancedAnimations);
|
||||
}
|
||||
|
||||
if(version >= 1054) {
|
||||
enableFeature(Otc::GameExperienceBonus);
|
||||
}
|
||||
|
||||
if(version >= 1061) {
|
||||
enableFeature(Otc::GameOGLInformation);
|
||||
}
|
||||
|
||||
if(version >= 1071) {
|
||||
enableFeature(Otc::GameContentRevision);
|
||||
}
|
||||
|
||||
m_clientVersion = version;
|
||||
|
||||
g_lua.callGlobalField("g_game", "onClientVersionChange", version);
|
||||
|
@@ -31,6 +31,7 @@ LocalPlayer::LocalPlayer()
|
||||
{
|
||||
m_states = 0;
|
||||
m_vocation = 0;
|
||||
m_blessings = Otc::BlessingNone;
|
||||
m_walkLockExpiration = 0;
|
||||
|
||||
m_skillsLevel.fill(-1);
|
||||
@@ -546,6 +547,16 @@ void LocalPlayer::setSpells(const std::vector<int>& spells)
|
||||
}
|
||||
}
|
||||
|
||||
void LocalPlayer::setBlessings(int blessings)
|
||||
{
|
||||
if(blessings != m_blessings) {
|
||||
int oldBlessings = m_blessings;
|
||||
m_blessings = blessings;
|
||||
|
||||
callLuaField("onBlessingsChange", blessings, oldBlessings);
|
||||
}
|
||||
}
|
||||
|
||||
bool LocalPlayer::hasSight(const Position& pos)
|
||||
{
|
||||
return m_position.isInRange(pos, g_map.getAwareRange().left - 1, g_map.getAwareRange().top - 1);
|
||||
|
@@ -63,6 +63,7 @@ public:
|
||||
void setRegenerationTime(double regenerationTime);
|
||||
void setOfflineTrainingTime(double offlineTrainingTime);
|
||||
void setSpells(const std::vector<int>& spells);
|
||||
void setBlessings(int blessings);
|
||||
|
||||
int getStates() { return m_states; }
|
||||
int getSkillLevel(Otc::Skill skill) { return m_skillsLevel[skill]; }
|
||||
@@ -88,6 +89,7 @@ public:
|
||||
double getOfflineTrainingTime() { return m_offlineTrainingTime; }
|
||||
std::vector<int> getSpells() { return m_spells; }
|
||||
ItemPtr getInventoryItem(Otc::InventorySlot inventory) { return m_inventoryItems[inventory]; }
|
||||
int getBlessings() { return m_blessings; }
|
||||
|
||||
bool hasSight(const Position& pos);
|
||||
bool isKnown() { return m_known; }
|
||||
@@ -144,6 +146,7 @@ private:
|
||||
|
||||
int m_states;
|
||||
int m_vocation;
|
||||
int m_blessings;
|
||||
|
||||
double m_health;
|
||||
double m_maxHealth;
|
||||
|
@@ -63,6 +63,7 @@ void Client::registerLuaFunctions()
|
||||
g_lua.bindSingletonFunction("g_things", "isDatLoaded", &ThingTypeManager::isDatLoaded, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "isOtbLoaded", &ThingTypeManager::isOtbLoaded, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "getDatSignature", &ThingTypeManager::getDatSignature, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "getContentRevision", &ThingTypeManager::getContentRevision, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "getThingType", &ThingTypeManager::getThingType, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "getItemType", &ThingTypeManager::getItemType, &g_things);
|
||||
g_lua.bindSingletonFunction("g_things", "getThingTypes", &ThingTypeManager::getThingTypes, &g_things);
|
||||
@@ -630,6 +631,7 @@ void Client::registerLuaFunctions()
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getTotalCapacity", &LocalPlayer::getTotalCapacity);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getInventoryItem", &LocalPlayer::getInventoryItem);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getVocation", &LocalPlayer::getVocation);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("getBlessings", &LocalPlayer::getBlessings);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("isPremium", &LocalPlayer::isPremium);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("isKnown", &LocalPlayer::isKnown);
|
||||
g_lua.bindClassMemberFunction<LocalPlayer>("isPreWalking", &LocalPlayer::isPreWalking);
|
||||
|
@@ -28,7 +28,52 @@ std::map<uint8, uint8> messageModesMap;
|
||||
|
||||
void buildMessageModesMap(int version) {
|
||||
messageModesMap.clear();
|
||||
if(version >= 1036) {
|
||||
|
||||
if(version >= 1055) { // might be 1054
|
||||
messageModesMap[Otc::MessageNone] = 0;
|
||||
messageModesMap[Otc::MessageSay] = 1;
|
||||
messageModesMap[Otc::MessageWhisper] = 2;
|
||||
messageModesMap[Otc::MessageYell] = 3;
|
||||
messageModesMap[Otc::MessagePrivateFrom] = 4;
|
||||
messageModesMap[Otc::MessagePrivateTo] = 5;
|
||||
messageModesMap[Otc::MessageChannelManagement] = 6;
|
||||
messageModesMap[Otc::MessageChannel] = 7;
|
||||
messageModesMap[Otc::MessageChannelHighlight] = 8;
|
||||
messageModesMap[Otc::MessageSpell] = 9;
|
||||
//NpcFromStartBlock = 10
|
||||
messageModesMap[Otc::MessageNpcFrom] = 11;
|
||||
messageModesMap[Otc::MessageNpcTo] = 12;
|
||||
messageModesMap[Otc::MessageGamemasterBroadcast] = 13;
|
||||
messageModesMap[Otc::MessageGamemasterChannel] = 14;
|
||||
messageModesMap[Otc::MessageGamemasterPrivateFrom] = 15;
|
||||
messageModesMap[Otc::MessageGamemasterPrivateTo] = 16;
|
||||
messageModesMap[Otc::MessageLogin] = 17;
|
||||
messageModesMap[Otc::MessageWarning] = 18; // Admin
|
||||
messageModesMap[Otc::MessageGame] = 19;
|
||||
messageModesMap[Otc::MessageGameHighlight] = 20;
|
||||
messageModesMap[Otc::MessageFailure] = 21;
|
||||
messageModesMap[Otc::MessageLook] = 22;
|
||||
messageModesMap[Otc::MessageDamageDealed] = 23;
|
||||
messageModesMap[Otc::MessageDamageReceived] = 24;
|
||||
messageModesMap[Otc::MessageHeal] = 25;
|
||||
messageModesMap[Otc::MessageExp] = 26;
|
||||
messageModesMap[Otc::MessageDamageOthers] = 27;
|
||||
messageModesMap[Otc::MessageHealOthers] = 28;
|
||||
messageModesMap[Otc::MessageExpOthers] = 29;
|
||||
messageModesMap[Otc::MessageStatus] = 30;
|
||||
messageModesMap[Otc::MessageLoot] = 31;
|
||||
messageModesMap[Otc::MessageTradeNpc] = 32;
|
||||
messageModesMap[Otc::MessageGuild] = 33;
|
||||
messageModesMap[Otc::MessagePartyManagement] = 34;
|
||||
messageModesMap[Otc::MessageParty] = 35;
|
||||
messageModesMap[Otc::MessageBarkLow] = 36;
|
||||
messageModesMap[Otc::MessageBarkLoud] = 37;
|
||||
messageModesMap[Otc::MessageReport] = 38;
|
||||
messageModesMap[Otc::MessageHotkeyUse] = 39;
|
||||
messageModesMap[Otc::MessageTutorialHint] = 40;
|
||||
messageModesMap[Otc::MessageThankyou] = 41;
|
||||
messageModesMap[Otc::MessageMarket] = 42;
|
||||
} else if(version >= 1036) {
|
||||
for(int i = Otc::MessageNone; i <= Otc::MessageBeyondLast; ++i) {
|
||||
if(i >= Otc::MessageNpcTo)
|
||||
messageModesMap[i] = i + 1;
|
||||
|
@@ -107,6 +107,8 @@ namespace Proto {
|
||||
GameServerCreatureType = 149,
|
||||
GameServerEditText = 150,
|
||||
GameServerEditList = 151,
|
||||
GameServerBlessings = 156,
|
||||
GameServerPreset = 157,
|
||||
GameServerPremiumTrigger = 158, // 1038
|
||||
GameServerPlayerDataBasic = 159, // 950
|
||||
GameServerPlayerData = 160,
|
||||
@@ -130,6 +132,8 @@ namespace Proto {
|
||||
GameServerTextMessage = 180,
|
||||
GameServerCancelWalk = 181,
|
||||
GameServerWalkWait = 182,
|
||||
GameServerUnjustifiedStats = 183,
|
||||
GameServerPvpSituations = 184,
|
||||
GameServerFloorChangeUp = 190,
|
||||
GameServerFloorChangeDown = 191,
|
||||
GameServerChooseOutfit = 200,
|
||||
|
@@ -56,7 +56,7 @@ void ProtocolGame::onRecv(const InputMessagePtr& inputMessage)
|
||||
if(m_firstRecv) {
|
||||
m_firstRecv = false;
|
||||
|
||||
if(g_game.getClientVersion() >= 841) { // not sure since which version this is, but it seems to be after 8.40
|
||||
if(g_game.getFeature(Otc::GameMessageSizeCheck)) {
|
||||
int size = inputMessage->getU16();
|
||||
if(size != inputMessage->getUnreadSize()) {
|
||||
g_logger.traceError("invalid message size");
|
||||
|
@@ -128,6 +128,10 @@ public:
|
||||
void addPosition(const OutputMessagePtr& msg, const Position& position);
|
||||
|
||||
private:
|
||||
void parseBlessings(const InputMessagePtr& msg);
|
||||
void parseUnjustifiedStats(const InputMessagePtr& msg);
|
||||
void parsePvpSituations(const InputMessagePtr& msg);
|
||||
void parsePreset(const InputMessagePtr& msg);
|
||||
void parseCreatureType(const InputMessagePtr& msg);
|
||||
void parsePlayerHelpers(const InputMessagePtr& msg);
|
||||
void parseMessage(const InputMessagePtr& msg);
|
||||
|
@@ -340,6 +340,19 @@ void ProtocolGame::parseMessage(const InputMessagePtr& msg)
|
||||
case Proto::GameServerCreatureType:
|
||||
parseCreatureType(msg);
|
||||
break;
|
||||
// PROTOCOL>=1055
|
||||
case Proto::GameServerBlessings:
|
||||
parseBlessings(msg);
|
||||
break;
|
||||
case Proto::GameServerUnjustifiedStats:
|
||||
parseUnjustifiedStats(msg);
|
||||
break;
|
||||
case Proto::GameServerPvpSituations:
|
||||
parsePvpSituations(msg);
|
||||
break;
|
||||
case Proto::GameServerPreset:
|
||||
parsePreset(msg);
|
||||
break;
|
||||
// otclient ONLY
|
||||
case Proto::GameServerExtendedOpcode:
|
||||
parseExtendedOpcode(msg);
|
||||
@@ -372,6 +385,9 @@ void ProtocolGame::parseLogin(const InputMessagePtr& msg)
|
||||
}
|
||||
bool canReportBugs = msg->getU8();
|
||||
|
||||
msg->getU8(); // can change pvp framing option
|
||||
msg->getU8(); // expert mode enabled
|
||||
|
||||
m_localPlayer->setId(playerId);
|
||||
g_game.setServerBeat(serverBeat);
|
||||
g_game.setCanReportBugs(canReportBugs);
|
||||
@@ -396,6 +412,34 @@ void ProtocolGame::parseEnterGame(const InputMessagePtr& msg)
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolGame::parseBlessings(const InputMessagePtr& msg)
|
||||
{
|
||||
uint16 blessings = msg->getU16();
|
||||
m_localPlayer->setBlessings(blessings);
|
||||
}
|
||||
|
||||
void ProtocolGame::parsePreset(const InputMessagePtr& msg)
|
||||
{
|
||||
uint16 preset = msg->getU32();
|
||||
}
|
||||
|
||||
void ProtocolGame::parseUnjustifiedStats(const InputMessagePtr& msg)
|
||||
{
|
||||
// Unjustified Kills display since 10.55
|
||||
msg->getU8();
|
||||
msg->getU8();
|
||||
msg->getU8();
|
||||
msg->getU8();
|
||||
msg->getU8();
|
||||
msg->getU8();
|
||||
msg->getU8();
|
||||
}
|
||||
|
||||
void ProtocolGame::parsePvpSituations(const InputMessagePtr& msg)
|
||||
{
|
||||
msg->getU8(); // amount of open pvp situations
|
||||
}
|
||||
|
||||
void ProtocolGame::parsePlayerHelpers(const InputMessagePtr& msg)
|
||||
{
|
||||
uint id = msg->getU32();
|
||||
@@ -468,6 +512,7 @@ void ProtocolGame::parseChallenge(const InputMessagePtr& msg)
|
||||
{
|
||||
uint timestamp = msg->getU32();
|
||||
uint8 random = msg->getU8();
|
||||
|
||||
sendLoginPacket(timestamp, random);
|
||||
}
|
||||
|
||||
@@ -1038,7 +1083,7 @@ void ProtocolGame::parsePlayerInfo(const InputMessagePtr& msg)
|
||||
bool premium = msg->getU8(); // premium
|
||||
int vocation = msg->getU8(); // vocation
|
||||
if(g_game.getFeature(Otc::GamePremiumExpiration))
|
||||
int premiumEx = msg->getU32(); // premium expiration
|
||||
int premiumEx = msg->getU32(); // premium expiration used for premium advertisement
|
||||
|
||||
int spellCount = msg->getU16();
|
||||
std::vector<int> spells;
|
||||
@@ -1081,6 +1126,10 @@ void ProtocolGame::parsePlayerStats(const InputMessagePtr& msg)
|
||||
|
||||
double level = msg->getU16();
|
||||
double levelPercent = msg->getU8();
|
||||
|
||||
if(g_game.getFeature(Otc::GameExperienceBonus))
|
||||
double experienceBonus = msg->getDouble();
|
||||
|
||||
double mana;
|
||||
double maxMana;
|
||||
|
||||
@@ -1145,7 +1194,7 @@ void ProtocolGame::parsePlayerSkills(const InputMessagePtr& msg)
|
||||
|
||||
int baseLevel;
|
||||
if(g_game.getFeature(Otc::GameSkillsBase))
|
||||
if (g_game.getFeature(Otc::GameBaseSkillU16))
|
||||
if(g_game.getFeature(Otc::GameBaseSkillU16))
|
||||
baseLevel = msg->getU16();
|
||||
else
|
||||
baseLevel = msg->getU8();
|
||||
@@ -1699,7 +1748,7 @@ void ProtocolGame::parseChangeMapAwareRange(const InputMessagePtr& msg)
|
||||
void ProtocolGame::parseCreaturesMark(const InputMessagePtr& msg)
|
||||
{
|
||||
int len;
|
||||
if (g_game.getClientVersion() >= 1035) {
|
||||
if(g_game.getClientVersion() >= 1035) {
|
||||
len = 1;
|
||||
} else {
|
||||
len = msg->getU8();
|
||||
|
@@ -56,17 +56,20 @@ void ProtocolGame::sendLoginPacket(uint challengeTimestamp, uint8 challengeRando
|
||||
msg->addU16(g_game.getOs());
|
||||
msg->addU16(g_game.getProtocolVersion());
|
||||
|
||||
if(g_game.getClientVersion() >= 980) {
|
||||
if(g_game.getFeature(Otc::GameClientVersion))
|
||||
msg->addU32(g_game.getClientVersion());
|
||||
msg->addU8(0); // preview state
|
||||
}
|
||||
|
||||
if(g_game.getFeature(Otc::GameContentRevision))
|
||||
msg->addU16(g_things.getContentRevision());
|
||||
|
||||
if(g_game.getFeature(Otc::GamePreviewState))
|
||||
msg->addU8(0);
|
||||
|
||||
int offset = msg->getMessageSize();
|
||||
// first RSA byte must be 0
|
||||
msg->addU8(0);
|
||||
|
||||
msg->addU8(0); // first RSA byte must be 0
|
||||
|
||||
if(g_game.getClientVersion() >= 770)
|
||||
{
|
||||
if(g_game.getFeature(Otc::GameLoginPacketEncryption)) {
|
||||
// xtea key
|
||||
generateXteaKey();
|
||||
msg->addU32(m_xteaKey[0]);
|
||||
@@ -99,7 +102,7 @@ void ProtocolGame::sendLoginPacket(uint challengeTimestamp, uint8 challengeRando
|
||||
msg->addPaddingBytes(paddingBytes);
|
||||
|
||||
// encrypt with RSA
|
||||
if(g_game.getClientVersion() >= 770)
|
||||
if(g_game.getFeature(Otc::GameLoginPacketEncryption))
|
||||
msg->encryptRsa();
|
||||
|
||||
if(g_game.getFeature(Otc::GameProtocolChecksum))
|
||||
@@ -107,7 +110,7 @@ void ProtocolGame::sendLoginPacket(uint challengeTimestamp, uint8 challengeRando
|
||||
|
||||
send(msg);
|
||||
|
||||
if(g_game.getClientVersion() >= 770)
|
||||
if(g_game.getFeature(Otc::GameLoginPacketEncryption))
|
||||
enableXteaEncryption();
|
||||
}
|
||||
|
||||
|
@@ -274,51 +274,60 @@ void ThingType::unserialize(uint16 clientId, ThingCategory category, const FileS
|
||||
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();
|
||||
m_size = Size(width, height);
|
||||
if(width > 1 || height > 1) {
|
||||
m_realSize = fin->getU8();
|
||||
m_exactSize = std::min<int>(m_realSize, std::max<int>(width * 32, height * 32));
|
||||
}
|
||||
else
|
||||
m_exactSize = 32;
|
||||
uint8 frames = 1;
|
||||
if(category == ThingCategoryCreature && g_game.getClientVersion() >= 1057)
|
||||
frames = fin->getU8();
|
||||
|
||||
m_layers = fin->getU8();
|
||||
m_numPatternX = fin->getU8();
|
||||
m_numPatternY = fin->getU8();
|
||||
if(g_game.getClientVersion() >= 755)
|
||||
m_numPatternZ = fin->getU8();
|
||||
else
|
||||
m_numPatternZ = 1;
|
||||
m_animationPhases = fin->getU8();
|
||||
for(int i = 0; i < frames; ++i) {
|
||||
uint8 frameGroup = FrameGroupDefault;
|
||||
if(category == ThingCategoryCreature && g_game.getClientVersion() >= 1057) {
|
||||
frameGroup = 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();
|
||||
uint8 width = fin->getU8();
|
||||
uint8 height = fin->getU8();
|
||||
m_size = Size(width, height);
|
||||
if(width > 1 || height > 1) {
|
||||
m_realSize = fin->getU8();
|
||||
m_exactSize = std::min<int>(m_realSize, std::max<int>(width * 32, height * 32));
|
||||
}
|
||||
else
|
||||
m_exactSize = 32;
|
||||
|
||||
for(int i = 0; i < m_animationPhases; i++) {
|
||||
int minDuration = fin->getU32();
|
||||
int maxDuration = fin->getU32();
|
||||
m_layers = fin->getU8();
|
||||
m_numPatternX = fin->getU8();
|
||||
m_numPatternY = fin->getU8();
|
||||
if(g_game.getClientVersion() >= 755)
|
||||
m_numPatternZ = fin->getU8();
|
||||
else
|
||||
m_numPatternZ = 1;
|
||||
m_animationPhases = fin->getU8();
|
||||
|
||||
m_animation.frames.push_back(std::make_tuple(minDuration, maxDuration));
|
||||
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 > 4096)
|
||||
stdext::throw_exception("a thing type has more than 4096 sprites");
|
||||
|
||||
m_spritesIndex.resize(totalSprites);
|
||||
for(int i = 0; i < totalSprites; i++)
|
||||
m_spritesIndex[i] = g_game.getFeature(Otc::GameSpritesU32) ? fin->getU32() : fin->getU16();
|
||||
}
|
||||
|
||||
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 > 4096)
|
||||
stdext::throw_exception("a thing type has more than 4096 sprites");
|
||||
|
||||
m_spritesIndex.resize(totalSprites);
|
||||
for(int i = 0; i < totalSprites; i++)
|
||||
m_spritesIndex[i] = g_game.getFeature(Otc::GameSpritesU32) ? fin->getU32() : fin->getU16();
|
||||
|
||||
m_textures.resize(m_animationPhases);
|
||||
m_texturesFramesRects.resize(m_animationPhases);
|
||||
m_texturesFramesOriginRects.resize(m_animationPhases);
|
||||
|
@@ -32,6 +32,12 @@
|
||||
#include <framework/luaengine/luaobject.h>
|
||||
#include <framework/net/server.h>
|
||||
|
||||
enum FrameGroup : uint8 {
|
||||
FrameGroupIdle = 0,
|
||||
FrameGroupMoving,
|
||||
FrameGroupDefault = FrameGroupIdle
|
||||
};
|
||||
|
||||
enum ThingCategory : uint8 {
|
||||
ThingCategoryItem = 0,
|
||||
ThingCategoryCreature,
|
||||
|
@@ -42,6 +42,7 @@ void ThingTypeManager::init()
|
||||
m_nullThingType = ThingTypePtr(new ThingType);
|
||||
m_nullItemType = ItemTypePtr(new ItemType);
|
||||
m_datSignature = 0;
|
||||
m_contentRevision = 0;
|
||||
m_otbMinorVersion = 0;
|
||||
m_otbMajorVersion = 0;
|
||||
m_datLoaded = false;
|
||||
@@ -100,12 +101,14 @@ bool ThingTypeManager::loadDat(std::string file)
|
||||
{
|
||||
m_datLoaded = false;
|
||||
m_datSignature = 0;
|
||||
m_contentRevision = 0;
|
||||
try {
|
||||
file = g_resources.guessFilePath(file, "dat");
|
||||
|
||||
FileStreamPtr fin = g_resources.openFile(file);
|
||||
|
||||
m_datSignature = fin->getU32();
|
||||
m_contentRevision = static_cast<uint16_t>(m_datSignature);
|
||||
|
||||
for(int category = 0; category < ThingLastCategory; ++category) {
|
||||
int count = fin->getU16() + 1;
|
||||
|
@@ -66,6 +66,7 @@ public:
|
||||
uint32 getDatSignature() { return m_datSignature; }
|
||||
uint32 getOtbMajorVersion() { return m_otbMajorVersion; }
|
||||
uint32 getOtbMinorVersion() { return m_otbMinorVersion; }
|
||||
uint16 getContentRevision() { return m_contentRevision; }
|
||||
|
||||
bool isDatLoaded() { return m_datLoaded; }
|
||||
bool isXmlLoaded() { return m_xmlLoaded; }
|
||||
@@ -89,6 +90,7 @@ private:
|
||||
uint32 m_otbMinorVersion;
|
||||
uint32 m_otbMajorVersion;
|
||||
uint32 m_datSignature;
|
||||
uint16 m_contentRevision;
|
||||
};
|
||||
|
||||
extern ThingTypeManager g_things;
|
||||
|
Reference in New Issue
Block a user