change how tile stack works
This commit is contained in:
parent
8e08decd25
commit
0b4d7ace05
|
@ -85,7 +85,7 @@ namespace Otc
|
||||||
DatLensHelp = 29,
|
DatLensHelp = 29,
|
||||||
DatFullGround = 30,
|
DatFullGround = 30,
|
||||||
DatIgnoreLook = 31,
|
DatIgnoreLook = 31,
|
||||||
DatClothe = 32,
|
DatCloth = 32,
|
||||||
DatAnimation = 33,
|
DatAnimation = 33,
|
||||||
DatLastOpt = 255
|
DatLastOpt = 255
|
||||||
};
|
};
|
||||||
|
@ -249,13 +249,6 @@ namespace Otc
|
||||||
ClientGetObjectInfo = 243
|
ClientGetObjectInfo = 243
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ThingType {
|
|
||||||
Item,
|
|
||||||
Creature,
|
|
||||||
Effect,
|
|
||||||
Shot
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SpriteMask {
|
enum SpriteMask {
|
||||||
SpriteRedMask = 0,
|
SpriteRedMask = 0,
|
||||||
SpriteGreenMask,
|
SpriteGreenMask,
|
||||||
|
|
|
@ -24,11 +24,14 @@
|
||||||
#include "thingstype.h"
|
#include "thingstype.h"
|
||||||
#include "localplayer.h"
|
#include "localplayer.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
#include "tile.h"
|
||||||
|
#include "item.h"
|
||||||
|
|
||||||
#include <framework/platform/platform.h>
|
#include <framework/platform/platform.h>
|
||||||
#include <framework/graphics/graphics.h>
|
#include <framework/graphics/graphics.h>
|
||||||
|
|
||||||
|
|
||||||
Creature::Creature() : Thing(Otc::Creature)
|
Creature::Creature() : Thing()
|
||||||
{
|
{
|
||||||
m_healthPercent = 0;
|
m_healthPercent = 0;
|
||||||
m_direction = Otc::South;
|
m_direction = Otc::South;
|
||||||
|
@ -218,9 +221,10 @@ void Creature::walk(const Position& position)
|
||||||
}
|
}
|
||||||
|
|
||||||
// update map tiles
|
// update map tiles
|
||||||
g_map.removeThingByPtr(asThing());
|
TilePtr oldTile = g_map.getTile(m_position);
|
||||||
m_position = position;
|
TilePtr newTile = g_map.getTile(position);
|
||||||
g_map.addThing(asThing());
|
oldTile->removeThing(asThing());
|
||||||
|
newTile->addThing(asThing(), -1);
|
||||||
|
|
||||||
if(m_walking) {
|
if(m_walking) {
|
||||||
// Calculate xPattern
|
// Calculate xPattern
|
||||||
|
@ -237,7 +241,7 @@ void Creature::walk(const Position& position)
|
||||||
// get walk speed
|
// get walk speed
|
||||||
int groundSpeed = 0;
|
int groundSpeed = 0;
|
||||||
|
|
||||||
ThingPtr ground = g_map.getThing(m_position, 0);
|
ItemPtr ground = newTile->getGround();
|
||||||
if(ground)
|
if(ground)
|
||||||
groundSpeed = ground->getType().groundSpeed;
|
groundSpeed = ground->getType().groundSpeed;
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,11 @@
|
||||||
#include "effect.h"
|
#include "effect.h"
|
||||||
#include "thingstype.h"
|
#include "thingstype.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
#include "tile.h"
|
||||||
#include <framework/platform/platform.h>
|
#include <framework/platform/platform.h>
|
||||||
#include <framework/core/eventdispatcher.h>
|
#include <framework/core/eventdispatcher.h>
|
||||||
|
|
||||||
Effect::Effect() : Thing(Otc::Effect)
|
Effect::Effect() : Thing()
|
||||||
{
|
{
|
||||||
m_lastTicks = g_platform.getTicks();
|
m_lastTicks = g_platform.getTicks();
|
||||||
m_finished = false;
|
m_finished = false;
|
||||||
|
@ -38,7 +39,11 @@ void Effect::draw(int x, int y)
|
||||||
if(g_platform.getTicks() - m_lastTicks > 75) {
|
if(g_platform.getTicks() - m_lastTicks > 75) {
|
||||||
const ThingType& type = getType();
|
const ThingType& type = getType();
|
||||||
if(m_animation+1 == type.animationPhases) {
|
if(m_animation+1 == type.animationPhases) {
|
||||||
g_dispatcher.addEvent(std::bind(&Map::removeThingByPtr, &g_map, asThing()));
|
EffectPtr self = asEffect();
|
||||||
|
g_dispatcher.addEvent([self] {
|
||||||
|
TilePtr tile = g_map.getTile(self->getPosition());
|
||||||
|
tile->removeEffect(self);
|
||||||
|
});
|
||||||
m_finished = true;
|
m_finished = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include "thing.h"
|
#include "thing.h"
|
||||||
#include <framework/platform/platform.h>
|
#include <framework/platform/platform.h>
|
||||||
|
|
||||||
Item::Item() : Thing(Otc::Item)
|
Item::Item() : Thing()
|
||||||
{
|
{
|
||||||
m_count = 0;
|
m_count = 0;
|
||||||
m_lastTicks = g_platform.getTicks();
|
m_lastTicks = g_platform.getTicks();
|
||||||
|
|
|
@ -76,18 +76,16 @@ void Map::draw(const Rect& rect)
|
||||||
// draw player names and health bars
|
// draw player names and health bars
|
||||||
for(int x = 0; x < MAP_VISIBLE_WIDTH; ++x) {
|
for(int x = 0; x < MAP_VISIBLE_WIDTH; ++x) {
|
||||||
for(int y = 0; y < MAP_VISIBLE_HEIGHT; ++y) {
|
for(int y = 0; y < MAP_VISIBLE_HEIGHT; ++y) {
|
||||||
Position tilePos = Position(m_centralPosition.x + (x - PLAYER_OFFSET_X - 1), m_centralPosition.y + (y - PLAYER_OFFSET_Y - 1), m_centralPosition.z);
|
Position tilePos = Position(m_centralPosition.x + (x - PLAYER_OFFSET_X + 1), m_centralPosition.y + (y - PLAYER_OFFSET_Y + 1), m_centralPosition.z);
|
||||||
if(const TilePtr& tile = m_tiles[tilePos]) {
|
if(const TilePtr& tile = m_tiles[tilePos]) {
|
||||||
auto& creatures = tile->getCreatures();
|
auto creatures = tile->getCreatures();
|
||||||
|
|
||||||
if(creatures.size() == 0)
|
if(creatures.size() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for(auto it = creatures.rbegin(), end = creatures.rend(); it != end; ++it) {
|
for(const CreaturePtr& creature : creatures) {
|
||||||
CreaturePtr creature = (*it)->asCreature();
|
int x = (7 + (tilePos.x - m_centralPosition.x))*NUM_TILE_PIXELS + 10 - tile->getDrawElevation();
|
||||||
|
int y = (5 + (tilePos.y - m_centralPosition.y))*NUM_TILE_PIXELS - 10 - tile->getDrawElevation();
|
||||||
int x = (7 + (tilePos.x - m_centralPosition.x))*NUM_TILE_PIXELS + 10 - tile->getDrawNextOffset();
|
|
||||||
int y = (5 + (tilePos.y - m_centralPosition.y))*NUM_TILE_PIXELS - 10 - tile->getDrawNextOffset();
|
|
||||||
|
|
||||||
if(creature != localPlayer) {
|
if(creature != localPlayer) {
|
||||||
x += creature->getWalkOffsetX() - walkOffsetX;
|
x += creature->getWalkOffsetX() - walkOffsetX;
|
||||||
|
@ -101,6 +99,11 @@ void Map::draw(const Rect& rect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Map::clean()
|
||||||
|
{
|
||||||
|
m_tiles.clear();
|
||||||
|
}
|
||||||
|
|
||||||
int Map::getMaxVisibleFloor()
|
int Map::getMaxVisibleFloor()
|
||||||
{
|
{
|
||||||
Position tilePos = m_centralPosition;
|
Position tilePos = m_centralPosition;
|
||||||
|
@ -159,7 +162,7 @@ bool Map::isCompletlyCovered(const Position& pos, int maxFloor)
|
||||||
for(int x=0;x<2;++x) {
|
for(int x=0;x<2;++x) {
|
||||||
for(int y=0;y<2;++y) {
|
for(int y=0;y<2;++y) {
|
||||||
TilePtr tile = m_tiles[tilePos + Position(-x, -y, 0)];
|
TilePtr tile = m_tiles[tilePos + Position(-x, -y, 0)];
|
||||||
if(!tile || !tile->isOpaque()) {
|
if(!tile || !tile->isFullyOpaque()) {
|
||||||
covered = false;
|
covered = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -172,50 +175,46 @@ bool Map::isCompletlyCovered(const Position& pos, int maxFloor)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::addThing(ThingPtr thing, int stackpos)
|
void Map::addThing(const ThingPtr& thing, const Position& pos, int stackPos)
|
||||||
{
|
{
|
||||||
if(!thing)
|
if(!thing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TilePtr& tile = m_tiles[thing->getPosition()];
|
TilePtr tile = getTile(pos);
|
||||||
if(!tile) {
|
tile->addThing(thing, stackPos);
|
||||||
tile = TilePtr(new Tile(thing->getPosition()));
|
|
||||||
|
if(CreaturePtr creature = thing->asCreature())
|
||||||
|
m_creatures[creature ->getId()] = creature;
|
||||||
}
|
}
|
||||||
|
|
||||||
tile->addThing(thing, stackpos);
|
ThingPtr Map::getThing(const Position& pos, int stackPos)
|
||||||
|
|
||||||
if(const CreaturePtr& creature = thing->asCreature())
|
|
||||||
m_creatures[thing->getId()] = creature;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThingPtr Map::getThing(const Position& pos, int stackpos)
|
|
||||||
{
|
{
|
||||||
if(const TilePtr& tile = m_tiles[pos]) {
|
if(const TilePtr& tile = m_tiles[pos])
|
||||||
return tile->getThing(stackpos);
|
return tile->getThing(stackPos);
|
||||||
}
|
return nullptr;
|
||||||
return ThingPtr();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::removeThing(const Position& pos, int stackpos)
|
void Map::removeThing(const Position& pos, int stackPos)
|
||||||
{
|
{
|
||||||
if(TilePtr& tile = m_tiles[pos]) {
|
if(TilePtr& tile = m_tiles[pos])
|
||||||
tile->removeThing(stackpos);
|
tile->removeThing(stackPos);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::removeThingByPtr(ThingPtr thing)
|
void Map::removeThing(const ThingPtr& thing)
|
||||||
{
|
{
|
||||||
if(!thing)
|
if(!thing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(TilePtr& tile = m_tiles[thing->getPosition()]) {
|
if(TilePtr& tile = m_tiles[thing->getPosition()])
|
||||||
tile->removeThingByPtr(thing);
|
tile->removeThing(thing);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::clean()
|
TilePtr Map::getTile(const Position& pos)
|
||||||
{
|
{
|
||||||
m_tiles.clear();
|
TilePtr& tile = m_tiles[pos];
|
||||||
|
if(!tile)
|
||||||
|
tile = TilePtr(new Tile(pos));
|
||||||
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::cleanTile(const Position& pos)
|
void Map::cleanTile(const Position& pos)
|
||||||
|
@ -224,6 +223,11 @@ void Map::cleanTile(const Position& pos)
|
||||||
tile->clean();
|
tile->clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Map::addCreature(const CreaturePtr& creature)
|
||||||
|
{
|
||||||
|
m_creatures[creature->getId()] = creature;
|
||||||
|
}
|
||||||
|
|
||||||
CreaturePtr Map::getCreatureById(uint32 id)
|
CreaturePtr Map::getCreatureById(uint32 id)
|
||||||
{
|
{
|
||||||
if(g_game.getLocalPlayer() && g_game.getLocalPlayer()->getId() == id)
|
if(g_game.getLocalPlayer() && g_game.getLocalPlayer()->getId() == id)
|
||||||
|
|
|
@ -42,18 +42,18 @@ class Map
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void draw(const Rect& rect);
|
void draw(const Rect& rect);
|
||||||
|
void clean();
|
||||||
|
|
||||||
int getMaxVisibleFloor();
|
int getMaxVisibleFloor();
|
||||||
bool isCovered(const Position& pos, int maxFloor);
|
bool isCovered(const Position& pos, int maxFloor);
|
||||||
bool isCompletlyCovered(const Position& pos, int maxFloor);
|
bool isCompletlyCovered(const Position& pos, int maxFloor);
|
||||||
|
|
||||||
void addThing(ThingPtr thing, int stackpos = -1);
|
void addThing(const ThingPtr& thing, const Position& pos, int stackPos = -1);
|
||||||
ThingPtr getThing(const Position& pos, int stackpos);
|
ThingPtr getThing(const Position& pos, int stackPos);
|
||||||
void removeThing(const Position& pos, int stackpos);
|
void removeThing(const Position& pos, int stackPos);
|
||||||
void removeThingByPtr(ThingPtr thing);
|
void removeThing(const ThingPtr& thing);
|
||||||
|
|
||||||
void clean();
|
|
||||||
void cleanTile(const Position& pos);
|
void cleanTile(const Position& pos);
|
||||||
|
TilePtr getTile(const Position& pos);
|
||||||
|
|
||||||
void setLight(const Light& light) { m_light = light; }
|
void setLight(const Light& light) { m_light = light; }
|
||||||
Light getLight() { return m_light; }
|
Light getLight() { return m_light; }
|
||||||
|
@ -61,6 +61,7 @@ public:
|
||||||
void setCentralPosition(const Position& centralPosition);
|
void setCentralPosition(const Position& centralPosition);
|
||||||
Position getCentralPosition() { return m_centralPosition; }
|
Position getCentralPosition() { return m_centralPosition; }
|
||||||
|
|
||||||
|
void addCreature(const CreaturePtr& creature);
|
||||||
CreaturePtr getCreatureById(uint32 id);
|
CreaturePtr getCreatureById(uint32 id);
|
||||||
void removeCreatureById(uint32 id);
|
void removeCreatureById(uint32 id);
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "spritemanager.h"
|
#include "spritemanager.h"
|
||||||
#include <framework/graphics/graphics.h>
|
#include <framework/graphics/graphics.h>
|
||||||
|
|
||||||
Thing::Thing(Otc::ThingType type) : m_id(0), m_type(type)
|
Thing::Thing() : m_id(0)
|
||||||
{
|
{
|
||||||
m_xPattern = 0;
|
m_xPattern = 0;
|
||||||
m_yPattern = 0;
|
m_yPattern = 0;
|
||||||
|
@ -67,3 +67,20 @@ void Thing::internalDraw(int x, int y, int layers, Otc::SpriteMask mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Thing::getStackPriority()
|
||||||
|
{
|
||||||
|
const ThingType& type = getType();
|
||||||
|
if(type.isGround)
|
||||||
|
return 0;
|
||||||
|
else if(type.isGroundClip)
|
||||||
|
return 1;
|
||||||
|
else if(type.isOnBottom)
|
||||||
|
return 2;
|
||||||
|
else if(type.isOnTop)
|
||||||
|
return 3;
|
||||||
|
else if(asCreature())
|
||||||
|
return 4;
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ struct Light
|
||||||
class Thing : public LuaObject
|
class Thing : public LuaObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Thing(Otc::ThingType type);
|
Thing();
|
||||||
virtual ~Thing() { }
|
virtual ~Thing() { }
|
||||||
|
|
||||||
virtual void draw(int x, int y) = 0;
|
virtual void draw(int x, int y) = 0;
|
||||||
|
@ -45,8 +45,8 @@ public:
|
||||||
void setPosition(const Position& position);
|
void setPosition(const Position& position);
|
||||||
|
|
||||||
uint32 getId() const { return m_id; }
|
uint32 getId() const { return m_id; }
|
||||||
Otc::ThingType getType() const { return m_type; }
|
|
||||||
Position getPosition() const { return m_position; }
|
Position getPosition() const { return m_position; }
|
||||||
|
int getStackPriority();
|
||||||
virtual const ThingType& getType() = 0;
|
virtual const ThingType& getType() = 0;
|
||||||
|
|
||||||
virtual void onPositionChange(const Position&) {}
|
virtual void onPositionChange(const Position&) {}
|
||||||
|
@ -62,7 +62,6 @@ protected:
|
||||||
void internalDraw(int x, int y, int layers, Otc::SpriteMask mask = Otc::SpriteNoMask);
|
void internalDraw(int x, int y, int layers, Otc::SpriteMask mask = Otc::SpriteNoMask);
|
||||||
|
|
||||||
uint32 m_id;
|
uint32 m_id;
|
||||||
Otc::ThingType m_type;
|
|
||||||
Position m_position;
|
Position m_position;
|
||||||
|
|
||||||
int m_xPattern, m_yPattern, m_zPattern, m_animation;
|
int m_xPattern, m_yPattern, m_zPattern, m_animation;
|
||||||
|
|
|
@ -174,7 +174,7 @@ void ThingsType::parseThingType(std::stringstream& fin, ThingType& thingType)
|
||||||
break;
|
break;
|
||||||
case Otc::DatLensHelp: // Used for giving players tips?
|
case Otc::DatLensHelp: // Used for giving players tips?
|
||||||
thingType.isLensHelp = true;
|
thingType.isLensHelp = true;
|
||||||
thingType.lensHelpParam = Fw::getU16(fin);
|
thingType.lensHelp = Fw::getU16(fin);
|
||||||
break;
|
break;
|
||||||
case Otc::DatFullGround: // Grounds that has no transparent pixels
|
case Otc::DatFullGround: // Grounds that has no transparent pixels
|
||||||
thingType.isFullGround = true;
|
thingType.isFullGround = true;
|
||||||
|
@ -182,9 +182,9 @@ void ThingsType::parseThingType(std::stringstream& fin, ThingType& thingType)
|
||||||
case Otc::DatIgnoreLook: // Ignore look, then looks at the item on the bottom of it
|
case Otc::DatIgnoreLook: // Ignore look, then looks at the item on the bottom of it
|
||||||
thingType.isIgnoreLook = true;
|
thingType.isIgnoreLook = true;
|
||||||
break;
|
break;
|
||||||
case Otc::DatClothe: // Clothes
|
case Otc::DatCloth: // Clothes
|
||||||
break;
|
thingType.isCloth = true;
|
||||||
case Otc::DatAnimation: // Not used in 8.62
|
thingType.clothSlot = Fw::getU16(fin);
|
||||||
break;
|
break;
|
||||||
case Otc::DatLastOpt:
|
case Otc::DatLastOpt:
|
||||||
done = true;
|
done = true;
|
||||||
|
@ -207,6 +207,8 @@ void ThingsType::parseThingType(std::stringstream& fin, ThingType& thingType)
|
||||||
thingType.yPattern = Fw::getU8(fin);
|
thingType.yPattern = Fw::getU8(fin);
|
||||||
thingType.zPattern = Fw::getU8(fin);
|
thingType.zPattern = Fw::getU8(fin);
|
||||||
thingType.animationPhases = Fw::getU8(fin);
|
thingType.animationPhases = Fw::getU8(fin);
|
||||||
|
if(thingType.animationPhases > 1)
|
||||||
|
thingType.isAnimation = true;
|
||||||
|
|
||||||
int totalSprites = thingType.width
|
int totalSprites = thingType.width
|
||||||
* thingType.height
|
* thingType.height
|
||||||
|
|
|
@ -64,7 +64,8 @@ struct ThingType
|
||||||
isLensHelp = false;
|
isLensHelp = false;
|
||||||
isFullGround = false;
|
isFullGround = false;
|
||||||
isIgnoreLook = false;
|
isIgnoreLook = false;
|
||||||
isClothe = false;
|
isCloth = false;
|
||||||
|
isAnimation = false;
|
||||||
hasLight = false;
|
hasLight = false;
|
||||||
hasMiniMapColor = false;
|
hasMiniMapColor = false;
|
||||||
|
|
||||||
|
@ -73,7 +74,8 @@ struct ThingType
|
||||||
maxTextLength = 0;
|
maxTextLength = 0;
|
||||||
lightLevel = lightColor = 0;
|
lightLevel = lightColor = 0;
|
||||||
miniMapColor = 0;
|
miniMapColor = 0;
|
||||||
lensHelpParam = 0;
|
lensHelp = 0;
|
||||||
|
clothSlot = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 layers;
|
uint8 layers;
|
||||||
|
@ -113,7 +115,8 @@ struct ThingType
|
||||||
bool isLensHelp;
|
bool isLensHelp;
|
||||||
bool isFullGround;
|
bool isFullGround;
|
||||||
bool isIgnoreLook;
|
bool isIgnoreLook;
|
||||||
bool isClothe;
|
bool isCloth;
|
||||||
|
bool isAnimation;
|
||||||
bool hasLight;
|
bool hasLight;
|
||||||
bool hasMiniMapColor;
|
bool hasMiniMapColor;
|
||||||
|
|
||||||
|
@ -122,7 +125,8 @@ struct ThingType
|
||||||
uint16 maxTextLength;
|
uint16 maxTextLength;
|
||||||
uint16 lightLevel, lightColor;
|
uint16 lightLevel, lightColor;
|
||||||
uint16 miniMapColor;
|
uint16 miniMapColor;
|
||||||
uint16 lensHelpParam;
|
uint16 lensHelp;
|
||||||
|
uint16 clothSlot;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<ThingType> ThingTypeList;
|
typedef std::vector<ThingType> ThingTypeList;
|
||||||
|
|
|
@ -26,221 +26,146 @@
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "localplayer.h"
|
#include "localplayer.h"
|
||||||
|
#include "effect.h"
|
||||||
#include <framework/graphics/fontmanager.h>
|
#include <framework/graphics/fontmanager.h>
|
||||||
|
|
||||||
Tile::Tile(const Position& position)
|
Tile::Tile(const Position& position)
|
||||||
{
|
{
|
||||||
m_drawNextOffset = 0;
|
m_drawElevation = 0;
|
||||||
m_position = position;
|
m_position = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tile::draw(int x, int y)
|
void Tile::draw(int x, int y)
|
||||||
{
|
{
|
||||||
m_drawNextOffset = 0;
|
m_drawElevation = 0;
|
||||||
|
|
||||||
if(m_ground)
|
// first bottom items
|
||||||
m_ground->draw(x, y);
|
for(const ThingPtr& thing : m_things) {
|
||||||
|
const ThingType& type = thing->getType();
|
||||||
for(auto it = m_itemsTop.rbegin(), end = m_itemsTop.rend(); it != end; ++it) {
|
if(thing->asCreature() || type.isOnTop)
|
||||||
const ThingPtr& thing = *it;
|
continue;
|
||||||
const ThingType& thingType = thing->getType();
|
thing->draw(x - m_drawElevation, y - m_drawElevation);
|
||||||
|
m_drawElevation += type.elevation;
|
||||||
if(thingType.isGroundClip) {
|
|
||||||
thing->draw(x - m_drawNextOffset, y - m_drawNextOffset);
|
|
||||||
m_drawNextOffset += thingType.elevation;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto it = m_itemsTop.rbegin(), end = m_itemsTop.rend(); it != end; ++it) {
|
// creatures
|
||||||
const ThingPtr& thing = *it;
|
for(const ThingPtr& thing : m_things) {
|
||||||
const ThingType& thingType = thing->getType();
|
if(thing->asCreature())
|
||||||
|
thing->draw(x - m_drawElevation, y - m_drawElevation);
|
||||||
if(thingType.isOnBottom) {
|
|
||||||
thing->draw(x - m_drawNextOffset, y - m_drawNextOffset);
|
|
||||||
m_drawNextOffset += thingType.elevation;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto it = m_itemsBottom.rbegin(), end = m_itemsBottom.rend(); it != end; ++it) {
|
// effects
|
||||||
const ThingPtr& thing = *it;
|
for(const EffectPtr& effect : m_effects)
|
||||||
const ThingType& thingType = thing->getType();
|
effect->draw(x - m_drawElevation, y - m_drawElevation);
|
||||||
thing->draw(x - m_drawNextOffset, y - m_drawNextOffset);
|
|
||||||
m_drawNextOffset += thingType.elevation;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto it = m_creatures.rbegin(), end = m_creatures.rend(); it != end; ++it) {
|
// top items
|
||||||
const ThingPtr& thing = *it;
|
for(const ThingPtr& thing : m_things) {
|
||||||
thing->draw(x - m_drawNextOffset, y - m_drawNextOffset);
|
const ThingType& type = thing->getType();
|
||||||
}
|
if(type.isOnTop)
|
||||||
|
thing->draw(x - m_drawElevation, y - m_drawElevation);
|
||||||
for(auto it = m_effects.rbegin(), end = m_effects.rend(); it != end; ++it) {
|
|
||||||
const ThingPtr& thing = *it;
|
|
||||||
thing->draw(x - m_drawNextOffset, y - m_drawNextOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto it = m_itemsTop.rbegin(), end = m_itemsTop.rend(); it != end; ++it) {
|
|
||||||
const ThingPtr& thing = *it;
|
|
||||||
const ThingType& thingType = thing->getType();
|
|
||||||
|
|
||||||
if(thingType.isOnTop) {
|
|
||||||
thing->draw(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Tile::addThing(ThingPtr thing, int stackpos)
|
|
||||||
{
|
|
||||||
// TODO: rework this. that -1 sucks
|
|
||||||
if(!thing)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const ThingType& thingType = thing->getType();
|
|
||||||
|
|
||||||
if(thing->asItem()) {
|
|
||||||
if(thingType.isGround)
|
|
||||||
m_ground = thing;
|
|
||||||
else {
|
|
||||||
if(thingType.isGroundClip || thingType.isOnBottom || thingType.isOnTop)
|
|
||||||
m_itemsTop.push_back(thing);
|
|
||||||
else {
|
|
||||||
if(stackpos == -1)
|
|
||||||
m_itemsBottom.push_back(thing);
|
|
||||||
else {
|
|
||||||
m_itemsBottom.insert(m_itemsBottom.begin()+(stackpos-getStackSize(2)), thing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(thing->asCreature()) {
|
|
||||||
m_creatures.push_back(thing);
|
|
||||||
}
|
|
||||||
else if(thing->asEffect()) {
|
|
||||||
m_effects.push_back(thing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ThingPtr Tile::getThing(unsigned int stackpos)
|
|
||||||
{
|
|
||||||
if(stackpos == 0)
|
|
||||||
return m_ground;
|
|
||||||
--stackpos;
|
|
||||||
|
|
||||||
if(stackpos < m_itemsTop.size())
|
|
||||||
return m_itemsTop[stackpos];
|
|
||||||
stackpos -= m_itemsTop.size();
|
|
||||||
|
|
||||||
if(stackpos < m_creatures.size())
|
|
||||||
return m_creatures[stackpos];
|
|
||||||
stackpos -= m_creatures.size();
|
|
||||||
|
|
||||||
if(stackpos < m_itemsBottom.size())
|
|
||||||
return m_itemsBottom[stackpos];
|
|
||||||
|
|
||||||
return ThingPtr();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Tile::removeThing(unsigned int stackpos)
|
|
||||||
{
|
|
||||||
if(stackpos == 0) {
|
|
||||||
m_ground.reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
--stackpos;
|
|
||||||
|
|
||||||
if(stackpos < m_itemsTop.size()) {
|
|
||||||
m_itemsTop.erase(m_itemsTop.begin() + stackpos);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
stackpos -= m_itemsTop.size();
|
|
||||||
|
|
||||||
if(stackpos < m_creatures.size()) {
|
|
||||||
m_creatures.erase(m_creatures.begin() + stackpos);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
stackpos -= m_creatures.size();
|
|
||||||
|
|
||||||
if(stackpos < m_itemsBottom.size()) {
|
|
||||||
m_itemsBottom.erase(m_itemsBottom.begin() + stackpos);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
logDebug("Invalid stackpos.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Tile::removeThingByPtr(ThingPtr thing)
|
|
||||||
{
|
|
||||||
// Items
|
|
||||||
if(thing->asItem()) {
|
|
||||||
const ThingType& thingType = thing->getType();
|
|
||||||
|
|
||||||
if(!(thingType.isGroundClip || thingType.isOnBottom || thingType.isOnTop)) {
|
|
||||||
for(auto it = m_itemsBottom.begin(), end = m_itemsBottom.end(); it != end; ++it) {
|
|
||||||
if(*it == thing) {
|
|
||||||
m_itemsBottom.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for(auto it = m_itemsTop.begin(), end = m_itemsTop.end(); it != end; ++it) {
|
|
||||||
if(*it == thing) {
|
|
||||||
m_itemsTop.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creatures
|
|
||||||
else if(thing->asCreature()) {
|
|
||||||
for(auto it = m_creatures.begin(), end = m_creatures.end(); it != end; ++it) {
|
|
||||||
if(*it == thing) {
|
|
||||||
m_creatures.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Effects
|
|
||||||
else if(thing->asEffect()) {
|
|
||||||
for(auto it = m_effects.begin(), end = m_effects.end(); it != end; ++it) {
|
|
||||||
if(*it == thing) {
|
|
||||||
m_effects.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tile::clean()
|
void Tile::clean()
|
||||||
{
|
{
|
||||||
m_itemsTop.clear();
|
m_things.clear();
|
||||||
m_creatures.clear();
|
|
||||||
m_itemsBottom.clear();
|
|
||||||
m_effects.clear();
|
m_effects.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Tile::getStackSize(int stop)
|
void Tile::addEffect(const EffectPtr& effect)
|
||||||
{
|
{
|
||||||
int ret = m_ground ? 1 : 0;
|
m_effects.push_back(effect);
|
||||||
if(stop == 0)
|
effect->setPosition(m_position);
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret += m_itemsTop.size();
|
|
||||||
if(stop == 1)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret += m_creatures.size();
|
|
||||||
if(stop == 2)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret += m_itemsBottom.size();
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Tile::isOpaque()
|
void Tile::removeEffect(const EffectPtr& effect)
|
||||||
{
|
{
|
||||||
if(m_ground && !m_ground->getType().isTranslucent)
|
auto it = std::find(m_effects.begin(), m_effects.end(), effect);
|
||||||
|
if(it != m_effects.end()) {
|
||||||
|
m_effects.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ThingPtr Tile::addThing(const ThingPtr& thing, int stackPos)
|
||||||
|
{
|
||||||
|
if(!thing)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if(stackPos < 0) {
|
||||||
|
stackPos = 0;
|
||||||
|
int priority = thing->getStackPriority();
|
||||||
|
for(stackPos = 0; stackPos < (int)m_things.size(); ++stackPos) {
|
||||||
|
int otherPriority = m_things[stackPos]->getStackPriority();
|
||||||
|
if(otherPriority > priority || (otherPriority == priority && otherPriority == 5))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if(stackPos > (int)m_things.size())
|
||||||
|
stackPos = m_things.size();
|
||||||
|
|
||||||
|
ThingPtr oldObject;
|
||||||
|
if(stackPos < (int)m_things.size())
|
||||||
|
oldObject = m_things[stackPos];
|
||||||
|
m_things.insert(m_things.begin() + stackPos, thing);
|
||||||
|
thing->setPosition(m_position);
|
||||||
|
return oldObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThingPtr Tile::getThing(int stackPos)
|
||||||
|
{
|
||||||
|
if(stackPos >= 0 && stackPos < (int)m_things.size())
|
||||||
|
return m_things[stackPos];
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThingPtr Tile::removeThing(int stackPos)
|
||||||
|
{
|
||||||
|
ThingPtr oldObject;
|
||||||
|
if(stackPos >= 0 && stackPos < (int)m_things.size()) {
|
||||||
|
oldObject = m_things[stackPos];
|
||||||
|
m_things.erase(m_things.begin() + stackPos);
|
||||||
|
}
|
||||||
|
return oldObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThingPtr Tile::removeThing(const ThingPtr& thing)
|
||||||
|
{
|
||||||
|
ThingPtr oldObject;
|
||||||
|
auto it = std::find(m_things.begin(), m_things.end(), thing);
|
||||||
|
if(it != m_things.end()) {
|
||||||
|
oldObject = *it;
|
||||||
|
m_things.erase(it);
|
||||||
|
}
|
||||||
|
return oldObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<CreaturePtr> Tile::getCreatures()
|
||||||
|
{
|
||||||
|
std::vector<CreaturePtr> creatures;
|
||||||
|
for(const ThingPtr& thing : m_things) {
|
||||||
|
if(CreaturePtr creature = thing->asCreature())
|
||||||
|
creatures.push_back(creature);
|
||||||
|
}
|
||||||
|
return creatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemPtr Tile::getGround()
|
||||||
|
{
|
||||||
|
ThingPtr firstObject = getThing(0);
|
||||||
|
if(!firstObject)
|
||||||
|
return nullptr;
|
||||||
|
const ThingType& type = firstObject->getType();
|
||||||
|
if(type.isGround)
|
||||||
|
return firstObject->asItem();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Tile::isFullyOpaque()
|
||||||
|
{
|
||||||
|
ThingPtr firstObject = getThing(0);
|
||||||
|
if(firstObject) {
|
||||||
|
const ThingType& type = firstObject->getType();
|
||||||
|
if(type.isGround && !type.isTranslucent)
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,34 +32,26 @@ public:
|
||||||
Tile(const Position& position);
|
Tile(const Position& position);
|
||||||
|
|
||||||
void draw(int x, int y);
|
void draw(int x, int y);
|
||||||
|
|
||||||
void addThing(ThingPtr thing, int stackpos);
|
|
||||||
ThingPtr getThing(unsigned int stackpos);
|
|
||||||
void removeThing(unsigned int stackpos);
|
|
||||||
void removeThingByPtr(ThingPtr thing);
|
|
||||||
|
|
||||||
void clean();
|
void clean();
|
||||||
|
|
||||||
bool hasGround() { return (!!m_ground); }
|
void addEffect(const EffectPtr& effect);
|
||||||
|
void removeEffect(const EffectPtr& effect);
|
||||||
int getStackSize(int stop);
|
ThingPtr addThing(const ThingPtr& thing, int stackPos = -1);
|
||||||
|
ThingPtr getThing(int stackPos);
|
||||||
const ThingList& getCreatures() { return m_creatures; }
|
ThingPtr removeThing(int stackPos);
|
||||||
int getDrawNextOffset() { return m_drawNextOffset; }
|
ThingPtr removeThing(const ThingPtr& thing);
|
||||||
|
|
||||||
const Position& getPosition() { return m_position; }
|
const Position& getPosition() { return m_position; }
|
||||||
|
int getDrawElevation() { return m_drawElevation; }
|
||||||
bool isOpaque();
|
std::vector<CreaturePtr> getCreatures();
|
||||||
|
ItemPtr getGround();
|
||||||
|
bool isFullyOpaque();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ThingPtr m_ground;
|
std::vector<EffectPtr> m_effects;
|
||||||
ThingList m_itemsBottom;
|
std::vector<ThingPtr> m_things;
|
||||||
ThingList m_creatures;
|
|
||||||
ThingList m_itemsTop;
|
|
||||||
ThingList m_effects;
|
|
||||||
Position m_position;
|
Position m_position;
|
||||||
|
int m_drawElevation;
|
||||||
int m_drawNextOffset;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <otclient/core/map.h>
|
#include <otclient/core/map.h>
|
||||||
#include <otclient/core/item.h>
|
#include <otclient/core/item.h>
|
||||||
#include <otclient/core/effect.h>
|
#include <otclient/core/effect.h>
|
||||||
|
#include <otclient/core/tile.h>
|
||||||
#include <framework/core/eventdispatcher.h>
|
#include <framework/core/eventdispatcher.h>
|
||||||
|
|
||||||
void ProtocolGame::parseMessage(InputMessage& msg)
|
void ProtocolGame::parseMessage(InputMessage& msg)
|
||||||
|
@ -364,18 +365,16 @@ void ProtocolGame::parseUpdateTile(InputMessage& msg)
|
||||||
void ProtocolGame::parseTileAddThing(InputMessage& msg)
|
void ProtocolGame::parseTileAddThing(InputMessage& msg)
|
||||||
{
|
{
|
||||||
Position pos = parsePosition(msg);
|
Position pos = parsePosition(msg);
|
||||||
uint8 stackpos = msg.getU8();
|
uint8 stackPos = msg.getU8();
|
||||||
|
|
||||||
ThingPtr thing = internalGetThing(msg);
|
ThingPtr thing = internalGetThing(msg);
|
||||||
thing->setPosition(pos);
|
g_map.addThing(thing, pos, stackPos);
|
||||||
|
|
||||||
g_map.addThing(thing, stackpos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseTileTransformThing(InputMessage& msg)
|
void ProtocolGame::parseTileTransformThing(InputMessage& msg)
|
||||||
{
|
{
|
||||||
Position pos = parsePosition(msg);
|
Position pos = parsePosition(msg);
|
||||||
uint8 stackpos = msg.getU8();
|
uint8 stackPos = msg.getU8();
|
||||||
|
|
||||||
uint16 thingId = msg.getU16();
|
uint16 thingId = msg.getU16();
|
||||||
if(thingId == 0x0061 || thingId == 0x0062 || thingId == 0x0063) {
|
if(thingId == 0x0061 || thingId == 0x0062 || thingId == 0x0063) {
|
||||||
|
@ -383,19 +382,17 @@ void ProtocolGame::parseTileTransformThing(InputMessage& msg)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ThingPtr thing = internalGetItem(msg, thingId);
|
ThingPtr thing = internalGetItem(msg, thingId);
|
||||||
thing->setPosition(pos);
|
g_map.removeThing(pos, stackPos);
|
||||||
|
g_map.addThing(thing, pos, stackPos);
|
||||||
g_map.removeThing(pos, stackpos);
|
|
||||||
g_map.addThing(thing, stackpos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseTileRemoveThing(InputMessage& msg)
|
void ProtocolGame::parseTileRemoveThing(InputMessage& msg)
|
||||||
{
|
{
|
||||||
Position pos = parsePosition(msg);
|
Position pos = parsePosition(msg);
|
||||||
uint8 stackpos = msg.getU8();
|
uint8 stackPos = msg.getU8();
|
||||||
|
|
||||||
g_map.removeThing(pos, stackpos);
|
g_map.removeThing(pos, stackPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseCreatureMove(InputMessage& msg)
|
void ProtocolGame::parseCreatureMove(InputMessage& msg)
|
||||||
|
@ -404,13 +401,12 @@ void ProtocolGame::parseCreatureMove(InputMessage& msg)
|
||||||
uint8 oldStackpos = msg.getU8();
|
uint8 oldStackpos = msg.getU8();
|
||||||
Position newPos = parsePosition(msg);
|
Position newPos = parsePosition(msg);
|
||||||
|
|
||||||
ThingPtr thing = g_map.getThing(oldPos, oldStackpos);
|
ThingPtr thing = g_map.getTile(oldPos)->getThing(oldStackpos);
|
||||||
if(thing) {
|
assert(thing);
|
||||||
CreaturePtr creature = thing->asCreature();
|
CreaturePtr creature = thing->asCreature();
|
||||||
if(creature)
|
assert(creature);
|
||||||
creature->walk(newPos);
|
creature->walk(newPos);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void ProtocolGame::parseOpenContainer(InputMessage& msg)
|
void ProtocolGame::parseOpenContainer(InputMessage& msg)
|
||||||
{
|
{
|
||||||
|
@ -512,11 +508,13 @@ void ProtocolGame::parseWorldLight(InputMessage& msg)
|
||||||
|
|
||||||
void ProtocolGame::parseMagicEffect(InputMessage& msg)
|
void ProtocolGame::parseMagicEffect(InputMessage& msg)
|
||||||
{
|
{
|
||||||
|
Position pos = parsePosition(msg);
|
||||||
|
int effectId = msg.getU8();
|
||||||
EffectPtr effect = EffectPtr(new Effect());
|
EffectPtr effect = EffectPtr(new Effect());
|
||||||
effect->setPosition(parsePosition(msg));
|
effect->setId(effectId);
|
||||||
effect->setId(msg.getU8());
|
|
||||||
|
|
||||||
g_map.addThing(effect);
|
TilePtr tile = g_map.getTile(pos);
|
||||||
|
tile->addEffect(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolGame::parseAnimatedText(InputMessage& msg)
|
void ProtocolGame::parseAnimatedText(InputMessage& msg)
|
||||||
|
@ -895,23 +893,19 @@ void ProtocolGame::setTileDescription(InputMessage& msg, Position position)
|
||||||
{
|
{
|
||||||
g_map.cleanTile(position);
|
g_map.cleanTile(position);
|
||||||
|
|
||||||
int stackpos = 0;
|
int stackPos = 0;
|
||||||
while(1){
|
while(1){
|
||||||
uint16 inspectTileId = msg.getU16(true);
|
uint16 inspectTileId = msg.getU16(true);
|
||||||
if(inspectTileId >= 0xFF00)
|
if(inspectTileId >= 0xFF00)
|
||||||
return;
|
return;
|
||||||
else {
|
else {
|
||||||
if(stackpos >= 10) {
|
if(stackPos >= 10)
|
||||||
logTraceDebug("Too many things!.");
|
logWarning("Too many things!");
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThingPtr thing = internalGetThing(msg);
|
ThingPtr thing = internalGetThing(msg);
|
||||||
if(thing)
|
g_map.addThing(thing, position);
|
||||||
thing->setPosition(position);
|
|
||||||
g_map.addThing(thing);
|
|
||||||
}
|
}
|
||||||
stackpos++;
|
stackPos++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue