rework on dat and spr loader

This commit is contained in:
Eduardo Bart 2011-08-15 16:15:49 -03:00
parent b21ccd16f9
commit 2e1a96c2df
43 changed files with 191 additions and 581 deletions

1
.gitignore vendored
View File

@ -10,4 +10,5 @@ otclient.exe
.kdev* .kdev*
otclient.kdev4 otclient.kdev4
CMakeLists.txt.user CMakeLists.txt.user
callgrind.out.*
!.gitignore !.gitignore

View File

@ -1,2 +1,3 @@
Programming Developers
edubart - leader developer <edub4rt@gmail.com> edubart - leader developer <edub4rt@gmail.com>
baxnie - developer <henrique_santiago93@hotmail.com>

View File

@ -58,8 +58,8 @@ SET(SOURCES
# otclient core # otclient core
src/otclient/core/game.cpp src/otclient/core/game.cpp
src/otclient/core/map.cpp src/otclient/core/map.cpp
src/otclient/core/tibiadat.cpp src/otclient/core/datmanager.cpp
src/otclient/core/tibiaspr.cpp src/otclient/core/spritemanager.cpp
src/otclient/core/item.cpp src/otclient/core/item.cpp
src/otclient/core/tile.cpp src/otclient/core/tile.cpp
src/otclient/core/thing.cpp src/otclient/core/thing.cpp

View File

@ -1,6 +1,6 @@
Button < UIButton Button < UIButton
font: helvetica-11px-bold font: helvetica-11px-bold
font-color: 240 173 77 font-color: #f0ad4dff
size: 106 24 size: 106 24
border-image: border-image:
source: /core_ui/images/button.png source: /core_ui/images/button.png

View File

@ -6,7 +6,7 @@ FlatPanel < Panel
border: 4 border: 4
RoundedPanel < Panel RoundedPanel < Panel
color: 255 255 255 192 color: #ffffffc0
border-image: border-image:
source: /core_ui/images/panel_rounded.png source: /core_ui/images/panel_rounded.png
border: 4 border: 4

View File

@ -2,7 +2,7 @@ GFX = { }
function GFX.fadeIn(widget, time, elapsed) function GFX.fadeIn(widget, time, elapsed)
if not elapsed then elapsed = 0 end if not elapsed then elapsed = 0 end
if not time then time = 750 end if not time then time = 250 end
widget.opacity = math.min((255*elapsed)/time, 255) widget.opacity = math.min((255*elapsed)/time, 255)
if elapsed < time then if elapsed < time then
scheduleEvent(function() scheduleEvent(function()
@ -13,7 +13,7 @@ end
function GFX.fadeOut(widget, time, elapsed) function GFX.fadeOut(widget, time, elapsed)
if not elapsed then elapsed = 0 end if not elapsed then elapsed = 0 end
if not time then time = 750 end if not time then time = 250 end
widget.opacity = (255*(time - elapsed))/time widget.opacity = (255*(time - elapsed))/time
if elapsed < time then if elapsed < time then
scheduleEvent(function() scheduleEvent(function()

View File

@ -89,10 +89,9 @@ void ResourceManager::loadFile(const std::string& fileName, std::iostream& out)
} else { } else {
int fileSize = PHYSFS_fileLength(file); int fileSize = PHYSFS_fileLength(file);
if(fileSize > 0) { if(fileSize > 0) {
char* buffer = new char[fileSize]; std::vector<char> buffer(fileSize);
PHYSFS_read(file, (void*)buffer, 1, fileSize); PHYSFS_read(file, (void*)&buffer[0], 1, fileSize);
out.write(buffer, fileSize); out.write(&buffer[0], fileSize);
delete[] buffer;
} else } else
out.clear(std::ios::eofbit); out.clear(std::ios::eofbit);
PHYSFS_close(file); PHYSFS_close(file);
@ -124,10 +123,9 @@ bool ResourceManager::saveFile(const std::string& fileName, std::istream& in)
in.seekg(0, std::ios::end); in.seekg(0, std::ios::end);
std::streampos size = in.tellg(); std::streampos size = in.tellg();
in.seekg(0, std::ios::beg); in.seekg(0, std::ios::beg);
char* buffer = new char[size]; std::vector<char> buffer(size);
in.read(buffer, size); in.read(&buffer[0], size);
bool ret = saveFile(fileName, (const uchar*)buffer, size); bool ret = saveFile(fileName, (const uchar*)&buffer[0], size);
delete[] buffer;
in.seekg(oldPos, std::ios::beg); in.seekg(oldPos, std::ios::beg);
return ret; return ret;
} }
@ -145,10 +143,10 @@ bool ResourceManager::deleteFile(const std::string& fileName)
std::list<std::string> ResourceManager::listDirectoryFiles(const std::string& directoryPath) std::list<std::string> ResourceManager::listDirectoryFiles(const std::string& directoryPath)
{ {
std::list<std::string> files; std::list<std::string> files;
char** rc = PHYSFS_enumerateFiles(resolvePath(directoryPath).c_str()); auto rc = PHYSFS_enumerateFiles(resolvePath(directoryPath).c_str());
for(char** i = rc; *i != NULL; i++) for(int i = 0; rc[i] != NULL; i++)
files.push_back(*i); files.push_back(rc[i]);
PHYSFS_freeList(rc); PHYSFS_freeList(rc);
return files; return files;

View File

@ -29,6 +29,7 @@
#include <typeinfo> #include <typeinfo>
#include <array> #include <array>
#include <iomanip> #include <iomanip>
#include <unordered_map>
// boost utilities // boost utilities
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>

View File

@ -12,8 +12,8 @@ AnimatedTexture::AnimatedTexture(int width, int height, int channels, int numFra
{ {
m_size.setSize(width, height); m_size.setSize(width, height);
m_framesTextureId = new uint[numFrames]; m_framesTextureId.resize(numFrames);
m_framesDelay = new int[numFrames]; m_framesDelay.resize(numFrames);
for(int i=0;i<numFrames;++i) { for(int i=0;i<numFrames;++i) {
uchar *framePixels = framesPixels + (i*height*width* channels); uchar *framePixels = framesPixels + (i*height*width* channels);
@ -29,9 +29,8 @@ AnimatedTexture::AnimatedTexture(int width, int height, int channels, int numFra
AnimatedTexture::~AnimatedTexture() AnimatedTexture::~AnimatedTexture()
{ {
glDeleteTextures(m_numFrames, m_framesTextureId); assert(!g_graphics.isDrawing());
delete[] m_framesTextureId; glDeleteTextures(m_numFrames, &m_framesTextureId[0]);
delete[] m_framesDelay;
m_textureId = 0; m_textureId = 0;
} }

View File

@ -7,14 +7,14 @@ class AnimatedTexture : public Texture
{ {
public: public:
AnimatedTexture(int width, int height, int channels, int numFrames, uchar *framesPixels, int *framesDelay); AnimatedTexture(int width, int height, int channels, int numFrames, uchar *framesPixels, int *framesDelay);
~AnimatedTexture(); virtual ~AnimatedTexture();
void enableBilinearFilter(); void enableBilinearFilter();
void processAnimation(); void processAnimation();
private: private:
uint *m_framesTextureId; std::vector<uint> m_framesTextureId;
int *m_framesDelay; std::vector<int> m_framesDelay;
int m_numFrames; int m_numFrames;
int m_currentFrame; int m_currentFrame;
int m_lastAnimCheckTicks; int m_lastAnimCheckTicks;

View File

@ -224,7 +224,7 @@ Size Font::calculateTextRectSize(const std::string& text)
void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize) void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
{ {
int numHorizontalGlyphs = m_texture->getSize().width() / glyphSize.width(); int numHorizontalGlyphs = m_texture->getSize().width() / glyphSize.width();
uchar *texturePixels = m_texture->getPixels(); auto texturePixels = m_texture->getPixels();
// small AI to auto calculate pixels widths // small AI to auto calculate pixels widths
for(int glyph = m_firstGlyph; glyph< 256; ++glyph) { for(int glyph = m_firstGlyph; glyph< 256; ++glyph) {
@ -256,6 +256,4 @@ void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
// store glyph size // store glyph size
m_glyphsSize[glyph].setSize(width, m_glyphHeight); m_glyphsSize[glyph].setSize(width, m_glyphHeight);
} }
delete[] texturePixels;
} }

View File

@ -26,13 +26,16 @@ void Graphics::init()
logInfo("OpenGL ", glGetString(GL_VERSION)); logInfo("OpenGL ", glGetString(GL_VERSION));
m_drawing = false; m_drawing = false;
bindColor(Color::white);
m_opacity = 255; m_opacity = 255;
m_emptyTexture = TexturePtr(new Texture);
bindColor(Color::white);
} }
void Graphics::terminate() void Graphics::terminate()
{ {
g_fonts.releaseFonts(); g_fonts.releaseFonts();
m_emptyTexture.reset();
} }
bool Graphics::isExtensionSupported(const char *extension) bool Graphics::isExtensionSupported(const char *extension)
@ -110,7 +113,7 @@ void Graphics::drawTexturedRect(const Rect& screenCoords,
const TexturePtr& texture, const TexturePtr& texture,
const Rect& textureCoords) const Rect& textureCoords)
{ {
if(screenCoords.isEmpty()) if(screenCoords.isEmpty() || texture->getId() == 0)
return; return;
// rect correction for opengl // rect correction for opengl
@ -156,7 +159,7 @@ void Graphics::drawRepeatedTexturedRect(const Rect& screenCoords,
const TexturePtr& texture, const TexturePtr& texture,
const Rect& textureCoords) const Rect& textureCoords)
{ {
if(screenCoords.isEmpty() || textureCoords.isEmpty()) if(screenCoords.isEmpty() || texture->getId() == 0 || textureCoords.isEmpty())
return; return;
if(!m_drawing) { if(!m_drawing) {

View File

@ -50,14 +50,17 @@ public:
void startDrawing(); void startDrawing();
void stopDrawing(); void stopDrawing();
bool isDrawing() const { return m_drawing; }
int getOpacity() const { return m_opacity; } int getOpacity() const { return m_opacity; }
void setOpacity(int opacity) { m_opacity = opacity; } void setOpacity(int opacity) { m_opacity = opacity; }
TexturePtr getEmptyTexture() { return m_emptyTexture; }
private: private:
bool m_drawing; bool m_drawing;
int m_opacity; int m_opacity;
Size m_screenSize; Size m_screenSize;
TexturePtr m_emptyTexture;
}; };
extern Graphics g_graphics; extern Graphics g_graphics;

View File

@ -3,14 +3,29 @@
#include <GL/gl.h> #include <GL/gl.h>
Texture::Texture()
{
m_textureId = 0;
}
Texture::Texture(int width, int height, int channels, uchar *pixels) Texture::Texture(int width, int height, int channels, uchar *pixels)
{ {
// generate opengl texture // generate opengl texture
m_textureId = internalLoadGLTexture(pixels, channels, width, height); m_textureId = internalLoadGLTexture(pixels, channels, width, height);
} }
Texture::~Texture()
{
assert(!g_graphics.isDrawing());
// free texture from gl memory
if(m_textureId > 0)
glDeleteTextures(1, &m_textureId);
}
uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height) uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height)
{ {
assert(!g_graphics.isDrawing());
m_size.setSize(width, height); m_size.setSize(width, height);
// gets max texture size supported by the driver // gets max texture size supported by the driver
@ -30,7 +45,8 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
GLuint id; GLuint id;
glGenTextures(1, &id); glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id); glBindTexture(GL_TEXTURE_2D, id);
bool mustFree = false;
std::vector<uchar> tmp;
// old opengl drivers only accept power of two dimensions // old opengl drivers only accept power of two dimensions
if(!g_graphics.isExtensionSupported("GL_ARB_texture_non_power_of_two") && pixels) { if(!g_graphics.isExtensionSupported("GL_ARB_texture_non_power_of_two") && pixels) {
@ -43,15 +59,13 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
glHeight = glHeight << 1; glHeight = glHeight << 1;
if(m_size != m_glSize) { if(m_size != m_glSize) {
uchar *tmp = new uchar[glHeight*glWidth*channels]; tmp.resize(glHeight*glWidth*channels, 0);
memset(tmp, 0, glHeight*glWidth*channels);
if(pixels) if(pixels)
for(int y=0; y<height; ++y) for(int y=0; y<height; ++y)
for(int x=0; x<width; ++x) for(int x=0; x<width; ++x)
for(int i=0; i<channels; ++i) for(int i=0; i<channels; ++i)
tmp[y*glWidth*channels+x*channels+i] = pixels[y*width*channels+x*channels+i]; tmp[y*glWidth*channels+x*channels+i] = pixels[y*width*channels+x*channels+i];
pixels = tmp; pixels = &tmp[0];
mustFree = true;
} }
m_glSize.setSize(glWidth, glHeight); m_glSize.setSize(glWidth, glHeight);
@ -86,19 +100,9 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
if(mustFree)
delete[] pixels;
return id; return id;
} }
Texture::~Texture()
{
// free texture from gl memory
if(m_textureId)
glDeleteTextures(1, &m_textureId);
}
void Texture::enableBilinearFilter() void Texture::enableBilinearFilter()
{ {
// enable smooth texture // enable smooth texture
@ -107,12 +111,12 @@ void Texture::enableBilinearFilter()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} }
uchar* Texture::getPixels() std::vector<uint8> Texture::getPixels()
{ {
// copy pixels from opengl memory // copy pixels from opengl memory
uchar* pixels = new uchar[m_glSize.area()*4]; std::vector<uint8> pixels(m_glSize.area()*4, 0);
glBindTexture(GL_TEXTURE_2D, m_textureId); glBindTexture(GL_TEXTURE_2D, m_textureId);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
// convert pixels to the real texture size // convert pixels to the real texture size
if(m_size != m_glSize) if(m_size != m_glSize)

View File

@ -7,6 +7,7 @@ class Texture : public std::enable_shared_from_this<Texture>
{ {
public: public:
/// Create a texture, width and height must be a multiple of 2 /// Create a texture, width and height must be a multiple of 2
Texture();
Texture(int width, int height, int channels, uchar* pixels = NULL); Texture(int width, int height, int channels, uchar* pixels = NULL);
virtual ~Texture(); virtual ~Texture();
@ -17,15 +18,16 @@ public:
virtual uint getId() const { return m_textureId; } virtual uint getId() const { return m_textureId; }
/// Copy pixels from OpenGL texture /// Copy pixels from OpenGL texture
uchar* getPixels(); std::vector<uint8> getPixels();
int getWidth() const { return m_size.width(); } int getWidth() const { return m_size.width(); }
int getHeight() const { return m_size.height(); } int getHeight() const { return m_size.height(); }
const Size getSize() const { return m_size; } const Size getSize() const { return m_size; }
const Size& getGlSize() const { return m_glSize; } const Size& getGlSize() const { return m_glSize; }
bool isEmpty() const { return m_textureId == 0; }
protected: protected:
Texture() { }
uint internalLoadGLTexture(uchar* pixels, int channels, int w, int h); uint internalLoadGLTexture(uchar* pixels, int channels, int w, int h);
uint m_textureId; uint m_textureId;

View File

@ -23,25 +23,6 @@ Rsa::~Rsa()
mpz_clear(m_mod); mpz_clear(m_mod);
} }
bool Rsa::setKey(const std::string& file)
{
//loads p,q and d from a file
FILE* f = fopen(file.c_str(), "r");
if(!f){
return false;
}
char p[512];
char q[512];
char d[512];
delete fgets(p, 512, f);
delete fgets(q, 512, f);
delete fgets(d, 512, f);
setKey(p, q, d);
return true;
}
void Rsa::setKey(const char* p, const char* q, const char* d) void Rsa::setKey(const char* p, const char* q, const char* d)
{ {
mpz_set_str(m_p, p, 10); mpz_set_str(m_p, p, 10);

View File

@ -9,8 +9,8 @@ class Rsa
public: public:
Rsa(); Rsa();
~Rsa(); ~Rsa();
void setKey(const char* p, const char* q, const char* d); void setKey(const char* p, const char* q, const char* d);
bool setKey(const std::string& file);
bool decrypt(char* msg, int32_t size); bool decrypt(char* msg, int32_t size);
static bool encrypt(char* msg, int32_t size, const char* key); static bool encrypt(char* msg, int32_t size, const char* key);
@ -20,6 +20,4 @@ protected:
mpz_t m_p, m_q, m_u, m_d, m_dp, m_dq, m_mod; mpz_t m_p, m_q, m_u, m_d, m_dp, m_dq, m_mod;
}; };
typedef std::shared_ptr<Rsa> RsaPtr; #endif
#endif //RSA_H

View File

@ -151,7 +151,7 @@ enum InputKeyCode {
KC_MEDIASELECT = 0xED // Media Select KC_MEDIASELECT = 0xED // Media Select
}; };
enum InputEventType { enum PlatformEventType {
EventNone = 0, EventNone = 0,
EventMouseAction = 1, EventMouseAction = 1,
EventKeyboardAction = 2, EventKeyboardAction = 2,
@ -175,7 +175,7 @@ enum InputEventType {
EventMouseWheelDown = EventMouseAction | EventMouseWheel | EventDown EventMouseWheelDown = EventMouseAction | EventMouseWheel | EventDown
}; };
struct InputEvent { struct PlatformEvent {
int type; int type;
Point mousePos; Point mousePos;
Point mouseMoved; Point mouseMoved;

View File

@ -11,7 +11,7 @@ public:
/// Fired when user resize the window /// Fired when user resize the window
virtual void onResize(const Size& size) = 0; virtual void onResize(const Size& size) = 0;
/// Fired when user press a key or move the mouse /// Fired when user press a key or move the mouse
virtual void onInputEvent(const InputEvent& event) = 0; virtual void onPlatformEvent(const PlatformEvent& event) = 0;
}; };
#endif #endif

View File

@ -260,7 +260,7 @@ void Platform::terminate()
void Platform::poll() void Platform::poll()
{ {
XEvent event, peekevent; XEvent event, peekevent;
static InputEvent inputEvent; static PlatformEvent inputEvent;
while(XPending(x11.display) > 0) { while(XPending(x11.display) > 0) {
XNextEvent(x11.display, &event); XNextEvent(x11.display, &event);
@ -335,7 +335,7 @@ void Platform::poll()
inputEvent.type = EventTextEnter; inputEvent.type = EventTextEnter;
inputEvent.keychar = buf[0]; inputEvent.keychar = buf[0];
inputEvent.keycode = KC_UNKNOWN; inputEvent.keycode = KC_UNKNOWN;
m_listener->onInputEvent(inputEvent); m_listener->onPlatformEvent(inputEvent);
} }
} }
@ -348,7 +348,7 @@ void Platform::poll()
inputEvent.keycode = x11.keyMap[keysym]; inputEvent.keycode = x11.keyMap[keysym];
inputEvent.type = (event.type == KeyPress) ? EventKeyDown : EventKeyUp; inputEvent.type = (event.type == KeyPress) ? EventKeyDown : EventKeyUp;
inputEvent.keychar = (len > 0) ? buf[0] : 0; inputEvent.keychar = (len > 0) ? buf[0] : 0;
m_listener->onInputEvent(inputEvent); m_listener->onPlatformEvent(inputEvent);
} }
break; break;
} }
@ -371,7 +371,7 @@ void Platform::poll()
inputEvent.type = EventMouseWheelDown; inputEvent.type = EventMouseWheelDown;
break; break;
} }
m_listener->onInputEvent(inputEvent); m_listener->onPlatformEvent(inputEvent);
break; break;
case MotionNotify: case MotionNotify:
@ -380,7 +380,7 @@ void Platform::poll()
Point newMousePos(event.xbutton.x, event.xbutton.y); Point newMousePos(event.xbutton.x, event.xbutton.y);
inputEvent.mouseMoved = newMousePos - inputEvent.mousePos; inputEvent.mouseMoved = newMousePos - inputEvent.mousePos;
inputEvent.mousePos = newMousePos; inputEvent.mousePos = newMousePos;
m_listener->onInputEvent(inputEvent); m_listener->onPlatformEvent(inputEvent);
break; break;
} }

View File

@ -37,7 +37,7 @@ void UIManager::resize(const Size& size)
m_rootWidget->resize(size); m_rootWidget->resize(size);
} }
void UIManager::inputEvent(const InputEvent& event) void UIManager::inputEvent(const PlatformEvent& event)
{ {
// translate input event to ui events // translate input event to ui events
if(m_rootWidget) { if(m_rootWidget) {

View File

@ -13,7 +13,7 @@ public:
void render(); void render();
void resize(const Size& size); void resize(const Size& size);
void inputEvent(const InputEvent& event); void inputEvent(const PlatformEvent& event);
bool importStyles(const std::string& file); bool importStyles(const std::string& file);
void importStyleFromOTML(const OTMLNodePtr& styleNode); void importStyleFromOTML(const OTMLNodePtr& styleNode);

View File

@ -26,6 +26,7 @@ public:
void setGreen(uint8 g) { color = ((g & 0xff)<<8) | (color & 0xffff00ff); } void setGreen(uint8 g) { color = ((g & 0xff)<<8) | (color & 0xffff00ff); }
void setRed(uint8 r) { color = (r & 0xff) | (color & 0xffffff00); } void setRed(uint8 r) { color = (r & 0xff) | (color & 0xffffff00); }
void setRGBA(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) { color = ((a & 0xff)<<24) | ((b & 0xff)<<16) | ((g & 0xff)<<8) | (r & 0xff); } void setRGBA(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) { color = ((a & 0xff)<<24) | ((b & 0xff)<<16) | ((g & 0xff)<<8) | (r & 0xff); }
void setABGR(uint32 abgr) { color = ((abgr>>24) & 0xff) | ((abgr>>16) & 0xff) << 8 | ((abgr>>8) & 0xff) << 16 | (abgr & 0xff) << 24; }
void setRGBA(uint32 rgba) { color = rgba; } void setRGBA(uint32 rgba) { color = rgba; }
Color& operator=(const Color& other) { color = other.color; return *this; } Color& operator=(const Color& other) { color = other.color; return *this; }
@ -47,17 +48,26 @@ private:
inline std::ostream& operator<<(std::ostream& out, const Color& color) inline std::ostream& operator<<(std::ostream& out, const Color& color)
{ {
out << (int)color.r() << " "<< (int)color.g() << " "<< (int)color.b() << " " << (int)color.a(); using namespace std;
out << "#" << hex << setfill('0')
<< setw(2) << (int)color.r()
<< setw(2) << (int)color.g()
<< setw(2) << (int)color.b()
<< setw(2) << (int)color.a();
out << dec << setfill(' ');
return out; return out;
} }
inline std::istream& operator>>(std::istream& in, Color& color) inline std::istream& operator>>(std::istream& in, Color& color)
{ {
int r, g, b, a = 255; using namespace std;
in >> r >> g >> b;
if(!in.eof()) if(in.get() == '#') {
in >> a; uint32 tmp;
color.setRGBA(r, g, b, a); in >> hex >> tmp;
color.setABGR(tmp);
in >> dec;
}
return in; return in;
} }

View File

@ -10,6 +10,25 @@
namespace fw { namespace fw {
// read utilities for istream
inline uint8 getu8(std::istream& in) {
uint8 tmp;
in.read((char*)&tmp, 1);
return tmp;
}
inline uint16 getu16(std::istream& in) {
uint16 tmp;
in.read((char*)&tmp, 2);
return tmp;
}
inline uint32 getu32(std::istream& in) {
uint32 tmp;
in.read((char*)&tmp, 4);
return tmp;
}
/// Fill an ostream by concatenating args /// Fill an ostream by concatenating args
/// Usage: /// Usage:
/// fw::fill_ostream(stream, a1, a2, ..., aN); /// fw::fill_ostream(stream, a1, a2, ..., aN);

View File

@ -1,5 +1,5 @@
#include "creature.h" #include "creature.h"
#include "tibiadat.h" #include "datmanager.h"
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
#include <framework/graphics/framebuffer.h> #include <framework/graphics/framebuffer.h>
#include "game.h" #include "game.h"
@ -26,9 +26,9 @@ Creature::Creature()
m_type = Thing::TYPE_CREATURE; m_type = Thing::TYPE_CREATURE;
} }
ThingAttributes *Creature::getAttributes() const ThingAttributes& Creature::getAttributes()
{ {
return g_tibiaDat.getCreatureAttributes(m_outfit.type); return g_dat.getCreatureAttributes(m_outfit.type);
} }
void Creature::draw(int x, int y) void Creature::draw(int x, int y)

View File

@ -18,7 +18,7 @@ class Creature : public Thing
public: public:
Creature(); Creature();
virtual ThingAttributes *getAttributes(); virtual const ThingAttributes& getAttributes();
void draw(int x, int y); void draw(int x, int y);
void setName(const std::string& name) { m_name = name; } void setName(const std::string& name) { m_name = name; }

View File

@ -1,14 +1,14 @@
#include "effect.h" #include "effect.h"
#include "tibiadat.h" #include "datmanager.h"
Effect::Effect() Effect::Effect()
{ {
m_type = Thing::TYPE_EFFECT; m_type = Thing::TYPE_EFFECT;
} }
ThingAttributes *Effect::getAttributes() const ThingAttributes& Effect::getAttributes()
{ {
return g_tibiaDat.getEffectAttributes(m_id); return g_dat.getEffectAttributes(m_id);
} }
void Effect::draw(int x, int y) void Effect::draw(int x, int y)

View File

@ -10,7 +10,7 @@ class Effect : public Thing
public: public:
Effect(); Effect();
virtual ThingAttributes *getAttributes(); virtual const ThingAttributes& getAttributes();
void draw(int x, int y); void draw(int x, int y);
private: private:

View File

@ -1,6 +1,6 @@
#include "item.h" #include "item.h"
#include "tibiadat.h" #include "datmanager.h"
#include "tibiaspr.h" #include "spritemanager.h"
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
#include "thing.h" #include "thing.h"
@ -9,27 +9,27 @@ Item::Item()
m_type = Thing::TYPE_ITEM; m_type = Thing::TYPE_ITEM;
} }
ThingAttributes *Item::getAttributes() const ThingAttributes& Item::getAttributes()
{ {
return g_tibiaDat.getItemAttributes(m_id); return g_dat.getItemAttributes(m_id);
} }
void Item::draw(int x, int y) void Item::draw(int x, int y)
{ {
ThingAttributes *itemAttributes = getAttributes(); auto attributes = g_dat.getItemAttributes(m_id);
int xdiv = 0, ydiv = 0, zdiv = 0, anim = 0; int xdiv = 0, ydiv = 0, zdiv = 0, anim = 0;
if(itemAttributes->group == THING_GROUP_SPLASH || itemAttributes->group == THING_GROUP_FLUID || itemAttributes->stackable) { if(attributes.group == THING_GROUP_SPLASH || attributes.group == THING_GROUP_FLUID || attributes.stackable) {
//cDivX = subType % itemAttributes->xdiv; //cDivX = subType % itemAttributes->xdiv;
//cDivY = subType / itemAttributes->xdiv; //cDivY = subType / itemAttributes->xdiv;
} }
else if(!itemAttributes->moveable) { else if(!attributes.moveable) {
xdiv = m_position.x % itemAttributes->xdiv; xdiv = m_position.x % attributes.xdiv;
ydiv = m_position.y % itemAttributes->ydiv; ydiv = m_position.y % attributes.ydiv;
zdiv = m_position.z % itemAttributes->zdiv; zdiv = m_position.z % attributes.zdiv;
} }
for(int b = 0; b < itemAttributes->blendframes; b++) for(int b = 0; b < attributes.blendframes; b++)
internalDraw(x, y, b, xdiv, ydiv, zdiv, anim); internalDraw(x, y, b, xdiv, ydiv, zdiv, anim);
} }

View File

@ -9,7 +9,7 @@ class Item : public Thing
public: public:
Item(); Item();
virtual ThingAttributes *getAttributes(); virtual const ThingAttributes& getAttributes();
void draw(int x, int y); void draw(int x, int y);
void setCount(uint8 count) { m_count = count; } void setCount(uint8 count) { m_count = count; }

View File

@ -4,7 +4,6 @@
#include "tile.h" #include "tile.h"
#include "effect.h" #include "effect.h"
#include <framework/graphics/declarations.h> #include <framework/graphics/declarations.h>
#include <unordered_map>
struct MapPositionHasher : std::unary_function<Position, std::size_t> { struct MapPositionHasher : std::unary_function<Position, std::size_t> {
std::size_t operator()(const Position& pos) const { std::size_t operator()(const Position& pos) const {

View File

@ -1,5 +1,5 @@
#include "thing.h" #include "thing.h"
#include "tibiaspr.h" #include "spritemanager.h"
#include <framework/graphics/graphics.h> #include <framework/graphics/graphics.h>
ThingAttributes::ThingAttributes() ThingAttributes::ThingAttributes()
@ -28,7 +28,6 @@ ThingAttributes::ThingAttributes()
hasMiniMapColor = false; hasMiniMapColor = false;
subParam07 = 0; subParam07 = 0;
subParam08 = 0; subParam08 = 0;
sprites = NULL;
width = 0; width = 0;
height = 0; height = 0;
blendframes = 0; blendframes = 0;
@ -40,12 +39,6 @@ ThingAttributes::ThingAttributes()
yOffset = 0; yOffset = 0;
} }
ThingAttributes::~ThingAttributes()
{
if(sprites)
delete []sprites;
}
Thing::Thing() Thing::Thing()
{ {
m_type = TYPE_NONE; m_type = TYPE_NONE;
@ -53,31 +46,33 @@ Thing::Thing()
void Thing::internalDraw(int x, int y, int blendframes, int xdiv, int ydiv, int zdiv, int anim) void Thing::internalDraw(int x, int y, int blendframes, int xdiv, int ydiv, int zdiv, int anim)
{ {
ThingAttributes *thingAttributes = getAttributes(); const ThingAttributes& attributes = getAttributes();
if(!thingAttributes)
return;
for(int yi = 0; yi < thingAttributes->height; yi++) { for(int yi = 0; yi < attributes.height; yi++) {
for(int xi = 0; xi < thingAttributes->width; xi++) { for(int xi = 0; xi < attributes.width; xi++) {
uint16 sprIndex = xi + int sprIndex = xi +
yi * thingAttributes->width + yi * attributes.width +
blendframes * thingAttributes->width * thingAttributes->height + blendframes * attributes.width * attributes.height +
xdiv * thingAttributes->width * thingAttributes->height * thingAttributes->blendframes + xdiv * attributes.width * attributes.height * attributes.blendframes +
ydiv * thingAttributes->width * thingAttributes->height * thingAttributes->blendframes * thingAttributes->xdiv + ydiv * attributes.width * attributes.height * attributes.blendframes * attributes.xdiv +
zdiv * thingAttributes->width * thingAttributes->height * thingAttributes->blendframes * thingAttributes->xdiv * thingAttributes->ydiv + zdiv * attributes.width * attributes.height * attributes.blendframes * attributes.xdiv * attributes.ydiv +
anim * thingAttributes->width * thingAttributes->height * thingAttributes->blendframes * thingAttributes->xdiv * thingAttributes->ydiv * thingAttributes->zdiv; anim * attributes.width * attributes.height * attributes.blendframes * attributes.xdiv * attributes.ydiv * attributes.zdiv;
uint16 itemId = thingAttributes->sprites[sprIndex];
if(itemId == 0xFFFF) int spriteId = attributes.sprites[sprIndex];
if(!spriteId)
continue;
TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId);
if(spriteTex->isEmpty())
continue; continue;
TexturePtr data = g_tibiaSpr.getSprite(itemId);
int offsetX = 0, offsetY = 0; int offsetX = 0, offsetY = 0;
if(thingAttributes->hasHeight) { if(attributes.hasHeight) {
offsetX = thingAttributes->xOffset; offsetX = attributes.xOffset;
offsetY = thingAttributes->xOffset; // << look to xoffset offsetY = attributes.xOffset; // << look to xoffset
} }
g_graphics.drawTexturedRect(Rect((x - xi*32) - offsetX, (y - yi*32) - offsetY, 32, 32), data, Rect(0, 0, 32, 32)); g_graphics.drawTexturedRect(Rect((x - xi*32) - offsetX, (y - yi*32) - offsetY, 32, 32), spriteTex, Rect(0, 0, 32, 32));
} }
} }
} }

View File

@ -7,22 +7,15 @@
struct ThingAttributes struct ThingAttributes
{ {
ThingAttributes(); ThingAttributes();
~ThingAttributes();
bool stackable, alwaysOnTop, useable, readable, moveable, blockSolid, blockProjectile, blockPathFind, pickupable, bool stackable, alwaysOnTop, useable, readable, moveable, blockSolid, blockProjectile, blockPathFind, pickupable,
isHangable, isHorizontal, isVertical, rotable, hasHeight, lookThrough, hasMiniMapColor; isHangable, isHorizontal, isVertical, rotable, hasHeight, lookThrough, hasMiniMapColor;
uint8 alwaysOnTopOrder, width, height, blendframes, xdiv, ydiv, zdiv, animcount, xOffset, yOffset; uint8 alwaysOnTopOrder, width, height, blendframes, xdiv, ydiv, zdiv, animcount, xOffset, yOffset;
uint16 id, speed, subParam07, subParam08, lightLevel, lightColor, miniMapColor; uint16 speed, subParam07, subParam08, lightLevel, lightColor, miniMapColor;
uint16 *sprites; std::vector<int> sprites;
ThingAttributesGroup group; ThingAttributesGroup group;
}; };
class Creature;
class Item;
class Thing;
typedef std::shared_ptr<Thing> ThingPtr;
class Thing class Thing
{ {
public: public:
@ -46,7 +39,7 @@ public:
Position *getPosition() { return &m_position; } Position *getPosition() { return &m_position; }
virtual void draw(int, int) {} virtual void draw(int, int) {}
virtual ThingAttributes *getAttributes() { return NULL; } virtual const ThingAttributes& getAttributes() = 0;
virtual Item* getItem() { return NULL; } virtual Item* getItem() { return NULL; }
virtual const Item *getItem() const { return NULL; } virtual const Item *getItem() const { return NULL; }
@ -62,4 +55,4 @@ protected:
}; };
#endif // THING_H #endif

View File

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

View File

@ -1,31 +0,0 @@
#ifndef TIBIADAT_H
#define TIBIADAT_H
#include <framework/global.h>
#include "thing.h"
class TibiaDat
{
public:
bool load(const std::string& filename);
ThingAttributes *getItemAttributes(uint16 id);
ThingAttributes *getCreatureAttributes(uint16 id);
ThingAttributes *getEffectAttributes(uint16 id);
ThingAttributes *getShotAttributes(uint16 id);
uint16 getGroupCount(int i) { return m_groupCount[i]; }
uint32 getSignature() { return m_signature; }
uint16 getTotalCount() { return m_totalCount; }
private:
uint32 m_signature, m_totalCount;
uint16 m_groupCount[4];
ThingAttributes **m_thingsAttributes;
};
extern TibiaDat g_tibiaDat;
#endif // TIBIADAT_H

View File

@ -1,120 +0,0 @@
#include "tibiaspr.h"
#include <framework/core/resourcemanager.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)
{
g_resources.loadFile(filename, m_fin);
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];
}

View File

@ -1,31 +0,0 @@
#ifndef TIBIASPR_H
#define TIBIASPR_H
#include <framework/global.h>
#include <framework/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

View File

@ -1,10 +1,10 @@
#include "tile.h" #include "tile.h"
#include "item.h" #include "item.h"
#include "tibiadat.h" #include "datmanager.h"
Tile::Tile() Tile::Tile()
{ {
m_ground = NULL;
} }
void Tile::addThing(ThingPtr thing, uint8 stackpos) void Tile::addThing(ThingPtr thing, uint8 stackpos)
@ -12,23 +12,19 @@ void Tile::addThing(ThingPtr thing, uint8 stackpos)
if(!thing) if(!thing)
return; return;
ThingAttributes *thingAttributes = thing->getAttributes(); const ThingAttributes& thingAttributes = thing->getAttributes();
if(thingAttributes) { if(thing->getType() == Thing::TYPE_ITEM) {
if(thing->getType() == Thing::TYPE_ITEM) { if(thingAttributes.group == THING_GROUP_GROUND)
if(thingAttributes->group == THING_GROUP_GROUND) m_ground = thing;
m_ground = thing; else {
else { if(thingAttributes.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) {
m_creatures.push_back(thing);
} }
} else if(thing->getType() == Thing::TYPE_CREATURE) {
m_creatures.push_back(thing);
} }
} }
void Tile::draw(int x, int y) void Tile::draw(int x, int y)
@ -36,20 +32,14 @@ void Tile::draw(int x, int y)
if(m_ground) if(m_ground)
m_ground->draw(x, y); m_ground->draw(x, y);
for(auto it = m_itemsTop.begin(), end = m_itemsTop.end(); it != end; ++it) for(const ThingPtr& thing : m_itemsBot)
(*it)->draw(x, y); thing->draw(x, y);
for(auto it = m_creatures.begin(), end = m_creatures.end(); it != end; ++it) for(const ThingPtr& thing : m_creatures)
(*it)->draw(x, y); thing->draw(x, y);
for(auto it = m_itemsBot.begin(), end = m_itemsBot.end(); it != end; ++it) for(const ThingPtr& thing : m_itemsTop)
(*it)->draw(x, y); thing->draw(x, y);
}
bool Tile::hasGround()
{
return m_ground != 0;
} }
int Tile::getStackSize() int Tile::getStackSize()
@ -57,10 +47,8 @@ int Tile::getStackSize()
int ret = 0; int ret = 0;
if(m_ground) if(m_ground)
ret++; ret++;
ret += m_itemsBot.size(); ret += m_itemsBot.size();
ret += m_creatures.size(); ret += m_creatures.size();
ret += m_itemsTop.size(); ret += m_itemsTop.size();
return ret; return ret;
} }

View File

@ -11,14 +11,16 @@ public:
void addThing(ThingPtr thing, uint8 stackpos); void addThing(ThingPtr thing, uint8 stackpos);
void draw(int x, int y); void draw(int x, int y);
bool hasGround();
bool hasGround() { return (!!m_ground); }
int getStackSize(); int getStackSize();
private: private:
ThingPtr m_ground; ThingPtr m_ground;
std::list<ThingPtr> m_itemsBot; std::deque<ThingPtr> m_itemsBot;
std::list<ThingPtr> m_creatures; std::deque<ThingPtr> m_creatures;
std::list<ThingPtr> m_itemsTop; std::deque<ThingPtr> m_itemsTop;
}; };
#endif #endif

View File

@ -1,7 +1,7 @@
#include "protocolgame.h" #include "protocolgame.h"
#include <otclient/core/player.h> #include <otclient/core/player.h>
#include <otclient/core/tibiadat.h> #include <otclient/core/datmanager.h>
#include <otclient/core/game.h> #include <otclient/core/game.h>
#include <otclient/core/map.h> #include <otclient/core/map.h>
#include <otclient/core/effect.h> #include <otclient/core/effect.h>
@ -926,9 +926,10 @@ ItemPtr ProtocolGame::internalGetItem(InputMessage& msg, uint16 id)
id = msg.getU16(); id = msg.getU16();
item->setId(id); item->setId(id);
ThingAttributes *itemAttributes = g_tibiaDat.getItemAttributes(id); const ThingAttributes& itemAttributes = g_dat.getItemAttributes(id);
if(itemAttributes->stackable || itemAttributes->group == THING_GROUP_FLUID || itemAttributes->group == THING_GROUP_SPLASH) if(itemAttributes.stackable || itemAttributes.group == THING_GROUP_FLUID || itemAttributes.group == THING_GROUP_SPLASH) {
item->setCount(msg.getU8()); item->setCount(msg.getU8());
}
return item; return item;
} }

View File

@ -199,6 +199,7 @@ void OTClient::poll()
void OTClient::render() void OTClient::render()
{ {
//TODO: UIMap for map drawing
if(g_game.getOnline()) if(g_game.getOnline())
g_game.getMap()->draw(0, 0); g_game.getMap()->draw(0, 0);
@ -258,7 +259,7 @@ void OTClient::onResize(const Size& size)
g_ui.resize(size); g_ui.resize(size);
} }
void OTClient::onInputEvent(const InputEvent& event) void OTClient::onPlatformEvent(const PlatformEvent& event)
{ {
g_ui.inputEvent(event); g_ui.inputEvent(event);

View File

@ -25,7 +25,7 @@ public:
/// Fired when user resize the window /// Fired when user resize the window
void onResize(const Size& size); void onResize(const Size& size);
/// Fired on an user input event /// Fired on an user input event
void onInputEvent(const InputEvent& event); void onPlatformEvent(const PlatformEvent& event);
bool isRunning() const { return m_running; } bool isRunning() const { return m_running; }

View File

@ -1,8 +1,8 @@
#include "otclient.h" #include "otclient.h"
#include <framework/luascript/luainterface.h> #include <framework/luascript/luainterface.h>
#include <otclient/core/tibiadat.h> #include <otclient/core/datmanager.h>
#include <otclient/core/tibiaspr.h> #include <otclient/core/spritemanager.h>
#include <otclient/net/protocollogin.h> #include <otclient/net/protocollogin.h>
#include <otclient/net/protocolgame.h> #include <otclient/net/protocolgame.h>
@ -13,8 +13,8 @@ void OTClient::registerLuaFunctions()
g_lua.bindGlobalFunction("exit", std::bind(&OTClient::exit, &g_client)); g_lua.bindGlobalFunction("exit", std::bind(&OTClient::exit, &g_client));
g_lua.bindGlobalFunction("setOnClose", std::bind(&OTClient::setOnClose, &g_client, _1)); g_lua.bindGlobalFunction("setOnClose", std::bind(&OTClient::setOnClose, &g_client, _1));
g_lua.bindGlobalFunction("importDat", std::bind(&TibiaDat::load, &g_tibiaDat, _1)); g_lua.bindGlobalFunction("importDat", std::bind(&DatManager::load, &g_dat, _1));
g_lua.bindGlobalFunction("importSpr", std::bind(&TibiaSpr::load, &g_tibiaSpr, _1)); g_lua.bindGlobalFunction("importSpr", std::bind(&SpriteManager::load, &g_sprites, _1));
g_lua.registerClass<ProtocolLogin, Protocol>(); g_lua.registerClass<ProtocolLogin, Protocol>();
g_lua.bindClassStaticFunction<ProtocolLogin>("create", &ProtocolLogin::create); g_lua.bindClassStaticFunction<ProtocolLogin>("create", &ProtocolLogin::create);