More multiprotocol progress
This commit is contained in:
parent
c8d1d5ecf2
commit
cf9f57736f
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 })
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue