map draw working with lil bugs
This commit is contained in:
parent
3a5683b549
commit
651315d4cd
|
@ -50,11 +50,20 @@ SET(SOURCES
|
||||||
|
|
||||||
# game files
|
# game files
|
||||||
src/tibiadat.cpp
|
src/tibiadat.cpp
|
||||||
|
src/tibiaspr.cpp
|
||||||
|
|
||||||
|
# game contents
|
||||||
|
src/game.cpp
|
||||||
|
src/map.cpp
|
||||||
|
src/tile.cpp
|
||||||
|
src/thing.cpp
|
||||||
|
src/item.cpp
|
||||||
|
|
||||||
# game net
|
# game net
|
||||||
src/protocollogin.cpp
|
src/protocollogin.cpp
|
||||||
src/protocolgame.cpp
|
src/protocolgame.cpp
|
||||||
src/protocolgameparse.cpp
|
src/protocolgameparse.cpp
|
||||||
|
src/protocolgamesend.cpp
|
||||||
|
|
||||||
# framework core
|
# framework core
|
||||||
src/framework/core/dispatcher.cpp
|
src/framework/core/dispatcher.cpp
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <ui/uiskins.h>
|
#include <ui/uiskins.h>
|
||||||
#include <script/luainterface.h>
|
#include <script/luainterface.h>
|
||||||
#include <net/connection.h>
|
#include <net/connection.h>
|
||||||
|
#include <../game.h>
|
||||||
|
|
||||||
Engine g_engine;
|
Engine g_engine;
|
||||||
|
|
||||||
|
@ -95,6 +96,9 @@ void Engine::run()
|
||||||
if(m_calculateFps)
|
if(m_calculateFps)
|
||||||
defaultFont->renderText(fpsText, Point(g_graphics.getScreenSize().width() - fpsTextSize.width() - 10, 10));
|
defaultFont->renderText(fpsText, Point(g_graphics.getScreenSize().width() - fpsTextSize.width() - 10, 10));
|
||||||
|
|
||||||
|
// todo remove. render map
|
||||||
|
g_game.getMap()->draw(0, 0, g_graphics.getScreenSize().width(), g_graphics.getScreenSize().height());
|
||||||
|
|
||||||
g_graphics.endRender();
|
g_graphics.endRender();
|
||||||
|
|
||||||
// swap buffers
|
// swap buffers
|
||||||
|
|
|
@ -34,7 +34,9 @@ Texture::Texture(int width, int height, int channels, uchar *pixels)
|
||||||
|
|
||||||
uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height)
|
uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height)
|
||||||
{
|
{
|
||||||
GLint texSize;
|
g_graphics.disableDrawing();
|
||||||
|
|
||||||
|
GLint texSize = 0;
|
||||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
|
||||||
if(width > texSize || height > texSize) {
|
if(width > texSize || height > texSize) {
|
||||||
logError("loading texture with size ",width,"x",height," failed, the maximum size is ",texSize,"x",texSize);
|
logError("loading texture with size ",width,"x",height," failed, the maximum size is ",texSize,"x",texSize);
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
Game g_game;
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef GAME_H
|
||||||
|
#define GAME_H
|
||||||
|
|
||||||
|
#include <global.h>
|
||||||
|
#include "map.h"
|
||||||
|
#include "player.h"
|
||||||
|
|
||||||
|
class Game
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Map *getMap() { return &m_map; }
|
||||||
|
Player *getPlayer() { return &m_player; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Map m_map;
|
||||||
|
Player m_player;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Game g_game;
|
||||||
|
|
||||||
|
#endif // GAME_H
|
|
@ -0,0 +1,79 @@
|
||||||
|
#include "item.h"
|
||||||
|
#include "tibiadat.h"
|
||||||
|
#include "tibiaspr.h"
|
||||||
|
#include <graphics/graphics.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()
|
||||||
|
{
|
||||||
|
m_type = Thing::TYPE_ITEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item::draw(int x, int y)
|
||||||
|
{
|
||||||
|
ItemAttributes *itemAttributes = g_tibiaDat.getItemAttributes(m_id);
|
||||||
|
|
||||||
|
int cDivX = 0, cDivY = 0, cDivZ = 0, cAnim = 0;
|
||||||
|
|
||||||
|
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 - 32, y - yi*32 - 32, 32, 32), data, Rect(0, 0, 32, 32));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
#ifndef ITEM_H
|
||||||
|
#define ITEM_H
|
||||||
|
|
||||||
|
#include <global.h>
|
||||||
|
#include "thing.h"
|
||||||
|
|
||||||
|
enum ItemGroup {
|
||||||
|
ITEM_GROUP_NONE = 0,
|
||||||
|
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
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
Item();
|
||||||
|
|
||||||
|
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; }
|
||||||
|
|
||||||
|
virtual Item* getItem() { return this; }
|
||||||
|
virtual const Item* getItem() const { return this; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint16 m_id;
|
||||||
|
uint8 m_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
14
src/main.cpp
14
src/main.cpp
|
@ -9,6 +9,7 @@
|
||||||
#include <ui/uicontainer.h>
|
#include <ui/uicontainer.h>
|
||||||
#include <script/luainterface.h>
|
#include <script/luainterface.h>
|
||||||
#include "tibiadat.h"
|
#include "tibiadat.h"
|
||||||
|
#include "tibiaspr.h"
|
||||||
|
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
|
|
||||||
|
@ -79,10 +80,6 @@ int main(int argc, const char *argv[])
|
||||||
// load resources paths
|
// load resources paths
|
||||||
g_resources.init(args[0].c_str());
|
g_resources.init(args[0].c_str());
|
||||||
|
|
||||||
// load Tibia.dat TODO this is temporary
|
|
||||||
if(!g_tibiaDat.load("Tibia.dat"))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// load configurations
|
// load configurations
|
||||||
loadDefaultConfigs();
|
loadDefaultConfigs();
|
||||||
if(!g_configs.load("config.otml"))
|
if(!g_configs.load("config.otml"))
|
||||||
|
@ -98,6 +95,15 @@ int main(int argc, const char *argv[])
|
||||||
|
|
||||||
// init engine
|
// init engine
|
||||||
g_engine.init();
|
g_engine.init();
|
||||||
|
|
||||||
|
// load Tibia.spr TODO this is temporary
|
||||||
|
if(!g_tibiaSpr.load("tibiafiles/Tibia.spr"))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// load Tibia.dat TODO this is temporary
|
||||||
|
if(!g_tibiaDat.load("tibiafiles/Tibia.dat"))
|
||||||
|
return -1;
|
||||||
|
|
||||||
g_engine.enableFpsCounter();
|
g_engine.enableFpsCounter();
|
||||||
|
|
||||||
// load ui skins
|
// load ui skins
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include "map.h"
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
void Map::draw(int x, int y, int width, int heigth)
|
||||||
|
{
|
||||||
|
Position playerPos = g_game.getPlayer()->getPosition();
|
||||||
|
for(int ix = 0; ix < 19; ++ix) {
|
||||||
|
for(int iy = 0; iy < 15; ++iy) {
|
||||||
|
if(playerPos.getZ() >= 7) {
|
||||||
|
for(int iz = 7; iz > 0; --iz) {
|
||||||
|
m_map[ix][iy][iz].draw(x+ix*32-(7-iz)*32, y+iy*32-(7-iz)*32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::addThing(Thing *thing, const Position& pos)
|
||||||
|
{
|
||||||
|
Position playerPos = g_game.getPlayer()->getPosition();
|
||||||
|
Position relativePos = Position(pos.getX() - playerPos.getX() + 8, pos.getY() - playerPos.getY() + 6, pos.getZ());
|
||||||
|
|
||||||
|
if(relativePos.getX() >= 18)
|
||||||
|
logDebug("relativePos is invalid.");
|
||||||
|
if(relativePos.getY() >= 14)
|
||||||
|
logDebug("relativePos is invalid.");
|
||||||
|
if(relativePos.getZ() >= 15)
|
||||||
|
logDebug("relativePos is invalid.");
|
||||||
|
|
||||||
|
logDebug("x: ", (int)relativePos.getX(), " y: ", (int)relativePos.getY(), " z: ", (int)relativePos.getZ());
|
||||||
|
m_map[relativePos.getX()][relativePos.getY()][relativePos.getZ()].addThing(thing);
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef MAP_H
|
||||||
|
#define MAP_H
|
||||||
|
|
||||||
|
#include "position.h"
|
||||||
|
#include "tile.h"
|
||||||
|
|
||||||
|
class Map
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void addThing(Thing *thing, const Position& pos);
|
||||||
|
|
||||||
|
void draw(int x, int y, int width, int heigth);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Visible tiles are 15x11, but we have a +3 value. We have 15 floors.
|
||||||
|
Tile m_map[19][15][15];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAP_H
|
|
@ -7,7 +7,7 @@ class Player
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void setPosition(Position position) { m_position = position; }
|
void setPosition(const Position& position) { m_position = position; }
|
||||||
Position getPosition() { return m_position; }
|
Position getPosition() { return m_position; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef POSITION_H
|
#ifndef POSITION_H
|
||||||
#define POSITION_H
|
#define POSITION_H
|
||||||
|
|
||||||
|
#include <global.h>
|
||||||
|
|
||||||
class Position
|
class Position
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -14,9 +16,12 @@ public:
|
||||||
void setY(uint16 y) { m_y = y; }
|
void setY(uint16 y) { m_y = y; }
|
||||||
void setZ(uint8 z) { m_z = z; }
|
void setZ(uint8 z) { m_z = z; }
|
||||||
|
|
||||||
uint16 getX() { return m_x; }
|
uint16 getX() const { return m_x; }
|
||||||
uint16 getY() { return m_y; }
|
uint16 getY() const { return m_y; }
|
||||||
uint8 getZ() { return m_z; }
|
uint8 getZ() const { return m_z; }
|
||||||
|
|
||||||
|
//const Position operator+(const Position& other) const { return Position(other.m_x + m_x, other.m_y + m_y, other.m_z + m_z); }
|
||||||
|
//const Position operator-(const Position& other) const { return Position(other.m_x - m_x, other.m_y - m_y, other.m_z - m_z); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16 m_x, m_y;
|
uint16 m_x, m_y;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "protocolgame.h"
|
#include "protocolgame.h"
|
||||||
|
#include "game.h"
|
||||||
#include <net/rsa.h>
|
#include <net/rsa.h>
|
||||||
|
|
||||||
ProtocolGame::ProtocolGame()
|
ProtocolGame::ProtocolGame()
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <net/protocol.h>
|
#include <net/protocol.h>
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
#include "thing.h"
|
||||||
|
|
||||||
class ProtocolGame;
|
class ProtocolGame;
|
||||||
typedef std::shared_ptr<ProtocolGame> ProtocolGamePtr;
|
typedef std::shared_ptr<ProtocolGame> ProtocolGamePtr;
|
||||||
|
@ -95,19 +96,18 @@ private:
|
||||||
void parseQuestList(InputMessage& msg);
|
void parseQuestList(InputMessage& msg);
|
||||||
void parseQuestPartList(InputMessage& msg);
|
void parseQuestPartList(InputMessage& msg);
|
||||||
|
|
||||||
|
void sendPing();
|
||||||
|
|
||||||
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);
|
||||||
void internalGetThing(InputMessage& msg);
|
Thing *internalGetThing(InputMessage& msg);
|
||||||
void internalCreatureOutfit(InputMessage& msg);
|
void internalCreatureOutfit(InputMessage& msg);
|
||||||
void internalGetItem(InputMessage& msg, uint16 id);
|
Item *internalGetItem(InputMessage& msg, uint16 id);
|
||||||
|
|
||||||
Position parsePosition(InputMessage& msg);
|
Position parsePosition(InputMessage& msg);
|
||||||
|
|
||||||
std::string m_accountName, m_accountPassword, m_characterName;
|
std::string m_accountName, m_accountPassword, m_characterName;
|
||||||
|
|
||||||
// TODO this is unknown
|
|
||||||
Player m_player;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: place it somewhere else
|
// TODO: place it somewhere else
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "protocolgame.h"
|
#include "protocolgame.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "tibiadat.h"
|
#include "tibiadat.h"
|
||||||
|
#include "game.h"
|
||||||
|
#include "map.h"
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
void ProtocolGame::parseMessage(InputMessage& msg)
|
void ProtocolGame::parseMessage(InputMessage& msg)
|
||||||
|
@ -260,9 +262,7 @@ void ProtocolGame::parseWaitList(InputMessage& msg)
|
||||||
|
|
||||||
void ProtocolGame::parsePing(InputMessage&)
|
void ProtocolGame::parsePing(InputMessage&)
|
||||||
{
|
{
|
||||||
//mSendmsg.reset();
|
sendPing();
|
||||||
//mSendmsg.addByte(0x1E);
|
|
||||||
//sendMessage(mSendMsg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseDeath(InputMessage&)
|
void ProtocolGame::parseDeath(InputMessage&)
|
||||||
|
@ -277,32 +277,37 @@ void ProtocolGame::parseCanReportBugs(InputMessage& msg)
|
||||||
|
|
||||||
void ProtocolGame::parseMapDescription(InputMessage& msg)
|
void ProtocolGame::parseMapDescription(InputMessage& msg)
|
||||||
{
|
{
|
||||||
m_player.setPosition(parsePosition(msg));
|
Player *player = g_game.getPlayer();
|
||||||
setMapDescription(msg, m_player.getPosition().getX() - 8, m_player.getPosition().getY() - 6, m_player.getPosition().getZ(), 18, 14);
|
player->setPosition(parsePosition(msg));
|
||||||
|
setMapDescription(msg, player->getPosition().getX() - 8, player->getPosition().getY() - 6, player->getPosition().getZ(), 18, 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseMoveNorth(InputMessage& msg)
|
void ProtocolGame::parseMoveNorth(InputMessage& msg)
|
||||||
{
|
{
|
||||||
m_player.getPosition().setY(m_player.getPosition().getY() - 1);
|
Player *player = g_game.getPlayer();
|
||||||
setMapDescription(msg, m_player.getPosition().getX() - 8, m_player.getPosition().getY() - 6, m_player.getPosition().getZ(), 18, 1);
|
player->getPosition().setY(player->getPosition().getY() - 1);
|
||||||
|
setMapDescription(msg, player->getPosition().getX() - 8, player->getPosition().getY() - 6, player->getPosition().getZ(), 18, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseMoveEast(InputMessage& msg)
|
void ProtocolGame::parseMoveEast(InputMessage& msg)
|
||||||
{
|
{
|
||||||
m_player.getPosition().setX(m_player.getPosition().getX() + 1);
|
Player *player = g_game.getPlayer();
|
||||||
setMapDescription(msg, m_player.getPosition().getX() + 9, m_player.getPosition().getY() - 6, m_player.getPosition().getZ(), 1, 14);
|
player->getPosition().setX(player->getPosition().getX() + 1);
|
||||||
|
setMapDescription(msg, player->getPosition().getX() + 9, player->getPosition().getY() - 6, player->getPosition().getZ(), 1, 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseMoveSouth(InputMessage& msg)
|
void ProtocolGame::parseMoveSouth(InputMessage& msg)
|
||||||
{
|
{
|
||||||
m_player.getPosition().setY(m_player.getPosition().getY() + 1);
|
Player *player = g_game.getPlayer();
|
||||||
setMapDescription(msg, m_player.getPosition().getX() - 8, m_player.getPosition().getY() + 7, m_player.getPosition().getZ(), 18, 1);
|
player->getPosition().setY(player->getPosition().getY() + 1);
|
||||||
|
setMapDescription(msg, player->getPosition().getX() - 8, player->getPosition().getY() + 7, player->getPosition().getZ(), 18, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseMoveWest(InputMessage& msg)
|
void ProtocolGame::parseMoveWest(InputMessage& msg)
|
||||||
{
|
{
|
||||||
m_player.getPosition().setX(m_player.getPosition().getX() - 1);
|
Player *player = g_game.getPlayer();
|
||||||
setMapDescription(msg, m_player.getPosition().getX() - 8, m_player.getPosition().getY() - 6, m_player.getPosition().getZ(), 1, 14);
|
player->getPosition().setX(player->getPosition().getX() - 1);
|
||||||
|
setMapDescription(msg, player->getPosition().getX() - 8, player->getPosition().getY() - 6, player->getPosition().getZ(), 1, 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseUpdateTile(InputMessage& msg)
|
void ProtocolGame::parseUpdateTile(InputMessage& msg)
|
||||||
|
@ -677,34 +682,36 @@ void ProtocolGame::parseCancelWalk(InputMessage& msg)
|
||||||
|
|
||||||
void ProtocolGame::parseFloorChangeUp(InputMessage& msg)
|
void ProtocolGame::parseFloorChangeUp(InputMessage& msg)
|
||||||
{
|
{
|
||||||
m_player.getPosition().setZ(m_player.getPosition().getZ() - 1);
|
Player *player = g_game.getPlayer();
|
||||||
|
player->getPosition().setZ(player->getPosition().getZ() - 1);
|
||||||
|
|
||||||
int32 skip = 0;
|
int32 skip = 0;
|
||||||
if(m_player.getPosition().getZ() == 7)
|
if(player->getPosition().getZ() == 7)
|
||||||
for(int32 i = 5; i >= 0; i--)
|
for(int32 i = 5; i >= 0; i--)
|
||||||
setFloorDescription(msg, m_player.getPosition().getX() - 8, m_player.getPosition().getY() - 6, i, 18, 14, 8 - i, &skip);
|
setFloorDescription(msg, player->getPosition().getX() - 8, player->getPosition().getY() - 6, i, 18, 14, 8 - i, &skip);
|
||||||
else if(m_player.getPosition().getZ() > 7)
|
else if(player->getPosition().getZ() > 7)
|
||||||
setFloorDescription(msg, m_player.getPosition().getX() - 8, m_player.getPosition().getY() - 6, m_player.getPosition().getZ() - 2, 18, 14, 3, &skip);
|
setFloorDescription(msg, player->getPosition().getX() - 8, player->getPosition().getY() - 6, player->getPosition().getZ() - 2, 18, 14, 3, &skip);
|
||||||
|
|
||||||
m_player.getPosition().setX(m_player.getPosition().getX() + 1);
|
player->getPosition().setX(player->getPosition().getX() + 1);
|
||||||
m_player.getPosition().setY(m_player.getPosition().getY() + 1);
|
player->getPosition().setY(player->getPosition().getY() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseFloorChangeDown(InputMessage& msg)
|
void ProtocolGame::parseFloorChangeDown(InputMessage& msg)
|
||||||
{
|
{
|
||||||
m_player.getPosition().setZ(m_player.getPosition().getZ() + 1);
|
Player *player = g_game.getPlayer();
|
||||||
|
player->getPosition().setZ(player->getPosition().getZ() + 1);
|
||||||
|
|
||||||
int32 skip = 0;
|
int32 skip = 0;
|
||||||
if(m_player.getPosition().getZ() == 8) {
|
if(player->getPosition().getZ() == 8) {
|
||||||
int32 j, i;
|
int32 j, i;
|
||||||
for(i = m_player.getPosition().getZ(), j = -1; i < (int32)m_player.getPosition().getZ() + 3; ++i, --j)
|
for(i = player->getPosition().getZ(), j = -1; i < (int32)player->getPosition().getZ() + 3; ++i, --j)
|
||||||
setFloorDescription(msg, m_player.getPosition().getX() - 8, m_player.getPosition().getY() - 6, i, 18, 14, j, &skip);
|
setFloorDescription(msg, player->getPosition().getX() - 8, player->getPosition().getY() - 6, i, 18, 14, j, &skip);
|
||||||
}
|
}
|
||||||
else if(m_player.getPosition().getZ() > 8 && m_player.getPosition().getZ() < 14)
|
else if(player->getPosition().getZ() > 8 && player->getPosition().getZ() < 14)
|
||||||
setFloorDescription(msg, m_player.getPosition().getX() - 8, m_player.getPosition().getY() - 6, m_player.getPosition().getZ() + 2, 18, 14, -3, &skip);
|
setFloorDescription(msg, player->getPosition().getX() - 8, player->getPosition().getY() - 6, player->getPosition().getZ() + 2, 18, 14, -3, &skip);
|
||||||
|
|
||||||
m_player.getPosition().setX(m_player.getPosition().getX() - 1);
|
player->getPosition().setX(player->getPosition().getX() - 1);
|
||||||
m_player.getPosition().setY(m_player.getPosition().getY() - 1);
|
player->getPosition().setY(player->getPosition().getY() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseOutfitWindow(InputMessage& msg)
|
void ProtocolGame::parseOutfitWindow(InputMessage& msg)
|
||||||
|
@ -823,13 +830,16 @@ void ProtocolGame::setTileDescription(InputMessage& msg, Position position)
|
||||||
logDebug("[ProtocolGame::setTileDescription] Too many things!.");
|
logDebug("[ProtocolGame::setTileDescription] Too many things!.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
internalGetThing(msg);
|
|
||||||
|
g_game.getMap()->addThing(internalGetThing(msg), position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::internalGetThing(InputMessage& msg)
|
Thing *ProtocolGame::internalGetThing(InputMessage& msg)
|
||||||
{
|
{
|
||||||
|
Thing *thing = NULL;
|
||||||
|
|
||||||
uint16 thingId = msg.getU16();
|
uint16 thingId = msg.getU16();
|
||||||
if(thingId == 0x0061 || thingId == 0x0062) { // add new creature
|
if(thingId == 0x0061 || thingId == 0x0062) { // add new creature
|
||||||
if(thingId == 0x0062) { //creature is known
|
if(thingId == 0x0062) { //creature is known
|
||||||
|
@ -860,7 +870,9 @@ void ProtocolGame::internalGetThing(InputMessage& msg)
|
||||||
msg.getU8(); // direction
|
msg.getU8(); // direction
|
||||||
}
|
}
|
||||||
else // item
|
else // item
|
||||||
internalGetItem(msg, thingId);
|
thing = internalGetItem(msg, thingId);
|
||||||
|
|
||||||
|
return thing;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::internalCreatureOutfit(InputMessage& msg)
|
void ProtocolGame::internalCreatureOutfit(InputMessage& msg)
|
||||||
|
@ -878,14 +890,19 @@ void ProtocolGame::internalCreatureOutfit(InputMessage& msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::internalGetItem(InputMessage& msg, uint16 id)
|
Item *ProtocolGame::internalGetItem(InputMessage& msg, uint16 id)
|
||||||
{
|
{
|
||||||
|
Item *item = new Item();
|
||||||
|
|
||||||
if(id == 0xFFFF)
|
if(id == 0xFFFF)
|
||||||
id = msg.getU16();
|
id = msg.getU16();
|
||||||
|
item->setId(id);
|
||||||
|
|
||||||
Item *item = g_tibiaDat.getItem(id);
|
ItemAttributes *itemAttributes = g_tibiaDat.getItemAttributes(id);
|
||||||
if(item->stackable || item->group == ITEM_GROUP_FLUID || item->group == ITEM_GROUP_SPLASH)
|
if(itemAttributes->stackable || itemAttributes->group == ITEM_GROUP_FLUID || itemAttributes->group == ITEM_GROUP_SPLASH)
|
||||||
msg.getU8();
|
item->setCount(msg.getU8());
|
||||||
|
|
||||||
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
Position ProtocolGame::parsePosition(InputMessage& msg)
|
Position ProtocolGame::parsePosition(InputMessage& msg)
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "protocolgame.h"
|
||||||
|
|
||||||
|
void ProtocolGame::sendPing()
|
||||||
|
{
|
||||||
|
OutputMessage oMsg;
|
||||||
|
oMsg.reset();
|
||||||
|
oMsg.addU8(0x1E);
|
||||||
|
send(oMsg);
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#include "thing.h"
|
||||||
|
|
||||||
|
Thing::Thing()
|
||||||
|
{
|
||||||
|
m_type = TYPE_NONE;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef THING_H
|
||||||
|
#define THING_H
|
||||||
|
|
||||||
|
#include <global.h>
|
||||||
|
|
||||||
|
class Item;
|
||||||
|
|
||||||
|
class Thing
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Thing();
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
TYPE_NONE,
|
||||||
|
TYPE_ITEM,
|
||||||
|
TYPE_CREATURE
|
||||||
|
};
|
||||||
|
|
||||||
|
void setType(Type type) { m_type = type; }
|
||||||
|
Type getType() const { return m_type; }
|
||||||
|
|
||||||
|
virtual void draw(int, int) {}
|
||||||
|
|
||||||
|
virtual Item* getItem() { return NULL; }
|
||||||
|
virtual const Item *getItem() const { return NULL; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Type m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // THING_H
|
105
src/tibiadat.cpp
105
src/tibiadat.cpp
|
@ -1,4 +1,5 @@
|
||||||
#include "tibiadat.h"
|
#include "tibiadat.h"
|
||||||
|
#include "tibiaspr.h"
|
||||||
#include <core/resources.h>
|
#include <core/resources.h>
|
||||||
|
|
||||||
TibiaDat g_tibiaDat;
|
TibiaDat g_tibiaDat;
|
||||||
|
@ -20,17 +21,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_items = new Item*[m_totalCount+1];
|
m_itemsAttributes = new ItemAttributes*[m_totalCount+1];
|
||||||
for(uint16 i = 0; i <= m_totalCount; i++)
|
for(uint16 i = 0; i <= m_totalCount; i++)
|
||||||
m_items[i] = NULL;
|
m_itemsAttributes[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_items[id] = new Item();
|
m_itemsAttributes[id] = new ItemAttributes();
|
||||||
m_items[id]->id = id;
|
m_itemsAttributes[id]->id = id;
|
||||||
|
|
||||||
uint8 opt;
|
uint8 opt;
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
@ -38,80 +39,80 @@ 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_items[id]->speed, 2);
|
fin.read((char*)&m_itemsAttributes[id]->speed, 2);
|
||||||
m_items[id]->group = ITEM_GROUP_GROUND;
|
m_itemsAttributes[id]->group = ITEM_GROUP_GROUND;
|
||||||
}
|
}
|
||||||
else if(opt == 0x01) { // All OnTop
|
else if(opt == 0x01) { // All OnTop
|
||||||
m_items[id]->alwaysOnTop = true;
|
m_itemsAttributes[id]->alwaysOnTop = true;
|
||||||
m_items[id]->alwaysOnTopOrder = 1;
|
m_itemsAttributes[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_items[id]->alwaysOnTop = true;
|
m_itemsAttributes[id]->alwaysOnTop = true;
|
||||||
m_items[id]->alwaysOnTopOrder = 2;
|
m_itemsAttributes[id]->alwaysOnTopOrder = 2;
|
||||||
}
|
}
|
||||||
else if(opt == 0x03) { // Can walk trough (arces)
|
else if(opt == 0x03) { // Can walk trough (arces)
|
||||||
m_items[id]->alwaysOnTop = true;
|
m_itemsAttributes[id]->alwaysOnTop = true;
|
||||||
m_items[id]->alwaysOnTopOrder = 3;
|
m_itemsAttributes[id]->alwaysOnTopOrder = 3;
|
||||||
}
|
}
|
||||||
else if(opt == 0x04) { // Container
|
else if(opt == 0x04) { // Container
|
||||||
m_items[id]->group = ITEM_GROUP_CONTAINER;
|
m_itemsAttributes[id]->group = ITEM_GROUP_CONTAINER;
|
||||||
}
|
}
|
||||||
else if(opt == 0x05) { // Stackable
|
else if(opt == 0x05) { // Stackable
|
||||||
m_items[id]->stackable = true;
|
m_itemsAttributes[id]->stackable = true;
|
||||||
}
|
}
|
||||||
else if(opt == 0x06) { // Unknown
|
else if(opt == 0x06) { // Unknown
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(opt == 0x07) { // Useable
|
else if(opt == 0x07) { // Useable
|
||||||
m_items[id]->useable = true;
|
m_itemsAttributes[id]->useable = true;
|
||||||
}
|
}
|
||||||
else if(opt == 0x08) { // Writtable
|
else if(opt == 0x08) { // Writtable
|
||||||
m_items[id]->group = ITEM_GROUP_WRITEABLE;
|
m_itemsAttributes[id]->group = ITEM_GROUP_WRITEABLE;
|
||||||
m_items[id]->readable = true;
|
m_itemsAttributes[id]->readable = true;
|
||||||
fin.read((char*)&m_items[id]->subParam07, 2);
|
fin.read((char*)&m_itemsAttributes[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_items[id]->readable = true;
|
m_itemsAttributes[id]->readable = true;
|
||||||
fin.read((char*)&m_items[id]->subParam08, 2);
|
fin.read((char*)&m_itemsAttributes[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_items[id]->group = ITEM_GROUP_FLUID;
|
m_itemsAttributes[id]->group = ITEM_GROUP_FLUID;
|
||||||
}
|
}
|
||||||
else if(opt == 0x0B) { // Splashes
|
else if(opt == 0x0B) { // Splashes
|
||||||
m_items[id]->group = ITEM_GROUP_SPLASH;
|
m_itemsAttributes[id]->group = ITEM_GROUP_SPLASH;
|
||||||
}
|
}
|
||||||
else if(opt == 0x0C) { // Blocks solid objects (creatures, walls etc)
|
else if(opt == 0x0C) { // Blocks solid objects (creatures, walls etc)
|
||||||
m_items[id]->blockSolid = true;
|
m_itemsAttributes[id]->blockSolid = true;
|
||||||
}
|
}
|
||||||
else if(opt == 0x0D) { // Not moveable
|
else if(opt == 0x0D) { // Not moveable
|
||||||
m_items[id]->moveable = false;
|
m_itemsAttributes[id]->moveable = false;
|
||||||
}
|
}
|
||||||
else if(opt == 0x0E) { // Blocks missiles (walls, magic wall etc)
|
else if(opt == 0x0E) { // Blocks missiles (walls, magic wall etc)
|
||||||
m_items[id]->blockProjectile = true;
|
m_itemsAttributes[id]->blockProjectile = true;
|
||||||
}
|
}
|
||||||
else if(opt == 0x0F) { // Blocks pathfind algorithms (monsters)
|
else if(opt == 0x0F) { // Blocks pathfind algorithms (monsters)
|
||||||
m_items[id]->blockPathFind = true;
|
m_itemsAttributes[id]->blockPathFind = true;
|
||||||
}
|
}
|
||||||
else if(opt == 0x10) { // Blocks monster movement (flowers, parcels etc)
|
else if(opt == 0x10) { // Blocks monster movement (flowers, parcels etc)
|
||||||
m_items[id]->pickupable = true;
|
m_itemsAttributes[id]->pickupable = true;
|
||||||
}
|
}
|
||||||
else if(opt == 0x11) { // Hangable objects (wallpaper etc)
|
else if(opt == 0x11) { // Hangable objects (wallpaper etc)
|
||||||
m_items[id]->isHangable = true;
|
m_itemsAttributes[id]->isHangable = true;
|
||||||
}
|
}
|
||||||
else if(opt == 0x12) { // Horizontal wall
|
else if(opt == 0x12) { // Horizontal wall
|
||||||
m_items[id]->isHorizontal = true;
|
m_itemsAttributes[id]->isHorizontal = true;
|
||||||
}
|
}
|
||||||
else if(opt == 0x13) { // Vertical wall
|
else if(opt == 0x13) { // Vertical wall
|
||||||
m_items[id]->isVertical = true;
|
m_itemsAttributes[id]->isVertical = true;
|
||||||
}
|
}
|
||||||
else if(opt == 0x14) { // Rotable
|
else if(opt == 0x14) { // Rotable
|
||||||
m_items[id]->rotable = true;
|
m_itemsAttributes[id]->rotable = true;
|
||||||
}
|
}
|
||||||
else if(opt == 0x15) { // Light info
|
else if(opt == 0x15) { // Light info
|
||||||
fin.read((char*)&m_items[id]->lightLevel, 2);
|
fin.read((char*)&m_itemsAttributes[id]->lightLevel, 2);
|
||||||
fin.read((char*)&m_items[id]->lightColor, 2);
|
fin.read((char*)&m_itemsAttributes[id]->lightColor, 2);
|
||||||
}
|
}
|
||||||
else if(opt == 0x16) {
|
else if(opt == 0x16) {
|
||||||
}
|
}
|
||||||
|
@ -121,26 +122,26 @@ bool TibiaDat::load(const std::string& filename)
|
||||||
fin.read((char*)&read_long, 4);
|
fin.read((char*)&read_long, 4);
|
||||||
}
|
}
|
||||||
else if(opt == 0x19) { // Has height
|
else if(opt == 0x19) { // Has height
|
||||||
m_items[id]->hasHeight = true;
|
m_itemsAttributes[id]->hasHeight = true;
|
||||||
fin.read((char*)&m_items[id]->uheight, 2);
|
fin.read((char*)&m_itemsAttributes[id]->uheight, 2);
|
||||||
}
|
}
|
||||||
else if(opt == 0x1A) {
|
else if(opt == 0x1A) {
|
||||||
}
|
}
|
||||||
else if(opt == 0x1B) {
|
else if(opt == 0x1B) {
|
||||||
}
|
}
|
||||||
else if(opt == 0x1C) { // Minimap color
|
else if(opt == 0x1C) { // Minimap color
|
||||||
fin.read((char*)&m_items[id]->miniMapColor, 2);
|
fin.read((char*)&m_itemsAttributes[id]->miniMapColor, 2);
|
||||||
m_items[id]->hasMiniMapColor = true;
|
m_itemsAttributes[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_items[id]->readable = true;
|
m_itemsAttributes[id]->readable = true;
|
||||||
}
|
}
|
||||||
else if(opt == 0x1E) {
|
else if(opt == 0x1E) {
|
||||||
}
|
}
|
||||||
else if(opt == 0x1F) {
|
else if(opt == 0x1F) {
|
||||||
m_items[id]->lookThrough = true;
|
m_itemsAttributes[id]->lookThrough = true;
|
||||||
}
|
}
|
||||||
else if(opt == 0x20) {
|
else if(opt == 0x20) {
|
||||||
}
|
}
|
||||||
|
@ -153,32 +154,32 @@ bool TibiaDat::load(const std::string& filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fin.read((char*)&m_items[id]->width, 1);
|
fin.read((char*)&m_itemsAttributes[id]->width, 1);
|
||||||
fin.read((char*)&m_items[id]->height, 1);
|
fin.read((char*)&m_itemsAttributes[id]->height, 1);
|
||||||
if((m_items[id]->width > 1) || (m_items[id]->height > 1))
|
if((m_itemsAttributes[id]->width > 1) || (m_itemsAttributes[id]->height > 1))
|
||||||
fin.read((char*)&read_byte, 1);
|
fin.read((char*)&read_byte, 1);
|
||||||
|
|
||||||
fin.read((char*)&m_items[id]->blendframes, 1);
|
fin.read((char*)&m_itemsAttributes[id]->blendframes, 1);
|
||||||
fin.read((char*)&m_items[id]->xdiv, 1);
|
fin.read((char*)&m_itemsAttributes[id]->xdiv, 1);
|
||||||
fin.read((char*)&m_items[id]->ydiv, 1);
|
fin.read((char*)&m_itemsAttributes[id]->ydiv, 1);
|
||||||
fin.read((char*)&m_items[id]->zdiv, 1);
|
fin.read((char*)&m_itemsAttributes[id]->zdiv, 1);
|
||||||
fin.read((char*)&m_items[id]->animcount, 1);
|
fin.read((char*)&m_itemsAttributes[id]->animcount, 1);
|
||||||
|
|
||||||
// Read sprites id.
|
// Read sprites id.
|
||||||
uint16 totalSprites = m_items[id]->width * m_items[id]->height * m_items[id]->blendframes * m_items[id]->xdiv * m_items[id]->ydiv * m_items[id]->zdiv * m_items[id]->animcount;
|
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;
|
||||||
|
|
||||||
m_items[id]->sprites = new uint16[totalSprites];
|
m_itemsAttributes[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_items[id]->sprites[i] = read_short-1;
|
m_itemsAttributes[id]->sprites[i] = read_short-1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Item *TibiaDat::getItem(uint16 id)
|
ItemAttributes *TibiaDat::getItemAttributes(uint16 id)
|
||||||
{
|
{
|
||||||
// items id start at 100.
|
// items id start at 100.
|
||||||
return m_items[id - 100];
|
return m_itemsAttributes[id - 100];
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,73 +2,14 @@
|
||||||
#define TIBIADAT_H
|
#define TIBIADAT_H
|
||||||
|
|
||||||
#include <global.h>
|
#include <global.h>
|
||||||
|
#include "item.h"
|
||||||
enum ItemGroup {
|
|
||||||
ITEM_GROUP_NONE = 0,
|
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Item
|
|
||||||
{
|
|
||||||
Item() {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
~Item() {
|
|
||||||
if(sprites)
|
|
||||||
delete []sprites;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 TibiaDat
|
class TibiaDat
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool load(const std::string& filename);
|
bool load(const std::string& filename);
|
||||||
|
|
||||||
Item *getItem(uint16 id);
|
ItemAttributes *getItemAttributes(uint16 id);
|
||||||
|
|
||||||
uint16 getGroupCount(int i) { return m_groupCount[i]; }
|
uint16 getGroupCount(int i) { return m_groupCount[i]; }
|
||||||
|
|
||||||
|
@ -79,7 +20,7 @@ private:
|
||||||
uint32 m_signature, m_totalCount;
|
uint32 m_signature, m_totalCount;
|
||||||
uint16 m_groupCount[4];
|
uint16 m_groupCount[4];
|
||||||
|
|
||||||
Item **m_items;
|
ItemAttributes **m_itemsAttributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TibiaDat g_tibiaDat;
|
extern TibiaDat g_tibiaDat;
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
#include "tibiaspr.h"
|
||||||
|
#include <core/resources.h>
|
||||||
|
|
||||||
|
TibiaSpr g_tibiaSpr;
|
||||||
|
|
||||||
|
TibiaSpr::TibiaSpr()
|
||||||
|
{
|
||||||
|
m_sprites = NULL;
|
||||||
|
m_spritesCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TibiaSpr::~TibiaSpr()
|
||||||
|
{
|
||||||
|
//for(uint16 i = 0; i < m_spritesCount; i++)
|
||||||
|
//if(m_sprites[i])
|
||||||
|
//delete m_sprites[i];
|
||||||
|
|
||||||
|
if(m_sprites)
|
||||||
|
delete []m_sprites;
|
||||||
|
|
||||||
|
//delete m_transparentSprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TibiaSpr::load(const std::string &filename)
|
||||||
|
{
|
||||||
|
if(!g_resources.loadFile(filename, m_fin))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_fin.read((char*)&m_signature, 4);
|
||||||
|
m_fin.read((char*)&m_spritesCount, 2);
|
||||||
|
|
||||||
|
m_sprites = new TexturePtr[m_spritesCount];
|
||||||
|
|
||||||
|
//for(uint16 i = 0; i < m_spritesCount; i++)
|
||||||
|
//m_sprites[i] = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
uchar pixels[4096];
|
||||||
|
for(int i = 0; i < 32*32*4; i += 4) {
|
||||||
|
pixels[i + 0] = 0xFF;
|
||||||
|
pixels[i + 1] = 0x00;
|
||||||
|
pixels[i + 2] = 0xFF;
|
||||||
|
pixels[i + 3] = 0xFF;
|
||||||
|
}
|
||||||
|
m_transparentSprite = TexturePtr(new Texture(32, 32, 4, pixels));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TexturePtr TibiaSpr::loadSprite(uint32 id)
|
||||||
|
{
|
||||||
|
if(m_fin.eof())
|
||||||
|
return TexturePtr();
|
||||||
|
|
||||||
|
m_fin.seekg((id * 4) + 6, std::ios_base::beg);
|
||||||
|
|
||||||
|
uint32 spriteAddress;
|
||||||
|
m_fin.read((char*)&spriteAddress, 4);
|
||||||
|
|
||||||
|
if(spriteAddress == 0) // Some error on tibia.spr, save a blank image.
|
||||||
|
return TexturePtr();
|
||||||
|
|
||||||
|
m_fin.seekg(spriteAddress, std::ios_base::beg);
|
||||||
|
|
||||||
|
uint32 colorKey = 0;
|
||||||
|
m_fin.read((char*)&colorKey, 3);
|
||||||
|
|
||||||
|
uint16 spriteSize;
|
||||||
|
m_fin.read((char*)&spriteSize, 2);
|
||||||
|
|
||||||
|
uchar image[4096];
|
||||||
|
uint16 imgPos = 0, read = 0, transparentPixels, coloredPixels, x;
|
||||||
|
while(read < spriteSize) {
|
||||||
|
m_fin.read((char*)&transparentPixels, 2);
|
||||||
|
m_fin.read((char*)&coloredPixels, 2);
|
||||||
|
|
||||||
|
for(x = 0; x < transparentPixels; x++) {
|
||||||
|
image[imgPos + 0] = 0x00;
|
||||||
|
image[imgPos + 1] = 0x00;
|
||||||
|
image[imgPos + 2] = 0x00;
|
||||||
|
image[imgPos + 3] = 0x00;
|
||||||
|
imgPos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(x = 0; x < coloredPixels; x++) {
|
||||||
|
m_fin.read((char*)&image[imgPos + 0], 1);
|
||||||
|
m_fin.read((char*)&image[imgPos + 1], 1);
|
||||||
|
m_fin.read((char*)&image[imgPos + 2], 1);
|
||||||
|
image[imgPos + 3] = 0xFF;
|
||||||
|
|
||||||
|
imgPos += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
read += 4 + (3 * coloredPixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill remaining bytes with pink.
|
||||||
|
if(imgPos < 32 * 32 * 4) {
|
||||||
|
for(x = imgPos; x < 32 * 32 * 4; x += 4) {
|
||||||
|
image[x + 0] = 0xFF;
|
||||||
|
image[x + 1] = 0x00;
|
||||||
|
image[x + 2] = 0xFF;
|
||||||
|
image[x + 3] = 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TexturePtr(new Texture(32, 32, 4, image));
|
||||||
|
}
|
||||||
|
|
||||||
|
TexturePtr TibiaSpr::getSprite(uint32 id)
|
||||||
|
{
|
||||||
|
if(!m_sprites)
|
||||||
|
return m_transparentSprite;
|
||||||
|
|
||||||
|
if(!m_sprites[id]) {
|
||||||
|
m_sprites[id] = loadSprite(id);
|
||||||
|
if(!m_sprites[id])
|
||||||
|
return m_transparentSprite;
|
||||||
|
}
|
||||||
|
return m_sprites[id];
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef TIBIASPR_H
|
||||||
|
#define TIBIASPR_H
|
||||||
|
|
||||||
|
#include <global.h>
|
||||||
|
#include <graphics/texture.h>
|
||||||
|
|
||||||
|
class TibiaSpr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TibiaSpr();
|
||||||
|
~TibiaSpr();
|
||||||
|
|
||||||
|
bool load(const std::string& filename);
|
||||||
|
|
||||||
|
uint32 getSignature() { return m_signature; }
|
||||||
|
uint16 getSpritesCount() { return m_spritesCount; }
|
||||||
|
TexturePtr getSprite(uint32 id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TexturePtr loadSprite(uint32 id);
|
||||||
|
|
||||||
|
std::stringstream m_fin;
|
||||||
|
uint32 m_signature;
|
||||||
|
uint16 m_spritesCount;
|
||||||
|
TexturePtr *m_sprites;
|
||||||
|
TexturePtr m_transparentSprite;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern TibiaSpr g_tibiaSpr;
|
||||||
|
|
||||||
|
#endif // TIBIASPR_H
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include "tile.h"
|
||||||
|
#include "item.h"
|
||||||
|
#include "tibiadat.h"
|
||||||
|
|
||||||
|
void Tile::addThing(Thing *thing)
|
||||||
|
{
|
||||||
|
if(!thing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(thing->getType() == Thing::TYPE_ITEM) {
|
||||||
|
const Item *item = thing->getItem();
|
||||||
|
if(item) {
|
||||||
|
ItemAttributes *itemAttributes = g_tibiaDat.getItemAttributes(item->getId());
|
||||||
|
|
||||||
|
if(itemAttributes->alwaysOnTop)
|
||||||
|
m_itemsTop.push_back(thing);
|
||||||
|
else
|
||||||
|
m_itemsBot.push_back(thing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(thing->getType() == Thing::TYPE_CREATURE) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tile::draw(int x, int y)
|
||||||
|
{
|
||||||
|
for(auto it = m_itemsBot.begin(), end = m_itemsBot.end(); it != end; ++it)
|
||||||
|
(*it)->draw(x, y);
|
||||||
|
for(auto it = m_creatures.begin(), end = m_creatures.end(); it != end; ++it)
|
||||||
|
(*it)->draw(x, y);
|
||||||
|
for(auto it = m_itemsTop.begin(), end = m_itemsTop.end(); it != end; ++it)
|
||||||
|
(*it)->draw(x, y);
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef TILE_H
|
||||||
|
#define TILE_H
|
||||||
|
|
||||||
|
#include <global.h>
|
||||||
|
#include "thing.h"
|
||||||
|
|
||||||
|
class Tile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void addThing(Thing *thing);
|
||||||
|
|
||||||
|
void draw(int x, int y);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// ground
|
||||||
|
std::list<Thing*> m_itemsBot;
|
||||||
|
std::list<Thing*> m_creatures;
|
||||||
|
std::list<Thing*> m_itemsTop;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TILE_H
|
Loading…
Reference in New Issue