parent
2e1a96c2df
commit
be15b1820d
@ -0,0 +1,209 @@
|
||||
#include "datmanager.h"
|
||||
#include "spritemanager.h"
|
||||
#include <framework/core/resourcemanager.h>
|
||||
|
||||
DatManager g_dat;
|
||||
|
||||
bool DatManager::load(const std::string& filename)
|
||||
{
|
||||
try {
|
||||
std::stringstream fin;
|
||||
g_resources.loadFile(filename, fin);
|
||||
|
||||
m_signature = fw::getu32(fin);
|
||||
int numItems = fw::getu16(fin);
|
||||
int numCreatures = fw::getu16(fin);
|
||||
int numEffects = fw::getu16(fin);
|
||||
int numShots = fw::getu16(fin);
|
||||
|
||||
m_itemsAttributes.resize(numItems);
|
||||
for(int id = 100; id <= numItems; ++id)
|
||||
parseThingAttributes(fin, m_itemsAttributes[id - 100]);
|
||||
|
||||
m_creaturesAttributes.resize(numItems);
|
||||
for(int id = 1; id < numCreatures; ++id)
|
||||
parseThingAttributes(fin, m_creaturesAttributes[id - 1]);
|
||||
|
||||
m_effectsAttributes.resize(numItems);
|
||||
for(int id = 100; id < numEffects; ++id)
|
||||
parseThingAttributes(fin, m_effectsAttributes[id - 100]);
|
||||
|
||||
m_shotsAttributes.resize(numItems);
|
||||
for(int id = 1; id < numShots; ++id)
|
||||
parseThingAttributes(fin, m_shotsAttributes[id - 1]);
|
||||
|
||||
return true;
|
||||
} catch(std::exception& e) {
|
||||
logError(e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void DatManager::unload()
|
||||
{
|
||||
m_itemsAttributes.clear();
|
||||
m_creaturesAttributes.clear();
|
||||
m_effectsAttributes.clear();
|
||||
m_shotsAttributes.clear();
|
||||
}
|
||||
|
||||
void DatManager::parseThingAttributes(std::stringstream& fin, ThingAttributes& thingAttributes)
|
||||
{
|
||||
assert(fin.good());
|
||||
|
||||
while(true) {
|
||||
uint8 opt;
|
||||
fin.read((char*)&opt, 1);
|
||||
|
||||
if(opt == 0xFF)
|
||||
break;
|
||||
|
||||
parseThingAttributesOpt(fin, thingAttributes, opt);
|
||||
}
|
||||
|
||||
thingAttributes.width = fw::getu8(fin);
|
||||
thingAttributes.height = fw::getu8(fin);
|
||||
if(thingAttributes.width > 1 || thingAttributes.height > 1)
|
||||
fw::getu8(fin); // ??
|
||||
|
||||
thingAttributes.blendframes = fw::getu8(fin);
|
||||
thingAttributes.xdiv = fw::getu8(fin);
|
||||
thingAttributes.ydiv = fw::getu8(fin);
|
||||
thingAttributes.zdiv = fw::getu8(fin);
|
||||
thingAttributes.animcount = fw::getu8(fin);
|
||||
|
||||
int totalSprites = thingAttributes.width
|
||||
* thingAttributes.height
|
||||
* thingAttributes.blendframes
|
||||
* thingAttributes.xdiv
|
||||
* thingAttributes.ydiv
|
||||
* thingAttributes.zdiv
|
||||
* thingAttributes.animcount;
|
||||
|
||||
thingAttributes.sprites.resize(totalSprites);
|
||||
for(uint16 i = 0; i < totalSprites; i++)
|
||||
thingAttributes.sprites[i] = fw::getu16(fin);
|
||||
}
|
||||
|
||||
void DatManager::parseThingAttributesOpt(std::stringstream& fin, ThingAttributes& thingAttributes, uint8 opt)
|
||||
{
|
||||
uint8 read_byte;
|
||||
uint16 read_short;
|
||||
switch(opt) {
|
||||
case 0x00: // Ground tile
|
||||
fin.read((char*)&thingAttributes.speed, 2);
|
||||
thingAttributes.group = THING_GROUP_GROUND;
|
||||
break;
|
||||
case 0x01: // All OnTop
|
||||
thingAttributes.alwaysOnTop = true;
|
||||
thingAttributes.alwaysOnTopOrder = 1;
|
||||
break;
|
||||
case 0x02: // Can walk trough (open doors, arces, bug pen fence)
|
||||
thingAttributes.alwaysOnTop = true;
|
||||
thingAttributes.alwaysOnTopOrder = 2;
|
||||
break;
|
||||
case 0x03: // Can walk trough (arces)
|
||||
thingAttributes.alwaysOnTop = true;
|
||||
thingAttributes.alwaysOnTopOrder = 3;
|
||||
break;
|
||||
case 0x04: // Container
|
||||
thingAttributes.group = THING_GROUP_CONTAINER;
|
||||
break;
|
||||
case 0x05: // Stackable
|
||||
thingAttributes.stackable = true;
|
||||
break;
|
||||
case 0x06: // Unknown
|
||||
break;
|
||||
case 0x07: // Useable
|
||||
thingAttributes.useable = true;
|
||||
break;
|
||||
case 0x08: // Writtable
|
||||
thingAttributes.group = THING_GROUP_WRITEABLE;
|
||||
thingAttributes.readable = true;
|
||||
fin.read((char*)&thingAttributes.subParam07, 2);
|
||||
break;
|
||||
case 0x09: // Writtable once
|
||||
// Writtable objects that can't be edited by players
|
||||
thingAttributes.readable = true;
|
||||
fin.read((char*)&thingAttributes.subParam08, 2);
|
||||
break;
|
||||
case 0x0A: // Fluid containers
|
||||
fin.read((char*)&read_byte, 1);
|
||||
thingAttributes.group = THING_GROUP_FLUID;
|
||||
break;
|
||||
case 0x0B: // Splashes
|
||||
thingAttributes.group = THING_GROUP_SPLASH;
|
||||
break;
|
||||
case 0x0C: // Blocks solid objects (creatures, walls etc)
|
||||
thingAttributes.blockSolid = true;
|
||||
break;
|
||||
case 0x0D: // Not moveable
|
||||
thingAttributes.moveable = false;
|
||||
break;
|
||||
case 0x0E: // Blocks missiles (walls, magic wall etc)
|
||||
thingAttributes.blockProjectile = true;
|
||||
break;
|
||||
case 0x0F: // Blocks pathfind algorithms (monsters)
|
||||
thingAttributes.blockPathFind = true;
|
||||
break;
|
||||
case 0x10: // Blocks monster movement (flowers, parcels etc)
|
||||
thingAttributes.pickupable = true;
|
||||
break;
|
||||
case 0x11: // Hangable objects (wallpaper etc)
|
||||
thingAttributes.isHangable = true;
|
||||
break;
|
||||
case 0x12: // Horizontal wall
|
||||
thingAttributes.isHorizontal = true;
|
||||
break;
|
||||
case 0x13: // Vertical wall
|
||||
thingAttributes.isVertical = true;
|
||||
break;
|
||||
case 0x14: // Rotable
|
||||
thingAttributes.rotable = true;
|
||||
break;
|
||||
case 0x15: // Light info
|
||||
fin.read((char*)&thingAttributes.lightLevel, 2);
|
||||
fin.read((char*)&thingAttributes.lightColor, 2);
|
||||
break;
|
||||
case 0x16:
|
||||
break;
|
||||
case 0x17: // Changes floor
|
||||
break;
|
||||
case 0x18: // Thing must be drawed with offset
|
||||
thingAttributes.hasHeight = true;
|
||||
fin.read((char*)&thingAttributes.xOffset, 1);
|
||||
fin.read((char*)&thingAttributes.yOffset, 1);
|
||||
|
||||
fin.read((char*)&read_short, 2);
|
||||
break;
|
||||
case 0x19: // pixels characters height
|
||||
|
||||
fin.read((char*)&thingAttributes.xOffset, 1);
|
||||
fin.read((char*)&thingAttributes.yOffset, 1);
|
||||
//logDebug((int)thingAttributes.xOffset, " ", (int)thingAttributes.yOffset);
|
||||
break;
|
||||
case 0x1A:
|
||||
//thingAttributes.hasHeight = true;
|
||||
break;
|
||||
case 0x1B:
|
||||
break;
|
||||
case 0x1C: // Minimap color
|
||||
fin.read((char*)&thingAttributes.miniMapColor, 2);
|
||||
thingAttributes.hasMiniMapColor = true;
|
||||
break;
|
||||
case 0x1D: // Unknown
|
||||
fin.read((char*)&read_short, 2);
|
||||
if(read_short == 1112)
|
||||
thingAttributes.readable = true;
|
||||
break;
|
||||
case 0x1E:
|
||||
break;
|
||||
case 0x1F:
|
||||
thingAttributes.lookThrough = true;
|
||||
break;
|
||||
case 0x20:
|
||||
break;
|
||||
default:
|
||||
throw std::logic_error(fw::mkstr("ERROR: unknown .dat byte code: 0x", std::hex, (int)opt));
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
#ifndef DATMANAGER_H
|
||||
#define DATMANAGER_H
|
||||
|
||||
#include <framework/global.h>
|
||||
#include "thing.h"
|
||||
|
||||
class DatManager
|
||||
{
|
||||
public:
|
||||
bool load(const std::string& filename);
|
||||
void unload();
|
||||
|
||||
void parseThingAttributes(std::stringstream& fin, ThingAttributes& thingAttributes);
|
||||
void parseThingAttributesOpt(std::stringstream& fin, ThingAttributes& thingAttributes, uint8 opt);
|
||||
|
||||
const ThingAttributes& getItemAttributes(uint16 id) { return m_itemsAttributes[id - 100]; }
|
||||
const ThingAttributes& getCreatureAttributes(uint16 id) { return m_creaturesAttributes[id - 1]; }
|
||||
const ThingAttributes& getEffectAttributes(uint16 id) { return m_effectsAttributes[id - 100]; }
|
||||
const ThingAttributes& getShotAttributes(uint16 id) { return m_shotsAttributes[id - 1]; }
|
||||
|
||||
uint32 getSignature() { return m_signature; }
|
||||
|
||||
private:
|
||||
uint32 m_signature;
|
||||
|
||||
std::vector<ThingAttributes> m_itemsAttributes;
|
||||
std::vector<ThingAttributes> m_creaturesAttributes;
|
||||
std::vector<ThingAttributes> m_effectsAttributes;
|
||||
std::vector<ThingAttributes> m_shotsAttributes;
|
||||
};
|
||||
|
||||
extern DatManager g_dat;
|
||||
|
||||
#endif
|
@ -1,33 +1,30 @@
|
||||
#ifndef GAME_H
|
||||
#define GAME_H
|
||||
|
||||
#include <framework/global.h>
|
||||
#include "map.h"
|
||||
#include "player.h"
|
||||
#include <otclient/net/protocolgame.h>
|
||||
#include "declarations.h"
|
||||
#include <otclient/net/declarations.h>
|
||||
|
||||
class Game
|
||||
{
|
||||
public:
|
||||
Game();
|
||||
|
||||
void onLogin();
|
||||
void onLogout();
|
||||
|
||||
void setProtocol(ProtocolGamePtr protocolGame) { m_protocolGame = protocolGame; }
|
||||
ProtocolGamePtr getProtocol() { return m_protocolGame; }
|
||||
|
||||
Map *getMap() { return &m_map; }
|
||||
Player *getPlayer() { return &m_player; }
|
||||
bool isOnline() { return m_online; }
|
||||
|
||||
void setOnline(bool online) { m_online = online; }
|
||||
bool getOnline() { return m_online; }
|
||||
ProtocolGamePtr getProtocol() { return m_protocolGame; }
|
||||
LocalPlayerPtr getLocalPlayer() { return m_localPlayer; }
|
||||
|
||||
private:
|
||||
Map m_map;
|
||||
Player m_player;
|
||||
LocalPlayerPtr m_localPlayer;
|
||||
ProtocolGamePtr m_protocolGame;
|
||||
bool m_online;
|
||||
|
||||
};
|
||||
|
||||
extern Game g_game;
|
||||
|
||||
#endif // GAME_H
|
||||
#endif
|
||||
|
@ -0,0 +1,2 @@
|
||||
#include "localplayer.h"
|
||||
|
@ -0,0 +1,24 @@
|
||||
#ifndef LOCALPLAYER_H
|
||||
#define LOCALPLAYER_H
|
||||
|
||||
#include "player.h"
|
||||
|
||||
class LocalPlayer : public Player
|
||||
{
|
||||
public:
|
||||
LocalPlayer() { }
|
||||
|
||||
void setDrawSpeed(uint16 drawSpeed) { m_drawSpeed = drawSpeed; }
|
||||
uint16 getDrawSpeed() { return m_drawSpeed; }
|
||||
|
||||
void setCanReportBugs(uint8 canReportBugs) { m_canReportBugs = (canReportBugs != 0); }
|
||||
bool getCanReportBugs() { return m_canReportBugs; }
|
||||
|
||||
LocalPlayerPtr asLocalPlayer() { return std::static_pointer_cast<LocalPlayer>(shared_from_this()); }
|
||||
|
||||
private:
|
||||
uint16 m_drawSpeed;
|
||||
bool m_canReportBugs;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,109 @@
|
||||
#include "spritemanager.h"
|
||||
#include <framework/core/resourcemanager.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
|
||||
SpriteManager g_sprites;
|
||||
|
||||
SpriteManager::SpriteManager()
|
||||
{
|
||||
m_spritesCount = 0;
|
||||
m_signature = 0;
|
||||
}
|
||||
|
||||
bool SpriteManager::load(const std::string &filename)
|
||||
{
|
||||
g_resources.loadFile(filename, m_fin);
|
||||
m_signature = fw::getu32(m_fin);
|
||||
m_spritesCount = fw::getu16(m_fin);
|
||||
m_sprites.resize(m_spritesCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SpriteManager::unload()
|
||||
{
|
||||
m_sprites.clear();
|
||||
m_spritesCount = 0;
|
||||
m_signature = 0;
|
||||
}
|
||||
|
||||
TexturePtr SpriteManager::loadSprite(int id)
|
||||
{
|
||||
m_fin.seekg(((id-1) * 4) + 6, std::ios_base::beg);
|
||||
|
||||
uint32 spriteAddress = fw::getu32(m_fin);
|
||||
|
||||
// no sprite? return an empty texture
|
||||
if(spriteAddress == 0)
|
||||
return g_graphics.getEmptyTexture();
|
||||
|
||||
m_fin.seekg(spriteAddress, std::ios_base::beg);
|
||||
assert(m_fin.good());
|
||||
|
||||
// skip color key
|
||||
fw::getu8(m_fin);
|
||||
fw::getu8(m_fin);
|
||||
fw::getu8(m_fin);
|
||||
|
||||
uint16 pixelDataSize = fw::getu16(m_fin);
|
||||
|
||||
uchar pixels[4096];
|
||||
int writePos = 0;
|
||||
int read = 0;
|
||||
|
||||
// decompress pixels
|
||||
while(read < pixelDataSize) {
|
||||
uint16 transparentPixels, coloredPixels;
|
||||
m_fin.read((char*)&transparentPixels, 2);
|
||||
m_fin.read((char*)&coloredPixels, 2);
|
||||
|
||||
for(int i = 0; i < transparentPixels; i++) {
|
||||
pixels[writePos + 0] = 0x00;
|
||||
pixels[writePos + 1] = 0x00;
|
||||
pixels[writePos + 2] = 0x00;
|
||||
pixels[writePos + 3] = 0x00;
|
||||
writePos += 4;
|
||||
}
|
||||
|
||||
for(int i = 0; i < coloredPixels; i++) {
|
||||
pixels[writePos + 0] = fw::getu8(m_fin);
|
||||
pixels[writePos + 1] = fw::getu8(m_fin);
|
||||
pixels[writePos + 2] = fw::getu8(m_fin);
|
||||
pixels[writePos + 3] = 0xFF;
|
||||
|
||||
writePos += 4;
|
||||
}
|
||||
|
||||
read += 4 + (3 * coloredPixels);
|
||||
}
|
||||
|
||||
// fill remaining pixels with alpha
|
||||
while(writePos < 4096) {
|
||||
pixels[writePos + 0] = 0x00;
|
||||
pixels[writePos + 1] = 0x00;
|
||||
pixels[writePos + 2] = 0x00;
|
||||
pixels[writePos + 3] = 0x00;
|
||||
writePos += 4;
|
||||
}
|
||||
|
||||
return TexturePtr(new Texture(32, 32, 4, pixels));
|
||||
}
|
||||
|
||||
TexturePtr SpriteManager::getSpriteTexture(int id)
|
||||
{
|
||||
if(id == 0)
|
||||
return g_graphics.getEmptyTexture();
|
||||
|
||||
assert(id <= m_spritesCount);
|
||||
|
||||
// load sprites on demand
|
||||
TexturePtr texture = m_sprites[id-1];
|
||||
if(!texture) {
|
||||
texture = loadSprite(id);
|
||||
m_sprites[id-1] = texture;
|
||||
}
|
||||
|
||||
//TODO: release unused sprites textures after X seconds
|
||||
// to avoid massive texture allocations
|
||||
|
||||
return texture;
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
#ifndef SPRITEMANAGER_H
|
||||
#define SPRITEMANAGER_H
|
||||
|
||||
#include <framework/global.h>
|
||||
#include <framework/graphics/texture.h>
|
||||
|
||||
class SpriteManager
|
||||
{
|
||||
public:
|
||||
SpriteManager();
|
||||
|
||||
bool load(const std::string& filename);
|
||||
void unload();
|
||||
|
||||
uint32 getSignature() { return m_signature; }
|
||||
int getSpritesCount() { return m_spritesCount; }
|
||||
TexturePtr getSpriteTexture(int id);
|
||||
|
||||
private:
|
||||
TexturePtr loadSprite(int id);
|
||||
|
||||
uint32 m_signature;
|
||||
uint16 m_spritesCount;
|
||||
std::stringstream m_fin;
|
||||
std::vector<TexturePtr> m_sprites;
|
||||
TexturePtr m_transparentSprite;
|
||||
};
|
||||
|
||||
extern SpriteManager g_sprites;
|
||||
|
||||
#endif
|
@ -1,58 +1,39 @@
|
||||
#ifndef THING_H
|
||||
#define THING_H
|
||||
|
||||
#include <otclient/global.h>
|
||||
#include "declarations.h"
|
||||
#include "thingattributes.h"
|
||||
#include <framework/luascript/luaobject.h>
|
||||
|
||||
struct ThingAttributes
|
||||
{
|
||||
ThingAttributes();
|
||||
|
||||
bool stackable, alwaysOnTop, useable, readable, moveable, blockSolid, blockProjectile, blockPathFind, pickupable,
|
||||
isHangable, isHorizontal, isVertical, rotable, hasHeight, lookThrough, hasMiniMapColor;
|
||||
uint8 alwaysOnTopOrder, width, height, blendframes, xdiv, ydiv, zdiv, animcount, xOffset, yOffset;
|
||||
uint16 speed, subParam07, subParam08, lightLevel, lightColor, miniMapColor;
|
||||
std::vector<int> sprites;
|
||||
ThingAttributesGroup group;
|
||||
};
|
||||
|
||||
class Thing
|
||||
class Thing : public LuaObject
|
||||
{
|
||||
public:
|
||||
Thing();
|
||||
Thing(ThingType type) : m_id(0), m_type(type) { }
|
||||
virtual ~Thing() { }
|
||||
|
||||
enum Type {
|
||||
TYPE_NONE,
|
||||
TYPE_ITEM,
|
||||
TYPE_CREATURE,
|
||||
TYPE_EFFECT,
|
||||
TYPE_SHOT
|
||||
};
|
||||
virtual void draw(int x, int y) = 0;
|
||||
|
||||
void setId(uint32 id) { m_id = id; }
|
||||
uint32 getId() { return m_id; }
|
||||
|
||||
void setType(Type type) { m_type = type; }
|
||||
Type getType() const { return m_type; }
|
||||
|
||||
void setPosition(const Position& position) { m_position = position; }
|
||||
Position *getPosition() { return &m_position; }
|
||||
|
||||
virtual void draw(int, int) {}
|
||||
uint32 getId() const { return m_id; }
|
||||
ThingType getType() const { return m_type; }
|
||||
Position getPosition() const { return m_position; }
|
||||
virtual const ThingAttributes& getAttributes() = 0;
|
||||
|
||||
virtual Item* getItem() { return NULL; }
|
||||
virtual const Item *getItem() const { return NULL; }
|
||||
virtual Creature *getCreature() { return NULL; }
|
||||
virtual const Creature *getCreature() const { return NULL; }
|
||||
ThingPtr asThing() { return std::static_pointer_cast<Thing>(shared_from_this()); }
|
||||
virtual ItemPtr asItem() { return nullptr; }
|
||||
virtual CreaturePtr asCreature() { return nullptr; }
|
||||
virtual EffectPtr asEffect() { return nullptr; }
|
||||
virtual PlayerPtr asPlayer() { return nullptr; }
|
||||
virtual LocalPlayerPtr asLocalPlayer() { return nullptr; }
|
||||
|
||||
protected:
|
||||
void internalDraw(int x, int y, int blendframes, int xdiv, int ydiv, int zdiv, int anim);
|
||||
|
||||
uint32 m_id;
|
||||
Type m_type;
|
||||
ThingType m_type;
|
||||
Position m_position;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,52 @@
|
||||
#ifndef THINGATTRIBUTES_H
|
||||
#define THINGATTRIBUTES_H
|
||||
|
||||
#include "declarations.h"
|
||||
|
||||
struct ThingAttributes
|
||||
{
|
||||
ThingAttributes() {
|
||||
group = THING_GROUP_NONE;
|
||||
blockSolid = false;
|
||||
hasHeight = false;
|
||||
blockPathFind = false;
|
||||
blockProjectile = false;
|
||||
alwaysOnTop = false;
|
||||
alwaysOnTopOrder = 0;
|
||||
stackable = false;
|
||||
useable = false;
|
||||
moveable = true;
|
||||
pickupable = false;
|
||||
rotable = false;
|
||||
readable = false;
|
||||
lookThrough = false;
|
||||
speed = 0;
|
||||
lightLevel = 0;
|
||||
lightColor = 0;
|
||||
isVertical = false;
|
||||
isHorizontal = false;
|
||||
isHangable = false;
|
||||
miniMapColor = 0;
|
||||
hasMiniMapColor = false;
|
||||
subParam07 = 0;
|
||||
subParam08 = 0;
|
||||
width = 0;
|
||||
height = 0;
|
||||
blendframes = 0;
|
||||
xdiv = 0;
|
||||
ydiv = 0;
|
||||
zdiv = 0;
|
||||
animcount = 0;
|
||||
xOffset = 0;
|
||||
yOffset = 0;
|
||||
}
|
||||
|
||||
bool stackable, alwaysOnTop, useable, readable, moveable, blockSolid, blockProjectile, blockPathFind, pickupable,
|
||||
isHangable, isHorizontal, isVertical, rotable, hasHeight, lookThrough, hasMiniMapColor;
|
||||
uint8 alwaysOnTopOrder, width, height, blendframes, xdiv, ydiv, zdiv, animcount, xOffset, yOffset;
|
||||
uint16 speed, subParam07, subParam08, lightLevel, lightColor, miniMapColor;
|
||||
std::vector<int> sprites;
|
||||
ThingAttributesGroup group;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in new issue