Merge branch 'master' of github.com:edubart/otclient

This commit is contained in:
Eduardo Bart 2011-08-15 06:55:51 -03:00
commit 4e03b15b27
28 changed files with 582 additions and 278 deletions

View File

@ -63,6 +63,8 @@ SET(SOURCES
src/item.cpp src/item.cpp
src/tile.cpp src/tile.cpp
src/thing.cpp src/thing.cpp
src/creature.cpp
src/effect.cpp
# framework third party # framework third party
src/framework/thirdparty/apngloader.cpp src/framework/thirdparty/apngloader.cpp

64
src/creature.cpp Normal file
View File

@ -0,0 +1,64 @@
#include "creature.h"
#include "tibiadat.h"
#include "graphics/graphics.h"
#include <graphics/framebuffer.h>
#include "game.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>
// OW BART TEM COMO USAR 2 FRAMEBUFFER?
// SERIA O IDEAL PARA DESENHAR A COR DOS BONEQUIN.
Creature::Creature()
{
m_type = Thing::TYPE_CREATURE;
}
ThingAttributes *Creature::getAttributes()
{
return g_tibiaDat.getCreatureAttributes(m_outfit.type);
}
void Creature::draw(int x, int y)
{
//ThingAttributes *creatureAttributes = getAttributes();
int anim = 0;
// draw outfit
internalDraw(x, y, 0, m_direction, 0, 0, anim);
// draw addons
//for(int a = 0; a < m_outfit.addons; ++a) {
//internalDraw(x, y, 0, m_direction, m_outfit.addons & (1 << a), 0, anim);
//}
//glPushAttrib(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT);
//glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
//Color colors[4] = {Color::yellow, Color::red, Color::green, Color::blue};
//for(int i = 0; i < 4; ++i) {
/*g_graphics.bindColor(colors[i]);
internalDraw(creatureAttributes->width*32 - 32, creatureAttributes->height*32 - 32, 1, m_direction, 0, 0, 0);
framebuffer.unbind();
g_graphics.bindColor(Color::green);*/
//framebuffer.draw(x, y, creatureAttributes->width*32, creatureAttributes->height*32);
//}
//glPopAttrib();
}

51
src/creature.h Normal file
View File

@ -0,0 +1,51 @@
#ifndef CREATURE_H
#define CREATURE_H
#include <global.h>
#include "thing.h"
struct Outfit
{
uint16 type;
uint8 head;
uint8 body;
uint8 legs;
uint8 feet;
uint8 addons;
};
class Creature;
typedef std::shared_ptr<Creature> CreaturePtr;
class Creature : public Thing
{
public:
Creature();
virtual ThingAttributes *getAttributes();
void draw(int x, int y);
void setName(const std::string& name) { m_name = name; }
std::string getName() { return m_name; }
void setHealthPercent(uint8 healthPercent) { m_healthPercent = healthPercent; }
uint8 getHealthPercent() { return m_healthPercent; }
void setDirection(Direction direction) { m_direction = direction; }
Direction getDirection() { return m_direction; }
void setOutfit(const Outfit& outfit) { m_outfit = outfit; }
Outfit getOutfit() { return m_outfit; }
virtual Creature *getCreature() { return this; }
virtual const Creature *getCreature() const { return this; }
private:
std::string m_name;
uint8 m_healthPercent;
Direction m_direction;
Outfit m_outfit;
};
#endif // CREATURE_H

18
src/effect.cpp Normal file
View File

@ -0,0 +1,18 @@
#include "effect.h"
#include "tibiadat.h"
Effect::Effect()
{
m_type = Thing::TYPE_EFFECT;
}
ThingAttributes *Effect::getAttributes()
{
return g_tibiaDat.getEffectAttributes(m_id);
}
void Effect::draw(int x, int y)
{
int anim = 0;
internalDraw(x, y, 0, 0, 0, 0, anim);
}

21
src/effect.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef EFFECT_H
#define EFFECT_H
#include <global.h>
#include "thing.h"
class Effect;
typedef std::shared_ptr<Effect> EffectPtr;
class Effect : public Thing
{
public:
Effect();
virtual ThingAttributes *getAttributes();
void draw(int x, int y);
private:
};
#endif // EFFECT_H

View File

@ -11,6 +11,11 @@ Connection::Connection() :
{ {
} }
Connection::~Connection()
{
disconnect();
}
void Connection::poll() void Connection::poll()
{ {
ioService.poll(); ioService.poll();
@ -28,6 +33,11 @@ void Connection::connect(const std::string& host, uint16 port, const ConnectCall
m_timer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1)); m_timer.async_wait(std::bind(&Connection::onTimeout, shared_from_this(), std::placeholders::_1));
} }
void Connection::disconnect()
{
m_socket.close();
}
void Connection::send(uint8* buffer, uint16 size) void Connection::send(uint8* buffer, uint16 size)
{ {
asio::async_write(m_socket, asio::async_write(m_socket,

View File

@ -11,10 +11,12 @@ class Connection : public std::enable_shared_from_this<Connection>, boost::nonco
public: public:
Connection(); Connection();
~Connection();
static void poll(); static void poll();
void connect(const std::string& host, uint16 port, const ConnectCallback& connectCallback); void connect(const std::string& host, uint16 port, const ConnectCallback& connectCallback);
void disconnect();
void send(uint8* buffer, uint16 size); void send(uint8* buffer, uint16 size);
void recv(uint16 bytes, uint32 timeout, const RecvCallback& callback); void recv(uint16 bytes, uint32 timeout, const RecvCallback& callback);

View File

@ -1,9 +1,10 @@
#include "color.h" #include "color.h"
Color Color::white(0xFF, 0xFF, 0xFF, 0xFF); Color Color::white (0xFF, 0xFF, 0xFF, 0xFF);
Color Color::black(0x00, 0x00, 0x00, 0xFF); Color Color::black (0x00, 0x00, 0x00, 0xFF);
Color Color::alpha(0x00, 0x00, 0x00, 0x00); Color Color::alpha (0x00, 0x00, 0x00, 0x00);
Color Color::red (0xFF, 0x00, 0x00, 0xFF); Color Color::red (0xFF, 0x00, 0x00, 0xFF);
Color Color::green(0x00, 0xFF, 0x00, 0xFF); Color Color::green (0x00, 0xFF, 0x00, 0xFF);
Color Color::blue (0x00, 0x00, 0xFF, 0xFF); Color Color::blue (0x00, 0x00, 0xFF, 0xFF);
Color Color::pink (0xFF, 0x00, 0xFF, 0xFF); Color Color::pink (0xFF, 0x00, 0xFF, 0xFF);
Color Color::yellow(0x00, 0xFF, 0xFF, 0xFF);

View File

@ -39,6 +39,7 @@ public:
static Color green; static Color green;
static Color blue; static Color blue;
static Color pink; static Color pink;
static Color yellow;
private: private:
RGBA color; RGBA color;

View File

@ -1,3 +1,8 @@
#include "game.h" #include "game.h"
Game g_game; Game g_game;
Game::Game()
{
m_online = false;
}

View File

@ -9,17 +9,22 @@
class Game class Game
{ {
public: public:
Game();
void setProtocol(ProtocolGame *protocolGame) { m_protocolGame = protocolGame; } void setProtocol(ProtocolGamePtr protocolGame) { m_protocolGame = protocolGame; }
ProtocolGame *getProtocol() { return m_protocolGame; } ProtocolGamePtr getProtocol() { return m_protocolGame; }
Map *getMap() { return &m_map; } Map *getMap() { return &m_map; }
Player *getPlayer() { return &m_player; } Player *getPlayer() { return &m_player; }
void setOnline(bool online) { m_online = online; }
bool getOnline() { return m_online; }
private: private:
Map m_map; Map m_map;
Player m_player; Player m_player;
ProtocolGame *m_protocolGame; ProtocolGamePtr m_protocolGame;
bool m_online;
}; };

View File

@ -2,96 +2,34 @@
#include "tibiadat.h" #include "tibiadat.h"
#include "tibiaspr.h" #include "tibiaspr.h"
#include <graphics/graphics.h> #include <graphics/graphics.h>
#include "thing.h"
ItemAttributes::ItemAttributes()
{
group = ITEM_GROUP_NONE;
blockSolid = false;
hasHeight = false;
blockPathFind = false;
blockProjectile = false;
alwaysOnTop = false;
alwaysOnTopOrder = 0;
stackable = false;
useable = false;
moveable = true;
pickupable = false;
rotable = false;
readable = false;
lookThrough = false;
speed = 0;
lightLevel = 0;
lightColor = 0;
isVertical = false;
isHorizontal = false;
isHangable = false;
miniMapColor = 0;
hasMiniMapColor = false;
subParam07 = 0;
subParam08 = 0;
sprites = NULL;
width = 0;
height = 0;
blendframes = 0;
xdiv = 0;
ydiv = 0;
zdiv = 0;
animcount = 0;
}
ItemAttributes::~ItemAttributes()
{
if(sprites)
delete []sprites;
}
Item::Item() Item::Item()
{ {
m_type = Thing::TYPE_ITEM; m_type = Thing::TYPE_ITEM;
} }
void Item::draw(int x, int y, int z) ThingAttributes *Item::getAttributes()
{ {
ItemAttributes *itemAttributes = g_tibiaDat.getItemAttributes(m_id); return g_tibiaDat.getItemAttributes(m_id);
}
int cDivX = 0, cDivY = 0, cDivZ = 0, cAnim = 0; void Item::draw(int x, int y)
{
ThingAttributes *itemAttributes = getAttributes();
if(itemAttributes->group == ITEM_GROUP_SPLASH || itemAttributes->group == ITEM_GROUP_FLUID || itemAttributes->stackable) { int xdiv = 0, ydiv = 0, zdiv = 0, anim = 0;
if(itemAttributes->group == THING_GROUP_SPLASH || itemAttributes->group == THING_GROUP_FLUID || itemAttributes->stackable) {
//cDivX = subType % itemAttributes->xdiv; //cDivX = subType % itemAttributes->xdiv;
//cDivY = subType / itemAttributes->xdiv; //cDivY = subType / itemAttributes->xdiv;
} }
else if(!itemAttributes->moveable) { else if(!itemAttributes->moveable) {
cDivX = x % itemAttributes->xdiv; xdiv = m_position.x % itemAttributes->xdiv;
cDivY = y % itemAttributes->ydiv; ydiv = m_position.y % itemAttributes->ydiv;
cDivZ = z % itemAttributes->zdiv; zdiv = m_position.z % itemAttributes->zdiv;
} }
x *= 32; for(int b = 0; b < itemAttributes->blendframes; b++)
y *= 32; internalDraw(x, y, b, xdiv, ydiv, zdiv, anim);
z = (7-z)*32;
for(int b = 0; b < itemAttributes->blendframes; b++) {
for(int yi = 0; yi < itemAttributes->height; yi++) {
for(int xi = 0; xi < itemAttributes->width; xi++) {
uint16 sprIndex = xi +
yi * itemAttributes->width +
b * itemAttributes->width * itemAttributes->height +
cDivX * itemAttributes->width * itemAttributes->height * itemAttributes->blendframes +
cDivY * itemAttributes->width * itemAttributes->height * itemAttributes->blendframes * itemAttributes->xdiv +
cDivZ * itemAttributes->width * itemAttributes->height * itemAttributes->blendframes * itemAttributes->xdiv * itemAttributes->ydiv +
cAnim * itemAttributes->width * itemAttributes->height * itemAttributes->blendframes * itemAttributes->xdiv * itemAttributes->ydiv * itemAttributes->zdiv;
uint16 itemId = itemAttributes->sprites[sprIndex];
if(itemId == 0xFFFF)
continue;
TexturePtr data = g_tibiaSpr.getSprite(itemId);
// todo verify this to draw in correct pos (screenX, screenY)
g_graphics.drawTexturedRect(Rect(x - xi*32 - z, y - yi*32 - z, 32, 32), data, Rect(0, 0, 32, 32));
//g_graphics.drawBoundingRect(Rect(x - xi*32 - z, y - yi*32 - z, 32, 32), Color::green);
if(x/32 == 7 && y/32 == 5 && z/32+7 == 7)
g_graphics.drawBoundingRect(Rect(x - xi*32 - z, y - yi*32 - z, 32, 32), Color::red);
}
}
}
} }

View File

@ -4,47 +4,16 @@
#include <global.h> #include <global.h>
#include "thing.h" #include "thing.h"
enum ItemGroup { class Item;
ITEM_GROUP_NONE = 0, typedef std::shared_ptr<Item> ItemPtr;
ITEM_GROUP_GROUND,
ITEM_GROUP_CONTAINER,
ITEM_GROUP_WEAPON,
ITEM_GROUP_AMMUNITION,
ITEM_GROUP_ARMOR,
ITEM_GROUP_RUNE,
ITEM_GROUP_TELEPORT,
ITEM_GROUP_MAGICFIELD,
ITEM_GROUP_WRITEABLE,
ITEM_GROUP_KEY,
ITEM_GROUP_SPLASH,
ITEM_GROUP_FLUID,
ITEM_GROUP_DOOR,
ITEM_GROUP_LAST
};
class ItemAttributes class Item : public Thing
{
public:
ItemAttributes();
~ItemAttributes();
bool stackable, alwaysOnTop, useable, readable, moveable, blockSolid, blockProjectile, blockPathFind, pickupable,
isHangable, isHorizontal, isVertical, rotable, hasHeight, lookThrough, hasMiniMapColor;
uint8 alwaysOnTopOrder, width, height, blendframes, xdiv, ydiv, zdiv, animcount;
uint16 id, speed, subParam07, subParam08, lightLevel, lightColor, uheight, miniMapColor;
uint16 *sprites;
ItemGroup group;
};
class Item : virtual public Thing
{ {
public: public:
Item(); Item();
void draw(int x, int y, int z); virtual ThingAttributes *getAttributes();
void draw(int x, int y);
void setId(uint16 id) { m_id = id; }
uint16 getId() const { return m_id; }
void setCount(uint8 count) { m_count = count; } void setCount(uint8 count) { m_count = count; }
@ -52,8 +21,7 @@ public:
virtual const Item* getItem() const { return this; } virtual const Item* getItem() const { return this; }
private: private:
uint16 m_id;
uint8 m_count; uint8 m_count;
}; };
#endif #endif // ITEM_H

View File

@ -17,41 +17,59 @@ void Map::draw(int x, int y)
if(playerPos->z <= 7) { if(playerPos->z <= 7) {
// player pos it 8-6. check if we can draw upper floors. // player pos it 8-6. check if we can draw upper floors.
/*bool draw = true; bool draw = true;
for(int jz = 6; jz >= 0; --jz) { for(int jz = 6; jz >= 0; --jz) {
if(m_tiles[Position(8+(6-jz), 6+(6-jz), jz)]->getStackSize() > 0) { Position coverPos = Position(playerPos->x-(6-jz), playerPos->y-(6-jz), jz);
if(m_tiles[coverPos]) {
if(m_tiles[coverPos]->getStackSize() > 0 && jz < playerPos->z) {
draw = false; draw = false;
} }
}*/ }
}
for(int iz = 7; iz > 0; --iz) { for(int iz = 7; iz > 0; --iz) {
// +1 in draws cause 64x64 items may affect view. // +1 in draws cause 64x64 items may affect view.
for(int ix = - 8; ix < + 8; ++ix) { for(int ix = -7; ix < + 8+7; ++ix) {
for(int iy = - 6; iy < + 6; ++iy) { for(int iy = -5; iy < + 6+7; ++iy) {
Position relativePos = Position(playerPos->x + ix, playerPos->y + iy, iz); Position itemPos = Position(playerPos->x + ix, playerPos->y + iy, iz);
//Position drawPos = Position(ix + 8, iy - playerPos->y + 6, iz); //Position drawPos = Position(ix + 8, iy - playerPos->y + 6, iz);
//logDebug("x: ", relativePos.x, " y: ", relativePos.y, " z: ", (int)relativePos.z); //logDebug("x: ", relativePos.x, " y: ", relativePos.y, " z: ", (int)relativePos.z);
if(m_tiles.find(relativePos) != m_tiles.end()) if(m_tiles[itemPos])
m_tiles[relativePos]->draw(ix + 8, iy + 6, iz); m_tiles[itemPos]->draw((ix + 7 - (7-iz))*32, (iy + 5 - (7-iz))*32);
} }
} }
//if(!draw) if(!draw)
//break; break;
} }
} }
// draw effects
for(auto it = m_effects.begin(), end = m_effects.end(); it != end; ++it) {
Position *effectPos = (*it)->getPosition();
(*it)->draw((effectPos->x - playerPos->x + 7) * 32, (effectPos->y - playerPos->y + 5) * 32);
}
// debug draws
g_graphics.drawBoundingRect(Rect(7*32, 5*32, 32, 32), Color::red);
m_framebuffer->unbind(); m_framebuffer->unbind();
m_framebuffer->draw(x, y, g_graphics.getScreenSize().width(), g_graphics.getScreenSize().height()); m_framebuffer->draw(x, y, g_graphics.getScreenSize().width(), g_graphics.getScreenSize().height());
} }
void Map::addThing(Thing *thing, const Position& pos) void Map::addThing(ThingPtr thing, uint8 stackpos)
{ {
if(m_tiles.find(pos) == m_tiles.end()) { if(thing->getType() == Thing::TYPE_ITEM || thing->getType() == Thing::TYPE_CREATURE) {
m_tiles[pos] = TilePtr(new Tile()); if(!m_tiles[*thing->getPosition()]) {
m_tiles[*thing->getPosition()] = TilePtr(new Tile());
}
m_tiles[*thing->getPosition()]->addThing(thing, stackpos);
}
else if(thing->getType() == Thing::TYPE_EFFECT) {
m_effects.push_back(thing);
} }
m_tiles[pos]->addThing(thing);
} }

