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