From cf9f57736f57a8b7ab4f8b9b4090ce2c6bf0cb1c Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Wed, 18 Jul 2012 03:04:57 -0300 Subject: [PATCH] More multiprotocol progress --- modules/game_containers/container.otui | 1 - modules/game_playertrade/tradewindow.otui | 1 - modules/game_textmessage/textmessage.lua | 2 +- modules/game_textwindow/textwindow.otui | 1 - modules/game_tibiafiles/tibiafiles.otmod | 11 +-- modules/gamelib/protocollogin.lua | 2 +- src/otclient/const.h | 25 ++--- src/otclient/game.cpp | 16 +++- src/otclient/localplayer.cpp | 4 +- src/otclient/localplayer.h | 6 +- src/otclient/protocolgameparse.cpp | 5 +- src/otclient/spritemanager.cpp | 109 ++++++++++++---------- 12 files changed, 97 insertions(+), 86 deletions(-) diff --git a/modules/game_containers/container.otui b/modules/game_containers/container.otui index cc42ecce..d4ff4af2 100644 --- a/modules/game_containers/container.otui +++ b/modules/game_containers/container.otui @@ -4,7 +4,6 @@ ContainerWindow < MiniWindow UIItem id: containerItemWidget virtual: true - item-id: 3253 size: 16 16 anchors.top: parent.top anchors.left: parent.left diff --git a/modules/game_playertrade/tradewindow.otui b/modules/game_playertrade/tradewindow.otui index 733a21f9..3b7df930 100644 --- a/modules/game_playertrade/tradewindow.otui +++ b/modules/game_playertrade/tradewindow.otui @@ -5,7 +5,6 @@ TradeWindow < MiniWindow UIItem id: tradeItem virtual: true - item-id: 3253 size: 16 16 anchors.top: parent.top anchors.left: parent.left diff --git a/modules/game_textmessage/textmessage.lua b/modules/game_textmessage/textmessage.lua index 391a6d5d..8ac766b9 100644 --- a/modules/game_textmessage/textmessage.lua +++ b/modules/game_textmessage/textmessage.lua @@ -56,7 +56,7 @@ local function createTextMessageLabel(id, parent, class) end -- public functions -function TextMessage.init() +function TextMessage.init() connect(g_game, { onTextMessage = TextMessage.display, onGameStart = TextMessage.clearMessages }) diff --git a/modules/game_textwindow/textwindow.otui b/modules/game_textwindow/textwindow.otui index 3624bf79..342c8328 100644 --- a/modules/game_textwindow/textwindow.otui +++ b/modules/game_textwindow/textwindow.otui @@ -6,7 +6,6 @@ TextWindow < MainWindow UIItem id: textItem virtual: true - item-id: 173 size: 32 32 anchors.top: parent.top anchors.left: parent.left diff --git a/modules/game_tibiafiles/tibiafiles.otmod b/modules/game_tibiafiles/tibiafiles.otmod index 9e4f023f..5ccadf57 100644 --- a/modules/game_tibiafiles/tibiafiles.otmod +++ b/modules/game_tibiafiles/tibiafiles.otmod @@ -4,9 +4,8 @@ Module reloadable: false @onLoad: | - if not g_things.loadDat('/game_tibiafiles/Tibia.dat') then - fatal(tr("Unable to load dat file, please place a valid Tibia dat in modules/game_tibiafiles/Tibia.dat")) - end - if not g_sprites.loadSpr('/game_tibiafiles/Tibia.spr') then - fatal(tr("Unable to load spr file, please place a valid Tibia spr in modules/game_tibiafiles/Tibia.spr")) - end + dofile 'tibiafiles' + TibiaFiles.init() + + @onUnload: | + TibiaFiles.terminate() diff --git a/modules/gamelib/protocollogin.lua b/modules/gamelib/protocollogin.lua index 6d3a9792..2dd65ab4 100644 --- a/modules/gamelib/protocollogin.lua +++ b/modules/gamelib/protocollogin.lua @@ -2,7 +2,7 @@ ProtocolLogin = extends(Protocol) -- set to the latest Tibia.pic signature to make otclient compatible with official tibia -local PIC_SIGNATURE = 0 +local PIC_SIGNATURE = 1337606793 LoginServerError = 10 LoginServerMotd = 20 diff --git a/src/otclient/const.h b/src/otclient/const.h index 9c221c82..7617d521 100644 --- a/src/otclient/const.h +++ b/src/otclient/const.h @@ -108,7 +108,7 @@ namespace Otc DatLastOpt = 255 }; - enum InventorySlots { + enum InventorySlot { InventorySlotHead = 1, InventorySlotNecklace, InventorySlotBackpack, @@ -118,7 +118,9 @@ namespace Otc InventorySlotLegs, InventorySlotFeet, InventorySlotRing, - InventorySlotAmmo + InventorySlotAmmo, + InventorySlotPurse, + LastInventorySlot }; enum Statistic { @@ -148,21 +150,6 @@ namespace Otc LastSkill }; - enum Inventory { - NoInventory = 0, - Head, - Neck, - Bag, - Armor, - RightHand, - LeftHand, - Legs, - Feet, - Ring, - Ammo, - LastInventory - }; - enum Direction { North = 0, East, @@ -304,6 +291,10 @@ namespace Otc GameItemAnimationPhase = 19, GameMagicEffectU16 = 22, GamePlayerMarket = 23, + GameSpritesU32 = 24, + GameChargeableItems = 25, + GameOfflineTrainingTime = 26, + GamePurseSlot = 27, // 23-50 unused yet // 51-100 reserved to be defined in lua LastGameFeature = 101 diff --git a/src/otclient/game.cpp b/src/otclient/game.cpp index e2e2acc9..c8f7de9c 100644 --- a/src/otclient/game.cpp +++ b/src/otclient/game.cpp @@ -38,6 +38,7 @@ Game g_game; Game::Game() { resetGameStates(); + //setProtocolVersion(960); m_protocolVersion = 0; } @@ -235,7 +236,7 @@ void Game::processInventoryChange(int slot, const ItemPtr& item) if(item) item->setPosition(Position(65535, slot, 0)); - m_localPlayer->setInventoryItem((Otc::Inventory)slot, item); + m_localPlayer->setInventoryItem((Otc::InventorySlot)slot, item); } void Game::processCreatureMove(const CreaturePtr& creature, const Position& oldPos, const Position& newPos) @@ -1101,6 +1102,10 @@ void Game::setProtocolVersion(int version) m_features.reset(); + if(version <= 810) { + enableFeature(Otc::GameChargeableItems); + } + if(version >= 854) { enableFeature(Otc::GameProtocolChecksum); enableFeature(Otc::GameAccountNames); @@ -1132,6 +1137,15 @@ void Game::setProtocolVersion(int version) enableFeature(Otc::GamePlayerMarket); } + if(version >= 954) { + enableFeature(Otc::GamePurseSlot); + } + + if(version >= 960) { + enableFeature(Otc::GameSpritesU32); + enableFeature(Otc::GameOfflineTrainingTime); + } + m_protocolVersion = version; } diff --git a/src/otclient/localplayer.cpp b/src/otclient/localplayer.cpp index d9e1b7f0..108c072b 100644 --- a/src/otclient/localplayer.cpp +++ b/src/otclient/localplayer.cpp @@ -313,9 +313,9 @@ void LocalPlayer::setStamina(double stamina) } } -void LocalPlayer::setInventoryItem(Otc::Inventory inventory, const ItemPtr& item) +void LocalPlayer::setInventoryItem(Otc::InventorySlot inventory, const ItemPtr& item) { - if(inventory >= Otc::LastInventory) { + if(inventory >= Otc::LastInventorySlot) { g_logger.traceError("invalid slot"); return; } diff --git a/src/otclient/localplayer.h b/src/otclient/localplayer.h index 54f0aa5e..314f9b20 100644 --- a/src/otclient/localplayer.h +++ b/src/otclient/localplayer.h @@ -51,7 +51,7 @@ public: void setSoul(double soul); void setStamina(double stamina); void setKnown(bool known) { m_known = known; } - void setInventoryItem(Otc::Inventory inventory, const ItemPtr& item); + void setInventoryItem(Otc::InventorySlot inventory, const ItemPtr& item); int getStates() { return m_states; } int getSkillLevel(Otc::Skill skill) { return m_skillsLevel[skill]; } @@ -68,7 +68,7 @@ public: double getMagicLevelPercent() { return m_magicLevelPercent; } double getSoul() { return m_soul; } double getStamina() { return m_stamina; } - ItemPtr getInventoryItem(Otc::Inventory inventory) { return m_inventoryItems[inventory]; } + ItemPtr getInventoryItem(Otc::InventorySlot inventory) { return m_inventoryItems[inventory]; } bool isKnown() { return m_known; } bool isPreWalking() { return m_preWalking; } @@ -98,7 +98,7 @@ private: bool m_autoWalking; Position m_lastPrewalkDestionation; Timer m_walkLockTimer; - ItemPtr m_inventoryItems[Otc::LastInventory]; + ItemPtr m_inventoryItems[Otc::LastInventorySlot]; ScheduledEventPtr m_autoWalkEndEvent; std::array m_skillsLevel; diff --git a/src/otclient/protocolgameparse.cpp b/src/otclient/protocolgameparse.cpp index b1f1635a..7e7eab06 100644 --- a/src/otclient/protocolgameparse.cpp +++ b/src/otclient/protocolgameparse.cpp @@ -887,7 +887,10 @@ void ProtocolGame::parsePlayerStats(const InputMessagePtr& msg) m_localPlayer->setSpeed(msg->getU16()); if(g_game.getFeature(Otc::GamePlayerRegenerationTime)) - msg->getU16(); // regeneration time + msg->getU16(); + + if(g_game.getFeature(Otc::GameOfflineTrainingTime)) + msg->getU16(); } void ProtocolGame::parsePlayerSkills(const InputMessagePtr& msg) diff --git a/src/otclient/spritemanager.cpp b/src/otclient/spritemanager.cpp index ad6474b6..ddcea00b 100644 --- a/src/otclient/spritemanager.cpp +++ b/src/otclient/spritemanager.cpp @@ -21,6 +21,7 @@ */ #include "spritemanager.h" +#include "game.h" #include #include #include @@ -49,7 +50,8 @@ bool SpriteManager::loadSpr(const std::string& file) m_spritesFile->cache(); m_signature = m_spritesFile->getU32(); - m_spritesCount = m_spritesFile->getU16(); + m_spritesCount = g_game.getFeature(Otc::GameSpritesU32) ? m_spritesFile->getU32() : m_spritesFile->getU16(); + m_spritesOffset = m_spritesFile->tell(); m_loaded = true; return true; } catch(stdext::exception& e) { @@ -67,48 +69,70 @@ void SpriteManager::unload() ImagePtr SpriteManager::getSpriteImage(int id) { - enum { - SPRITE_SIZE = 32, - SPRITE_DATA_SIZE = SPRITE_SIZE*SPRITE_SIZE*4 - }; + try { + enum { + SPRITE_SIZE = 32, + SPRITE_DATA_SIZE = SPRITE_SIZE*SPRITE_SIZE*4 + }; - if(id == 0) - return nullptr; + if(id == 0 || !m_spritesFile) + return nullptr; - m_spritesFile->seek(((id-1) * 4) + 6); + m_spritesFile->seek(((id-1) * 4) + m_spritesOffset); - uint32 spriteAddress = m_spritesFile->getU32(); + uint32 spriteAddress = m_spritesFile->getU32(); - // no sprite? return an empty texture - if(spriteAddress == 0) - return nullptr; + // no sprite? return an empty texture + if(spriteAddress == 0) + return nullptr; - m_spritesFile->seek(spriteAddress); + m_spritesFile->seek(spriteAddress); - // skip color key - m_spritesFile->getU8(); - m_spritesFile->getU8(); - m_spritesFile->getU8(); + // skip color key + m_spritesFile->getU8(); + m_spritesFile->getU8(); + m_spritesFile->getU8(); - uint16 pixelDataSize = m_spritesFile->getU16(); + uint16 pixelDataSize = m_spritesFile->getU16(); - ImagePtr image(new Image(Size(SPRITE_SIZE, SPRITE_SIZE))); + ImagePtr image(new Image(Size(SPRITE_SIZE, SPRITE_SIZE))); - uint8 *pixels = image->getPixelData(); - int writePos = 0; - int read = 0; + uint8 *pixels = image->getPixelData(); + int writePos = 0; + int read = 0; - // decompress pixels - while(read < pixelDataSize) { - uint16 transparentPixels = m_spritesFile->getU16(); - uint16 coloredPixels = m_spritesFile->getU16(); + // decompress pixels + while(read < pixelDataSize) { + uint16 transparentPixels = m_spritesFile->getU16(); + uint16 coloredPixels = m_spritesFile->getU16(); - if(writePos + transparentPixels*4 + coloredPixels*3 >= SPRITE_DATA_SIZE) { - g_logger.warning(stdext::format("corrupt sprite id %d", id)); - return nullptr; + if(writePos + transparentPixels*4 + coloredPixels*3 >= SPRITE_DATA_SIZE) { + g_logger.warning(stdext::format("corrupt sprite id %d", id)); + return nullptr; + } + + for(int i = 0; i < transparentPixels; i++) { + pixels[writePos + 0] = 0x00; + pixels[writePos + 1] = 0x00; + pixels[writePos + 2] = 0x00; + pixels[writePos + 3] = 0x00; + writePos += 4; + } + + for(int i = 0; i < coloredPixels; i++) { + pixels[writePos + 0] = m_spritesFile->getU8(); + pixels[writePos + 1] = m_spritesFile->getU8(); + pixels[writePos + 2] = m_spritesFile->getU8(); + pixels[writePos + 3] = 0xFF; + + writePos += 4; + } + + read += 4 + (3 * coloredPixels); } - for(int i = 0; i < transparentPixels; i++) { + // fill remaining pixels with alpha + while(writePos < SPRITE_DATA_SIZE) { pixels[writePos + 0] = 0x00; pixels[writePos + 1] = 0x00; pixels[writePos + 2] = 0x00; @@ -116,27 +140,10 @@ ImagePtr SpriteManager::getSpriteImage(int id) writePos += 4; } - for(int i = 0; i < coloredPixels; i++) { - pixels[writePos + 0] = m_spritesFile->getU8(); - pixels[writePos + 1] = m_spritesFile->getU8(); - pixels[writePos + 2] = m_spritesFile->getU8(); - pixels[writePos + 3] = 0xFF; - - writePos += 4; - } - - read += 4 + (3 * coloredPixels); - } - - // fill remaining pixels with alpha - while(writePos < SPRITE_DATA_SIZE) { - pixels[writePos + 0] = 0x00; - pixels[writePos + 1] = 0x00; - pixels[writePos + 2] = 0x00; - pixels[writePos + 3] = 0x00; - writePos += 4; + return image; + } catch(stdext::exception& e) { + g_logger.error(stdext::format("Failed to get sprite id %d: %s", id, e.what())); + return nullptr; } - - return image; }