View File

@ -3,18 +3,22 @@
#include "position.h" #include "position.h"
#include "tile.h" #include "tile.h"
#include "effect.h"
#include <graphics/graphicsdeclarations.h> #include <graphics/graphicsdeclarations.h>
#include <unordered_map> #include <unordered_map>
class Map class Map
{ {
public: public:
void addThing(Thing *thing, const Position& pos); void addThing(ThingPtr thing, uint8 stackpos = 0);
void draw(int x, int y); void draw(int x, int y);
FrameBufferPtr getFramebuffer() { return m_framebuffer; }
private: private:
std::unordered_map<Position, TilePtr, PositionHash> m_tiles; std::unordered_map<Position, TilePtr, PositionHash> m_tiles;
std::list<ThingPtr> m_effects;
FrameBufferPtr m_framebuffer; FrameBufferPtr m_framebuffer;
}; };

View File

@ -199,6 +199,7 @@ void OTClient::poll()
void OTClient::render() void OTClient::render()
{ {
if(g_game.getOnline())
g_game.getMap()->draw(0, 0); g_game.getMap()->draw(0, 0);
// everything is rendered by UI components // everything is rendered by UI components
@ -261,7 +262,7 @@ void OTClient::onInputEvent(const InputEvent& event)
{ {
g_ui.inputEvent(event); g_ui.inputEvent(event);
ProtocolGame *protocol = g_game.getProtocol(); ProtocolGamePtr protocol = g_game.getProtocol();
if(protocol) { if(protocol) {
if(event.type == EventKeyDown) { if(event.type == EventKeyDown) {
if(event.keycode == KC_UP) if(event.keycode == KC_UP)

View File

@ -1,17 +1,22 @@
#ifndef PLAYER_H #ifndef PLAYER_H
#define PLAYER_H #define PLAYER_H
#include "position.h" #include "creature.h"
class Player class Player : public Creature
{ {
public: public:
void setDrawSpeed(uint16 drawSpeed) { m_drawSpeed = drawSpeed; }
uint16 getDrawSpeed() { return m_drawSpeed; }
void setPosition(const Position& position) { m_position = position; } void setCanReportBugs(uint8 canReportBugs) { m_canReportBugs = (canReportBugs != 0); }
Position *getPosition() { return &m_position; } bool getCanReportBugs() { return m_canReportBugs; }
private: private:
Position m_position;
uint16 m_drawSpeed;
bool m_canReportBugs;
}; };
#endif #endif

View File

@ -3,6 +3,14 @@
#include <global.h> #include <global.h>
enum Direction
{
DIRECTION_NORTH,
DIRECTION_EAST,
DIRECTION_SOUTH,
DIRECTION_WEST
};
class Position class Position
{ {
public: public:

View File

@ -5,11 +5,12 @@
ProtocolGame::ProtocolGame() ProtocolGame::ProtocolGame()
{ {
m_checksumEnabled = false; m_checksumEnabled = false;
g_game.setProtocol(this); g_game.setProtocol(ProtocolGamePtr(this));
} }
ProtocolGame::~ProtocolGame() ProtocolGame::~ProtocolGame()
{ {
sendLogout();
g_game.setProtocol(NULL); g_game.setProtocol(NULL);
} }

View File

@ -3,7 +3,7 @@
#include <net/protocol.h> #include <net/protocol.h>
#include "player.h" #include "player.h"
#include "thing.h" #include "item.h"
class ProtocolGame; class ProtocolGame;
typedef std::shared_ptr<ProtocolGame> ProtocolGamePtr; typedef std::shared_ptr<ProtocolGame> ProtocolGamePtr;
@ -22,6 +22,7 @@ public:
void onRecv(InputMessage& inputMessage); void onRecv(InputMessage& inputMessage);
// Send Messages // Send Messages
void sendLogout();
void sendPing(); void sendPing();
void sendWalkNorth(); void sendWalkNorth();
void sendWalkEast(); void sendWalkEast();
@ -73,6 +74,7 @@ private:
void parseCreatureSpeed(InputMessage& msg); void parseCreatureSpeed(InputMessage& msg);
void parseCreatureSkulls(InputMessage& msg); void parseCreatureSkulls(InputMessage& msg);
void parseCreatureShields(InputMessage& msg); void parseCreatureShields(InputMessage& msg);
void parseCreatureTurn(InputMessage& msg);
void parseItemTextWindow(InputMessage& msg); void parseItemTextWindow(InputMessage& msg);
void parseHouseTextWindow(InputMessage& msg); void parseHouseTextWindow(InputMessage& msg);
void parsePlayerStats(InputMessage& msg); void parsePlayerStats(InputMessage& msg);
@ -107,9 +109,9 @@ private:
void setMapDescription(InputMessage& msg, int32 x, int32 y, int32 z, int32 width, int32 height); void setMapDescription(InputMessage& msg, int32 x, int32 y, int32 z, int32 width, int32 height);
void setFloorDescription(InputMessage& msg, int32 x, int32 y, int32 z, int32 width, int32 height, int32 offset, int32* skipTiles); void setFloorDescription(InputMessage& msg, int32 x, int32 y, int32 z, int32 width, int32 height, int32 offset, int32* skipTiles);
void setTileDescription(InputMessage& msg, Position position); void setTileDescription(InputMessage& msg, Position position);
Thing *internalGetThing(InputMessage& msg); ThingPtr internalGetThing(InputMessage& msg);
void internalCreatureOutfit(InputMessage& msg); Outfit internalCreatureOutfit(InputMessage& msg);
Item *internalGetItem(InputMessage& msg, uint16 id); ItemPtr internalGetItem(InputMessage& msg, uint16 id);
Position parsePosition(InputMessage& msg); Position parsePosition(InputMessage& msg);

View File

@ -3,6 +3,7 @@
#include "tibiadat.h" #include "tibiadat.h"
#include "game.h" #include "game.h"
#include "map.h" #include "map.h"
#include "effect.h"
#include <iomanip> #include <iomanip>
void ProtocolGame::parseMessage(InputMessage& msg) void ProtocolGame::parseMessage(InputMessage& msg)
@ -235,9 +236,12 @@ void ProtocolGame::parseMessage(InputMessage& msg)
void ProtocolGame::parsePlayerLogin(InputMessage& msg) void ProtocolGame::parsePlayerLogin(InputMessage& msg)
{ {
msg.getU32(); // player id Player *player = g_game.getPlayer();
msg.getU16(); // drawing speed. player->setId(msg.getU32());
msg.getU8(); // can report bugs player->setDrawSpeed(msg.getU16());
player->setCanReportBugs(msg.getU8());
g_game.setOnline(true);
} }
void ProtocolGame::parseGMActions(InputMessage& msg) void ProtocolGame::parseGMActions(InputMessage& msg)
@ -248,7 +252,8 @@ void ProtocolGame::parseGMActions(InputMessage& msg)
void ProtocolGame::parseErrorMessage(InputMessage& msg) void ProtocolGame::parseErrorMessage(InputMessage& msg)
{ {
msg.getString(); // message std::string error = msg.getString();
callLuaField("onError", error);
} }
void ProtocolGame::parseFYIMessage(InputMessage& msg) void ProtocolGame::parseFYIMessage(InputMessage& msg)
@ -280,12 +285,7 @@ void ProtocolGame::parseCanReportBugs(InputMessage& msg)
void ProtocolGame::parseMapDescription(InputMessage& msg) void ProtocolGame::parseMapDescription(InputMessage& msg)
{ {
Player *player = g_game.getPlayer(); Player *player = g_game.getPlayer();
player->setPosition(parsePosition(msg));
Position playerPos = parsePosition(msg);
logDebug("x: ", playerPos.x, " y: ", playerPos.y, " z: ", (int)playerPos.z);
player->setPosition(playerPos);
logDebug("x: ", player->getPosition()->x, " y: ", player->getPosition()->y, " z: ", (int)player->getPosition()->z);
setMapDescription(msg, player->getPosition()->x - 8, player->getPosition()->y - 6, player->getPosition()->z, 18, 14); setMapDescription(msg, player->getPosition()->x - 8, player->getPosition()->y - 6, player->getPosition()->z, 18, 14);
} }
@ -462,8 +462,11 @@ void ProtocolGame::parseWorldLight(InputMessage& msg)
void ProtocolGame::parseMagicEffect(InputMessage& msg) void ProtocolGame::parseMagicEffect(InputMessage& msg)
{ {
parsePosition(msg); // effect pos EffectPtr effect = EffectPtr(new Effect());
msg.getU8(); // effect effect->setPosition(parsePosition(msg));
effect->setId(msg.getU8());
g_game.getMap()->addThing(effect);
} }
void ProtocolGame::parseAnimatedText(InputMessage& msg) void ProtocolGame::parseAnimatedText(InputMessage& msg)
@ -523,6 +526,12 @@ void ProtocolGame::parseCreatureShields(InputMessage& msg)
msg.getU8(); // shield msg.getU8(); // shield
} }
void ProtocolGame::parseCreatureTurn(InputMessage& msg)
{
msg.getU32(); // creature id
msg.getU8(); // direction
}
void ProtocolGame::parseItemTextWindow(InputMessage& msg) void ProtocolGame::parseItemTextWindow(InputMessage& msg)
{ {
msg.getU32(); // windowId msg.getU32(); // windowId
@ -828,43 +837,48 @@ void ProtocolGame::setFloorDescription(InputMessage& msg, int32 x, int32 y, int3
void ProtocolGame::setTileDescription(InputMessage& msg, Position position) void ProtocolGame::setTileDescription(InputMessage& msg, Position position)
{ {
int n = 0; int stackpos = 0;
while(1){ while(1){
n++; stackpos++;
uint16 inspectTileId = msg.getU16(true); uint16 inspectTileId = msg.getU16(true);
if(inspectTileId >= 0xFF00) if(inspectTileId >= 0xFF00)
return; return;
else { else {
if(n > 10) { if(stackpos > 10) {
logDebug("[ProtocolGame::setTileDescription] Too many things!."); logDebug("[ProtocolGame::setTileDescription] Too many things!.");
return; return;
} }
g_game.getMap()->addThing(internalGetThing(msg), position); ThingPtr thing = internalGetThing(msg);
if(thing)
thing->setPosition(position);
g_game.getMap()->addThing(thing, stackpos);
} }
} }
} }
Thing *ProtocolGame::internalGetThing(InputMessage& msg) ThingPtr ProtocolGame::internalGetThing(InputMessage& msg)
{ {
Thing *thing = NULL; ThingPtr thing;
uint16 thingId = msg.getU16(); uint16 thingId = msg.getU16();
if(thingId == 0x0061 || thingId == 0x0062) { // add new creature if(thingId == 0x0061 || thingId == 0x0062) { // add new creature
CreaturePtr creature = CreaturePtr(new Creature);
if(thingId == 0x0062) { //creature is known if(thingId == 0x0062) { //creature is known
msg.getU32(); // creature id creature->setId(msg.getU32());
} }
else if(thingId == 0x0061) { //creature is not known else if(thingId == 0x0061) { //creature is not known
msg.getU32(); // remove id msg.getU32(); // remove id
msg.getU32(); // creature id creature->setId(msg.getU32());
msg.getString(); // creature name creature->setName(msg.getString());
} }
msg.getU8(); // hp creature->setHealthPercent(msg.getU8());
msg.getU8(); // direction creature->setDirection((Direction)msg.getU8());
internalCreatureOutfit(msg); creature->setOutfit(internalCreatureOutfit(msg));
msg.getU8(); // level msg.getU8(); // light level
msg.getU8(); // color msg.getU8(); // light color
msg.getU16(); // speed msg.getU16(); // speed
msg.getU8(); // skull msg.getU8(); // skull
msg.getU8(); // shield msg.getU8(); // shield
@ -873,10 +887,11 @@ Thing *ProtocolGame::internalGetThing(InputMessage& msg)
msg.getU8(); msg.getU8();
msg.getU8(); // impassable msg.getU8(); // impassable
thing = creature;
} }
else if(thingId == 0x0063) { // creature turn else if(thingId == 0x0063) { // creature turn
msg.getU32(); // creature id parseCreatureTurn(msg);
msg.getU8(); // direction
} }
else // item else // item
thing = internalGetItem(msg, thingId); thing = internalGetItem(msg, thingId);
@ -884,31 +899,35 @@ Thing *ProtocolGame::internalGetThing(InputMessage& msg)
return thing; return thing;
} }
void ProtocolGame::internalCreatureOutfit(InputMessage& msg) Outfit ProtocolGame::internalCreatureOutfit(InputMessage& msg)
{ {
uint16 lookType = msg.getU16(); // looktype Outfit outfit;
if(lookType != 0) {
msg.getU8(); // lookhead outfit.type = msg.getU16(); // looktype
msg.getU8(); // lookbody if(outfit.type != 0) {
msg.getU8(); // looklegs outfit.head = msg.getU8();
msg.getU8(); // lookfeet outfit.body = msg.getU8();
msg.getU8(); // lookaddons outfit.legs = msg.getU8();
outfit.feet = msg.getU8();
outfit.addons = msg.getU8();
} }
else { else {
msg.getU16(); // looktype outfit.type = msg.getU16();
} }
return outfit;
} }
Item *ProtocolGame::internalGetItem(InputMessage& msg, uint16 id) ItemPtr ProtocolGame::internalGetItem(InputMessage& msg, uint16 id)
{ {
Item *item = new Item(); ItemPtr item = ItemPtr(new Item());
if(id == 0xFFFF) if(id == 0xFFFF)
id = msg.getU16(); id = msg.getU16();
item->setId(id); item->setId(id);
ItemAttributes *itemAttributes = g_tibiaDat.getItemAttributes(id); ThingAttributes *itemAttributes = g_tibiaDat.getItemAttributes(id);
if(itemAttributes->stackable || itemAttributes->group == ITEM_GROUP_FLUID || itemAttributes->group == ITEM_GROUP_SPLASH) if(itemAttributes->stackable || itemAttributes->group == THING_GROUP_FLUID || itemAttributes->group == THING_GROUP_SPLASH)
item->setCount(msg.getU8()); item->setCount(msg.getU8());
return item; return item;

View File

@ -1,5 +1,12 @@
#include "protocolgame.h" #include "protocolgame.h"
void ProtocolGame::sendLogout()
{
OutputMessage oMsg;
oMsg.addU8(0x14);
send(oMsg);
}
void ProtocolGame::sendPing() void ProtocolGame::sendPing()
{ {
OutputMessage oMsg; OutputMessage oMsg;

View File

@ -1,6 +1,83 @@
#include "thing.h" #include "thing.h"
#include "tibiaspr.h"
#include <graphics/graphics.h>
ThingAttributes::ThingAttributes()
{
group = THING_GROUP_NONE;
blockSolid = false;
hasHeight = false;
blockPathFind = false;
blockProjectile = false;
alwaysOnTop = false;
alwaysOnTopOrder = 0;
stackable = false;
useable = false;
moveable = true;
pickupable = false;
rotable = false;
readable = false;
lookThrough = false;
speed = 0;
lightLevel = 0;
lightColor = 0;
isVertical = false;
isHorizontal = false;
isHangable = false;
miniMapColor = 0;
hasMiniMapColor = false;
subParam07 = 0;
subParam08 = 0;
sprites = NULL;
width = 0;
height = 0;
blendframes = 0;
xdiv = 0;
ydiv = 0;
zdiv = 0;
animcount = 0;
xOffset = 0;
yOffset = 0;
}
ThingAttributes::~ThingAttributes()
{
if(sprites)
delete []sprites;
}
Thing::Thing() Thing::Thing()
{ {
m_type = TYPE_NONE; m_type = TYPE_NONE;
} }
void Thing::internalDraw(int x, int y, int blendframes, int xdiv, int ydiv, int zdiv, int anim)
{
ThingAttributes *thingAttributes = getAttributes();
if(!thingAttributes)
return;
for(int yi = 0; yi < thingAttributes->height; yi++) {
for(int xi = 0; xi < thingAttributes->width; xi++) {
uint16 sprIndex = xi +
yi * thingAttributes->width +
blendframes * thingAttributes->width * thingAttributes->height +
xdiv * thingAttributes->width * thingAttributes->height * thingAttributes->blendframes +
ydiv * thingAttributes->width * thingAttributes->height * thingAttributes->blendframes * thingAttributes->xdiv +
zdiv * thingAttributes->width * thingAttributes->height * thingAttributes->blendframes * thingAttributes->xdiv * thingAttributes->ydiv +
anim * thingAttributes->width * thingAttributes->height * thingAttributes->blendframes * thingAttributes->xdiv * thingAttributes->ydiv * thingAttributes->zdiv;
uint16 itemId = thingAttributes->sprites[sprIndex];
if(itemId == 0xFFFF)
continue;
TexturePtr data = g_tibiaSpr.getSprite(itemId);
int offsetX = 0, offsetY = 0;
if(thingAttributes->hasHeight) {
offsetX = thingAttributes->xOffset;
offsetY = thingAttributes->xOffset; // << look to xoffset
}
g_graphics.drawTexturedRect(Rect((x - xi*32) - offsetX, (y - yi*32) - offsetY, 32, 32), data, Rect(0, 0, 32, 32));
}
}
}

View File

@ -2,9 +2,45 @@
#define THING_H #define THING_H
#include <global.h> #include <global.h>
#include "position.h"
enum ThingAttributesGroup {
THING_GROUP_NONE = 0,
THING_GROUP_GROUND,
THING_GROUP_CONTAINER,
THING_GROUP_WEAPON,
THING_GROUP_AMMUNITION,
THING_GROUP_ARMOR,
THING_GROUP_RUNE,
THING_GROUP_TELEPORT,
THING_GROUP_MAGICFIELD,
THING_GROUP_WRITEABLE,
THING_GROUP_KEY,
THING_GROUP_SPLASH,
THING_GROUP_FLUID,
THING_GROUP_DOOR,
THING_GROUP_LAST
};
struct ThingAttributes
{
ThingAttributes();
~ThingAttributes();
bool stackable, alwaysOnTop, useable, readable, moveable, blockSolid, blockProjectile, blockPathFind, pickupable,
isHangable, isHorizontal, isVertical, rotable, hasHeight, lookThrough, hasMiniMapColor;
uint8 alwaysOnTopOrder, width, height, blendframes, xdiv, ydiv, zdiv, animcount, xOffset, yOffset;
uint16 id, speed, subParam07, subParam08, lightLevel, lightColor, miniMapColor;
uint16 *sprites;
ThingAttributesGroup group;
};
class Creature;
class Item; class Item;
class Thing;
typedef std::shared_ptr<Thing> ThingPtr;
class Thing class Thing
{ {
public: public:
@ -13,19 +49,35 @@ public:
enum Type { enum Type {
TYPE_NONE, TYPE_NONE,
TYPE_ITEM, TYPE_ITEM,
TYPE_CREATURE TYPE_CREATURE,
TYPE_EFFECT,
TYPE_SHOT
}; };
void setId(uint32 id) { m_id = id; }
uint32 getId() { return m_id; }
void setType(Type type) { m_type = type; } void setType(Type type) { m_type = type; }
Type getType() const { return m_type; } Type getType() const { return m_type; }
virtual void draw(int, int, int) {} void setPosition(const Position& position) { m_position = position; }
Position *getPosition() { return &m_position; }
virtual void draw(int, int) {}
virtual ThingAttributes *getAttributes() { return NULL; }
virtual Item* getItem() { return NULL; } virtual Item* getItem() { return NULL; }
virtual const Item *getItem() const { return NULL; } virtual const Item *getItem() const { return NULL; }
virtual Creature *getCreature() { return NULL; }
virtual const Creature *getCreature() const { return NULL; }
protected: protected:
void internalDraw(int x, int y, int blendframes, int xdiv, int ydiv, int zdiv, int anim);
uint32 m_id;
Type m_type; Type m_type;
Position m_position;
}; };
#endif // THING_H #endif // THING_H

View File

@ -20,17 +20,17 @@ bool TibiaDat::load(const std::string& filename)
m_totalCount = m_groupCount[0] + m_groupCount[1] + m_groupCount[2] + m_groupCount[3]; m_totalCount = m_groupCount[0] + m_groupCount[1] + m_groupCount[2] + m_groupCount[3];
m_itemsAttributes = new ItemAttributes*[m_totalCount+1]; m_thingsAttributes = new ThingAttributes*[m_totalCount+1];
for(uint16 i = 0; i <= m_totalCount; i++) for(uint16 i = 0; i <= m_totalCount; i++)
m_itemsAttributes[i] = NULL; m_thingsAttributes[i] = NULL;
uint8 read_byte; uint8 read_byte;
uint16 read_short; uint16 read_short;
uint32 read_long; //uint32 read_long;
for(uint16 id = 0; (id <= m_totalCount) && !fin.eof(); id++) { for(uint16 id = 0; (id <= m_totalCount) && !fin.eof(); id++) {
m_itemsAttributes[id] = new ItemAttributes(); m_thingsAttributes[id] = new ThingAttributes();
m_itemsAttributes[id]->id = id; m_thingsAttributes[id]->id = id;
uint8 opt; uint8 opt;
bool done = false; bool done = false;
@ -38,109 +38,116 @@ bool TibiaDat::load(const std::string& filename)
fin.read((char*)&opt, 1); fin.read((char*)&opt, 1);
if(opt == 0x00) { // Ground tile if(opt == 0x00) { // Ground tile
fin.read((char*)&m_itemsAttributes[id]->speed, 2); fin.read((char*)&m_thingsAttributes[id]->speed, 2);
m_itemsAttributes[id]->group = ITEM_GROUP_GROUND; m_thingsAttributes[id]->group = THING_GROUP_GROUND;
} }
else if(opt == 0x01) { // All OnTop else if(opt == 0x01) { // All OnTop
m_itemsAttributes[id]->alwaysOnTop = true; m_thingsAttributes[id]->alwaysOnTop = true;
m_itemsAttributes[id]->alwaysOnTopOrder = 1; m_thingsAttributes[id]->alwaysOnTopOrder = 1;
} }
else if(opt == 0x02) { // Can walk trough (open doors, arces, bug pen fence) else if(opt == 0x02) { // Can walk trough (open doors, arces, bug pen fence)
m_itemsAttributes[id]->alwaysOnTop = true; m_thingsAttributes[id]->alwaysOnTop = true;
m_itemsAttributes[id]->alwaysOnTopOrder = 2; m_thingsAttributes[id]->alwaysOnTopOrder = 2;
} }
else if(opt == 0x03) { // Can walk trough (arces) else if(opt == 0x03) { // Can walk trough (arces)
m_itemsAttributes[id]->alwaysOnTop = true; m_thingsAttributes[id]->alwaysOnTop = true;
m_itemsAttributes[id]->alwaysOnTopOrder = 3; m_thingsAttributes[id]->alwaysOnTopOrder = 3;
} }
else if(opt == 0x04) { // Container else if(opt == 0x04) { // Container
m_itemsAttributes[id]->group = ITEM_GROUP_CONTAINER; m_thingsAttributes[id]->group = THING_GROUP_CONTAINER;
} }
else if(opt == 0x05) { // Stackable else if(opt == 0x05) { // Stackable
m_itemsAttributes[id]->stackable = true; m_thingsAttributes[id]->stackable = true;
} }
else if(opt == 0x06) { // Unknown else if(opt == 0x06) { // Unknown
} }
else if(opt == 0x07) { // Useable else if(opt == 0x07) { // Useable
m_itemsAttributes[id]->useable = true; m_thingsAttributes[id]->useable = true;
} }
else if(opt == 0x08) { // Writtable else if(opt == 0x08) { // Writtable
m_itemsAttributes[id]->group = ITEM_GROUP_WRITEABLE; m_thingsAttributes[id]->group = THING_GROUP_WRITEABLE;
m_itemsAttributes[id]->readable = true; m_thingsAttributes[id]->readable = true;
fin.read((char*)&m_itemsAttributes[id]->subParam07, 2); fin.read((char*)&m_thingsAttributes[id]->subParam07, 2);
} }
else if(opt == 0x09) { // Writtable once else if(opt == 0x09) { // Writtable once
// Writtable objects that can't be edited by players // Writtable objects that can't be edited by players
m_itemsAttributes[id]->readable = true; m_thingsAttributes[id]->readable = true;
fin.read((char*)&m_itemsAttributes[id]->subParam08, 2); fin.read((char*)&m_thingsAttributes[id]->subParam08, 2);
} }
else if(opt == 0x0A) { // Fluid containers else if(opt == 0x0A) { // Fluid containers
fin.read((char*)&read_byte, 1); fin.read((char*)&read_byte, 1);
m_itemsAttributes[id]->group = ITEM_GROUP_FLUID; m_thingsAttributes[id]->group = THING_GROUP_FLUID;
} }
else if(opt == 0x0B) { // Splashes else if(opt == 0x0B) { // Splashes
m_itemsAttributes[id]->group = ITEM_GROUP_SPLASH; m_thingsAttributes[id]->group = THING_GROUP_SPLASH;
} }
else if(opt == 0x0C) { // Blocks solid objects (creatures, walls etc) else if(opt == 0x0C) { // Blocks solid objects (creatures, walls etc)
m_itemsAttributes[id]->blockSolid = true; m_thingsAttributes[id]->blockSolid = true;
} }
else if(opt == 0x0D) { // Not moveable else if(opt == 0x0D) { // Not moveable
m_itemsAttributes[id]->moveable = false; m_thingsAttributes[id]->moveable = false;
} }
else if(opt == 0x0E) { // Blocks missiles (walls, magic wall etc) else if(opt == 0x0E) { // Blocks missiles (walls, magic wall etc)
m_itemsAttributes[id]->blockProjectile = true; m_thingsAttributes[id]->blockProjectile = true;
} }
else if(opt == 0x0F) { // Blocks pathfind algorithms (monsters) else if(opt == 0x0F) { // Blocks pathfind algorithms (monsters)
m_itemsAttributes[id]->blockPathFind = true; m_thingsAttributes[id]->blockPathFind = true;
} }
else if(opt == 0x10) { // Blocks monster movement (flowers, parcels etc) else if(opt == 0x10) { // Blocks monster movement (flowers, parcels etc)
m_itemsAttributes[id]->pickupable = true; m_thingsAttributes[id]->pickupable = true;
} }
else if(opt == 0x11) { // Hangable objects (wallpaper etc) else if(opt == 0x11) { // Hangable objects (wallpaper etc)
m_itemsAttributes[id]->isHangable = true; m_thingsAttributes[id]->isHangable = true;
} }
else if(opt == 0x12) { // Horizontal wall else if(opt == 0x12) { // Horizontal wall
m_itemsAttributes[id]->isHorizontal = true; m_thingsAttributes[id]->isHorizontal = true;
} }
else if(opt == 0x13) { // Vertical wall else if(opt == 0x13) { // Vertical wall
m_itemsAttributes[id]->isVertical = true; m_thingsAttributes[id]->isVertical = true;
} }
else if(opt == 0x14) { // Rotable else if(opt == 0x14) { // Rotable
m_itemsAttributes[id]->rotable = true; m_thingsAttributes[id]->rotable = true;
} }
else if(opt == 0x15) { // Light info else if(opt == 0x15) { // Light info
fin.read((char*)&m_itemsAttributes[id]->lightLevel, 2); fin.read((char*)&m_thingsAttributes[id]->lightLevel, 2);
fin.read((char*)&m_itemsAttributes[id]->lightColor, 2); fin.read((char*)&m_thingsAttributes[id]->lightColor, 2);
} }
else if(opt == 0x16) { else if(opt == 0x16) {
} }
else if(opt == 0x17) { // Changes floor else if(opt == 0x17) { // Changes floor
} }
else if(opt == 0x18) { // Unknown else if(opt == 0x18) { // Thing must be drawed with offset
fin.read((char*)&read_long, 4); m_thingsAttributes[id]->hasHeight = true;
fin.read((char*)&m_thingsAttributes[id]->xOffset, 1);
fin.read((char*)&m_thingsAttributes[id]->yOffset, 1);
fin.read((char*)&read_short, 2);
} }
else if(opt == 0x19) { // Has height else if(opt == 0x19) { // pixels characters height
m_itemsAttributes[id]->hasHeight = true;
fin.read((char*)&m_itemsAttributes[id]->uheight, 2); fin.read((char*)&m_thingsAttributes[id]->xOffset, 1);
fin.read((char*)&m_thingsAttributes[id]->yOffset, 1);
//logDebug((int)m_thingsAttributes[id]->xOffset, " ", (int)m_thingsAttributes[id]->yOffset);
} }
else if(opt == 0x1A) { else if(opt == 0x1A) {
//m_thingsAttributes[id]->hasHeight = true;
} }
else if(opt == 0x1B) { else if(opt == 0x1B) {
} }
else if(opt == 0x1C) { // Minimap color else if(opt == 0x1C) { // Minimap color
fin.read((char*)&m_itemsAttributes[id]->miniMapColor, 2); fin.read((char*)&m_thingsAttributes[id]->miniMapColor, 2);
m_itemsAttributes[id]->hasMiniMapColor = true; m_thingsAttributes[id]->hasMiniMapColor = true;
} }
else if(opt == 0x1D) { // Unknown else if(opt == 0x1D) { // Unknown
fin.read((char*)&read_short, 2); fin.read((char*)&read_short, 2);
if(read_short == 1112) if(read_short == 1112)
m_itemsAttributes[id]->readable = true; m_thingsAttributes[id]->readable = true;
} }
else if(opt == 0x1E) { else if(opt == 0x1E) {
} }
else if(opt == 0x1F) { else if(opt == 0x1F) {
m_itemsAttributes[id]->lookThrough = true; m_thingsAttributes[id]->lookThrough = true;
} }
else if(opt == 0x20) { else if(opt == 0x20) {
} }
@ -153,32 +160,46 @@ bool TibiaDat::load(const std::string& filename)
} }
} }
fin.read((char*)&m_itemsAttributes[id]->width, 1); fin.read((char*)&m_thingsAttributes[id]->width, 1);
fin.read((char*)&m_itemsAttributes[id]->height, 1); fin.read((char*)&m_thingsAttributes[id]->height, 1);
if((m_itemsAttributes[id]->width > 1) || (m_itemsAttributes[id]->height > 1)) if((m_thingsAttributes[id]->width > 1) || (m_thingsAttributes[id]->height > 1))
fin.read((char*)&read_byte, 1); fin.read((char*)&read_byte, 1);
fin.read((char*)&m_itemsAttributes[id]->blendframes, 1); fin.read((char*)&m_thingsAttributes[id]->blendframes, 1);
fin.read((char*)&m_itemsAttributes[id]->xdiv, 1); fin.read((char*)&m_thingsAttributes[id]->xdiv, 1);
fin.read((char*)&m_itemsAttributes[id]->ydiv, 1); fin.read((char*)&m_thingsAttributes[id]->ydiv, 1);
fin.read((char*)&m_itemsAttributes[id]->zdiv, 1); fin.read((char*)&m_thingsAttributes[id]->zdiv, 1);
fin.read((char*)&m_itemsAttributes[id]->animcount, 1); fin.read((char*)&m_thingsAttributes[id]->animcount, 1);
// Read sprites id. // Read sprites id.
uint16 totalSprites = m_itemsAttributes[id]->width * m_itemsAttributes[id]->height * m_itemsAttributes[id]->blendframes * m_itemsAttributes[id]->xdiv * m_itemsAttributes[id]->ydiv * m_itemsAttributes[id]->zdiv * m_itemsAttributes[id]->animcount; uint16 totalSprites = m_thingsAttributes[id]->width * m_thingsAttributes[id]->height * m_thingsAttributes[id]->blendframes * m_thingsAttributes[id]->xdiv * m_thingsAttributes[id]->ydiv * m_thingsAttributes[id]->zdiv * m_thingsAttributes[id]->animcount;
m_itemsAttributes[id]->sprites = new uint16[totalSprites]; m_thingsAttributes[id]->sprites = new uint16[totalSprites];
for(uint16 i = 0; i < totalSprites; i++) { for(uint16 i = 0; i < totalSprites; i++) {
fin.read((char*)&read_short, 2); fin.read((char*)&read_short, 2);
m_itemsAttributes[id]->sprites[i] = read_short-1; m_thingsAttributes[id]->sprites[i] = read_short-1;
} }
} }
return true; return true;
} }
ItemAttributes *TibiaDat::getItemAttributes(uint16 id) ThingAttributes *TibiaDat::getItemAttributes(uint16 id)
{ {
// items id start at 100. return m_thingsAttributes[id - 100];
return m_itemsAttributes[id - 100]; }
ThingAttributes *TibiaDat::getCreatureAttributes(uint16 id)
{
return m_thingsAttributes[id - 1 + m_groupCount[0]];
}
ThingAttributes *TibiaDat::getEffectAttributes(uint16 id)
{
return m_thingsAttributes[id - 1 + m_groupCount[0] + m_groupCount[1]];
}
ThingAttributes *TibiaDat::getShotAttributes(uint16 id)
{
return m_thingsAttributes[id - 100 + m_groupCount[0] + m_groupCount[1] + m_groupCount[2]];
} }

