creatures, fixe
This commit is contained in:
parent
92b54b6f55
commit
e8448cddb9
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
|
|
||||||
Game g_game;
|
Game g_game;
|
||||||
|
|
||||||
|
Game::Game()
|
||||||
|
{
|
||||||
|
m_online = false;
|
||||||
|
}
|
||||||
|
|
11
src/game.h
11
src/game.h
|
@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
92
src/item.cpp
92
src/item.cpp
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
44
src/item.h
44
src/item.h
|
@ -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
|
||||||
|
|
46
src/map.cpp
46
src/map.cpp
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
|
|
15
src/player.h
15
src/player.h
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
56
src/thing.h
56
src/thing.h
|
@ -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
|
||||||
|
|
135
src/tibiadat.cpp
135
src/tibiadat.cpp
|
@ -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]];
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
29
src/tile.cpp
29
src/tile.cpp
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
src/tile.h
13
src/tile.h
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue