More multiprotocol progress
This commit is contained in:
parent
c8d1d5ecf2
commit
cf9f57736f
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 })
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<int, Otc::LastSkill> m_skillsLevel;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "spritemanager.h"
|
||||
#include "game.h"
|
||||
#include <framework/core/resourcemanager.h>
|
||||
#include <framework/core/filestream.h>
|
||||
#include <framework/graphics/image.h>
|
||||
|
@ -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;
|
||||
|
||||
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));
|
||||
if(id == 0 || !m_spritesFile)
|
||||
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 + 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);
|
||||
return image;
|
||||
} catch(stdext::exception& e) {
|
||||
g_logger.error(stdext::format("Failed to get sprite id %d: %s", id, e.what()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 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