More multiprotocol progress

This commit is contained in:
Eduardo Bart 2012-07-18 03:04:57 -03:00
parent c8d1d5ecf2
commit cf9f57736f
12 changed files with 106 additions and 95 deletions

View File

@ -4,7 +4,6 @@ ContainerWindow < MiniWindow
UIItem UIItem
id: containerItemWidget id: containerItemWidget
virtual: true virtual: true
item-id: 3253
size: 16 16 size: 16 16
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left

View File

@ -5,7 +5,6 @@ TradeWindow < MiniWindow
UIItem UIItem
id: tradeItem id: tradeItem
virtual: true virtual: true
item-id: 3253
size: 16 16 size: 16 16
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left

View File

@ -56,7 +56,7 @@ local function createTextMessageLabel(id, parent, class)
end end
-- public functions -- public functions
function TextMessage.init() function TextMessage.init()
connect(g_game, { onTextMessage = TextMessage.display, connect(g_game, { onTextMessage = TextMessage.display,
onGameStart = TextMessage.clearMessages }) onGameStart = TextMessage.clearMessages })

View File

@ -6,7 +6,6 @@ TextWindow < MainWindow
UIItem UIItem
id: textItem id: textItem
virtual: true virtual: true
item-id: 173
size: 32 32 size: 32 32
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left

View File

@ -4,9 +4,8 @@ Module
reloadable: false reloadable: false
@onLoad: | @onLoad: |
if not g_things.loadDat('/game_tibiafiles/Tibia.dat') then dofile 'tibiafiles'
fatal(tr("Unable to load dat file, please place a valid Tibia dat in modules/game_tibiafiles/Tibia.dat")) TibiaFiles.init()
end
if not g_sprites.loadSpr('/game_tibiafiles/Tibia.spr') then @onUnload: |
fatal(tr("Unable to load spr file, please place a valid Tibia spr in modules/game_tibiafiles/Tibia.spr")) TibiaFiles.terminate()
end

View File

@ -2,7 +2,7 @@
ProtocolLogin = extends(Protocol) ProtocolLogin = extends(Protocol)
-- set to the latest Tibia.pic signature to make otclient compatible with official tibia -- set to the latest Tibia.pic signature to make otclient compatible with official tibia
local PIC_SIGNATURE = 0 local PIC_SIGNATURE = 1337606793
LoginServerError = 10 LoginServerError = 10
LoginServerMotd = 20 LoginServerMotd = 20

View File

@ -108,7 +108,7 @@ namespace Otc
DatLastOpt = 255 DatLastOpt = 255
}; };
enum InventorySlots { enum InventorySlot {
InventorySlotHead = 1, InventorySlotHead = 1,
InventorySlotNecklace, InventorySlotNecklace,
InventorySlotBackpack, InventorySlotBackpack,
@ -118,7 +118,9 @@ namespace Otc
InventorySlotLegs, InventorySlotLegs,
InventorySlotFeet, InventorySlotFeet,
InventorySlotRing, InventorySlotRing,
InventorySlotAmmo InventorySlotAmmo,
InventorySlotPurse,
LastInventorySlot
}; };
enum Statistic { enum Statistic {
@ -148,21 +150,6 @@ namespace Otc
LastSkill LastSkill
}; };
enum Inventory {
NoInventory = 0,
Head,
Neck,
Bag,
Armor,
RightHand,
LeftHand,
Legs,
Feet,
Ring,
Ammo,
LastInventory
};
enum Direction { enum Direction {
North = 0, North = 0,
East, East,
@ -304,6 +291,10 @@ namespace Otc
GameItemAnimationPhase = 19, GameItemAnimationPhase = 19,
GameMagicEffectU16 = 22, GameMagicEffectU16 = 22,
GamePlayerMarket = 23, GamePlayerMarket = 23,
GameSpritesU32 = 24,
GameChargeableItems = 25,
GameOfflineTrainingTime = 26,
GamePurseSlot = 27,
// 23-50 unused yet // 23-50 unused yet
// 51-100 reserved to be defined in lua // 51-100 reserved to be defined in lua
LastGameFeature = 101 LastGameFeature = 101

View File

@ -38,6 +38,7 @@ Game g_game;
Game::Game() Game::Game()
{ {
resetGameStates(); resetGameStates();
//setProtocolVersion(960);
m_protocolVersion = 0; m_protocolVersion = 0;
} }
@ -235,7 +236,7 @@ void Game::processInventoryChange(int slot, const ItemPtr& item)
if(item) if(item)
item->setPosition(Position(65535, slot, 0)); 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) void Game::processCreatureMove(const CreaturePtr& creature, const Position& oldPos, const Position& newPos)
@ -1101,6 +1102,10 @@ void Game::setProtocolVersion(int version)
m_features.reset(); m_features.reset();
if(version <= 810) {
enableFeature(Otc::GameChargeableItems);
}
if(version >= 854) { if(version >= 854) {
enableFeature(Otc::GameProtocolChecksum); enableFeature(Otc::GameProtocolChecksum);
enableFeature(Otc::GameAccountNames); enableFeature(Otc::GameAccountNames);
@ -1132,6 +1137,15 @@ void Game::setProtocolVersion(int version)
enableFeature(Otc::GamePlayerMarket); enableFeature(Otc::GamePlayerMarket);
} }
if(version >= 954) {
enableFeature(Otc::GamePurseSlot);
}
if(version >= 960) {
enableFeature(Otc::GameSpritesU32);
enableFeature(Otc::GameOfflineTrainingTime);
}
m_protocolVersion = version; m_protocolVersion = version;
} }

View File

@ -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"); g_logger.traceError("invalid slot");
return; return;
} }

View File

@ -51,7 +51,7 @@ public:
void setSoul(double soul); void setSoul(double soul);
void setStamina(double stamina); void setStamina(double stamina);
void setKnown(bool known) { m_known = known; } 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 getStates() { return m_states; }
int getSkillLevel(Otc::Skill skill) { return m_skillsLevel[skill]; } int getSkillLevel(Otc::Skill skill) { return m_skillsLevel[skill]; }
@ -68,7 +68,7 @@ public:
double getMagicLevelPercent() { return m_magicLevelPercent; } double getMagicLevelPercent() { return m_magicLevelPercent; }
double getSoul() { return m_soul; } double getSoul() { return m_soul; }
double getStamina() { return m_stamina; } 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 isKnown() { return m_known; }
bool isPreWalking() { return m_preWalking; } bool isPreWalking() { return m_preWalking; }
@ -98,7 +98,7 @@ private:
bool m_autoWalking; bool m_autoWalking;
Position m_lastPrewalkDestionation; Position m_lastPrewalkDestionation;
Timer m_walkLockTimer; Timer m_walkLockTimer;
ItemPtr m_inventoryItems[Otc::LastInventory]; ItemPtr m_inventoryItems[Otc::LastInventorySlot];
ScheduledEventPtr m_autoWalkEndEvent; ScheduledEventPtr m_autoWalkEndEvent;
std::array<int, Otc::LastSkill> m_skillsLevel; std::array<int, Otc::LastSkill> m_skillsLevel;

View File

@ -887,7 +887,10 @@ void ProtocolGame::parsePlayerStats(const InputMessagePtr& msg)
m_localPlayer->setSpeed(msg->getU16()); m_localPlayer->setSpeed(msg->getU16());
if(g_game.getFeature(Otc::GamePlayerRegenerationTime)) 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) void ProtocolGame::parsePlayerSkills(const InputMessagePtr& msg)

View File

@ -21,6 +21,7 @@
*/ */
#include "spritemanager.h" #include "spritemanager.h"
#include "game.h"
#include <framework/core/resourcemanager.h> #include <framework/core/resourcemanager.h>
#include <framework/core/filestream.h> #include <framework/core/filestream.h>
#include <framework/graphics/image.h> #include <framework/graphics/image.h>
@ -49,7 +50,8 @@ bool SpriteManager::loadSpr(const std::string& file)
m_spritesFile->cache(); m_spritesFile->cache();
m_signature = m_spritesFile->getU32(); 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; m_loaded = true;
return true; return true;
} catch(stdext::exception& e) { } catch(stdext::exception& e) {
@ -67,48 +69,70 @@ void SpriteManager::unload()
ImagePtr SpriteManager::getSpriteImage(int id) ImagePtr SpriteManager::getSpriteImage(int id)
{ {
enum { try {
SPRITE_SIZE = 32, enum {
SPRITE_DATA_SIZE = SPRITE_SIZE*SPRITE_SIZE*4 SPRITE_SIZE = 32,
}; SPRITE_DATA_SIZE = SPRITE_SIZE*SPRITE_SIZE*4
};
if(id == 0) if(id == 0 || !m_spritesFile)
return nullptr;
m_spritesFile->seek(((id-1) * 4) + 6);
uint32 spriteAddress = m_spritesFile->getU32();
// no sprite? return an empty texture
if(spriteAddress == 0)
return nullptr;
m_spritesFile->seek(spriteAddress);
// skip color key
m_spritesFile->getU8();
m_spritesFile->getU8();
m_spritesFile->getU8();
uint16 pixelDataSize = m_spritesFile->getU16();
ImagePtr image(new Image(Size(SPRITE_SIZE, SPRITE_SIZE)));
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();
if(writePos + transparentPixels*4 + coloredPixels*3 >= SPRITE_DATA_SIZE) {
g_logger.warning(stdext::format("corrupt sprite id %d", id));
return nullptr; return nullptr;
m_spritesFile->seek(((id-1) * 4) + m_spritesOffset);
uint32 spriteAddress = m_spritesFile->getU32();
// no sprite? return an empty texture
if(spriteAddress == 0)
return nullptr;
m_spritesFile->seek(spriteAddress);
// skip color key
m_spritesFile->getU8();
m_spritesFile->getU8();
m_spritesFile->getU8();
uint16 pixelDataSize = m_spritesFile->getU16();
ImagePtr image(new Image(Size(SPRITE_SIZE, SPRITE_SIZE)));
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();
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 + 0] = 0x00;
pixels[writePos + 1] = 0x00; pixels[writePos + 1] = 0x00;
pixels[writePos + 2] = 0x00; pixels[writePos + 2] = 0x00;
@ -116,27 +140,10 @@ ImagePtr SpriteManager::getSpriteImage(int id)
writePos += 4; writePos += 4;
} }
for(int i = 0; i < coloredPixels; i++) { return image;
pixels[writePos + 0] = m_spritesFile->getU8(); } catch(stdext::exception& e) {
pixels[writePos + 1] = m_spritesFile->getU8(); g_logger.error(stdext::format("Failed to get sprite id %d: %s", id, e.what()));
pixels[writePos + 2] = m_spritesFile->getU8(); return nullptr;
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;
} }