View File

@ -2,14 +2,17 @@
#define TIBIADAT_H #define TIBIADAT_H
#include <global.h> #include <global.h>
#include "item.h" #include "thing.h"
class TibiaDat class TibiaDat
{ {
public: public:
bool load(const std::string& filename); bool load(const std::string& filename);
ItemAttributes *getItemAttributes(uint16 id); ThingAttributes *getItemAttributes(uint16 id);
ThingAttributes *getCreatureAttributes(uint16 id);
ThingAttributes *getEffectAttributes(uint16 id);
ThingAttributes *getShotAttributes(uint16 id);
uint16 getGroupCount(int i) { return m_groupCount[i]; } uint16 getGroupCount(int i) { return m_groupCount[i]; }
@ -20,7 +23,7 @@ private:
uint32 m_signature, m_totalCount; uint32 m_signature, m_totalCount;
uint16 m_groupCount[4]; uint16 m_groupCount[4];
ItemAttributes **m_itemsAttributes; ThingAttributes **m_thingsAttributes;
}; };
extern TibiaDat g_tibiaDat; extern TibiaDat g_tibiaDat;

View File

@ -7,44 +7,43 @@ Tile::Tile()
m_ground = NULL; m_ground = NULL;
} }
void Tile::addThing(Thing *thing) void Tile::addThing(ThingPtr thing, uint8 stackpos)
{ {
if(!thing) if(!thing)
return; return;
ThingAttributes *thingAttributes = thing->getAttributes();
if(thingAttributes) {
if(thing->getType() == Thing::TYPE_ITEM) { if(thing->getType() == Thing::TYPE_ITEM) {
Item *item = thing->getItem(); if(thingAttributes->group == THING_GROUP_GROUND)
if(item) { m_ground = thing;
ItemAttributes *itemAttributes = g_tibiaDat.getItemAttributes(item->getId());
if(itemAttributes->group == ITEM_GROUP_GROUND)
m_ground = item;
else { else {
if(itemAttributes->alwaysOnTop) if(thingAttributes->alwaysOnTop)
m_itemsTop.push_back(thing); m_itemsTop.push_back(thing);
else else
m_itemsBot.push_back(thing); m_itemsBot.push_back(thing);
} }
} }
}
else if(thing->getType() == Thing::TYPE_CREATURE) { else if(thing->getType() == Thing::TYPE_CREATURE) {
m_creatures.push_back(thing);
} }
}
} }
void Tile::draw(int x, int y, int z) void Tile::draw(int x, int y)
{ {
if(m_ground) if(m_ground)
m_ground->draw(x, y, z); m_ground->draw(x, y);
for(auto it = m_itemsTop.begin(), end = m_itemsTop.end(); it != end; ++it) for(auto it = m_itemsTop.begin(), end = m_itemsTop.end(); it != end; ++it)
(*it)->draw(x, y, z); (*it)->draw(x, y);
for(auto it = m_creatures.begin(), end = m_creatures.end(); it != end; ++it) for(auto it = m_creatures.begin(), end = m_creatures.end(); it != end; ++it)
(*it)->draw(x, y, z); (*it)->draw(x, y);
for(auto it = m_itemsBot.begin(), end = m_itemsBot.end(); it != end; ++it) for(auto it = m_itemsBot.begin(), end = m_itemsBot.end(); it != end; ++it)
(*it)->draw(x, y, z); (*it)->draw(x, y);
} }

View File

@ -3,6 +3,7 @@
#include <global.h> #include <global.h>
#include "thing.h" #include "thing.h"
#include "position.h"
class Tile; class Tile;
typedef std::shared_ptr<Tile> TilePtr; typedef std::shared_ptr<Tile> TilePtr;
@ -12,17 +13,17 @@ class Tile
public: public:
Tile(); Tile();
void addThing(Thing *thing); void addThing(ThingPtr thing, uint8 stackpos);
void draw(int x, int y, int z); void draw(int x, int y);
bool hasGround(); bool hasGround();
int getStackSize(); int getStackSize();
private: private:
Item *m_ground; ThingPtr m_ground;
std::list<Thing*> m_itemsBot; std::list<ThingPtr> m_itemsBot;
std::list<Thing*> m_creatures; std::list<ThingPtr> m_creatures;
std::list<Thing*> m_itemsTop; std::list<ThingPtr> m_itemsTop;
}; };
#endif // TILE_H #endif // TILE_H