Skip to content

Commit

Permalink
Move map cache to monster
Browse files Browse the repository at this point in the history
  • Loading branch information
ramon-bernardo committed Sep 19, 2024
1 parent 25df9cf commit eb06511
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 243 deletions.
217 changes: 1 addition & 216 deletions src/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,6 @@ int32_t Creature::getWalkDelay() const

void Creature::onThink(uint32_t interval)
{
if (!isMapLoaded && useCacheMap()) {
isMapLoaded = true;
updateMapCache();
}

if (followCreature && master != followCreature && !canSeeCreature(followCreature)) {
onCreatureDisappear(followCreature, false);
}
Expand Down Expand Up @@ -330,129 +325,16 @@ void Creature::updateIcons() const
}
}

void Creature::updateMapCache()
{
Tile* tile;
const Position& myPos = getPosition();
Position pos(0, 0, myPos.z);

for (int32_t y = -maxWalkCacheHeight; y <= maxWalkCacheHeight; ++y) {
for (int32_t x = -maxWalkCacheWidth; x <= maxWalkCacheWidth; ++x) {
pos.x = myPos.getX() + x;
pos.y = myPos.getY() + y;
tile = g_game.map.getTile(pos);
updateTileCache(tile, pos);
}
}
}

void Creature::updateTileCache(const Tile* tile, int32_t dx, int32_t dy)
{
if (std::abs(dx) <= maxWalkCacheWidth && std::abs(dy) <= maxWalkCacheHeight) {
localMapCache[maxWalkCacheHeight + dy][maxWalkCacheWidth + dx] =
tile && tile->queryAdd(0, *this, 1, FLAG_PATHFINDING | FLAG_IGNOREFIELDDAMAGE) == RETURNVALUE_NOERROR;
}
}

void Creature::updateTileCache(const Tile* tile, const Position& pos)
{
const Position& myPos = getPosition();
if (pos.z == myPos.z) {
int32_t dx = pos.getOffsetX(myPos);
int32_t dy = pos.getOffsetY(myPos);
updateTileCache(tile, dx, dy);
}
}

int32_t Creature::getWalkCache(const Position& pos) const
{
if (!useCacheMap()) {
return 2;
}

const Position& myPos = getPosition();
if (myPos.z != pos.z) {
return 0;
}

if (pos == myPos) {
return 1;
}

if (int32_t dx = pos.getOffsetX(myPos); std::abs(dx) <= maxWalkCacheWidth) {
if (int32_t dy = pos.getOffsetY(myPos); std::abs(dy) <= maxWalkCacheHeight) {
if (localMapCache[maxWalkCacheHeight + dy][maxWalkCacheWidth + dx]) {
return 1;
}
return 0;
}
}

// out of range
return 2;
}

void Creature::onAddTileItem(const Tile* tile, const Position& pos)
{
if (isMapLoaded && pos.z == getPosition().z) {
updateTileCache(tile, pos);
}
}

void Creature::onUpdateTileItem(const Tile* tile, const Position& pos, const Item*, const ItemType& oldType,
const Item*, const ItemType& newType)
{
if (!isMapLoaded) {
return;
}

if (oldType.blockSolid || oldType.blockPathFind || newType.blockPathFind || newType.blockSolid) {
if (pos.z == getPosition().z) {
updateTileCache(tile, pos);
}
}
}

void Creature::onRemoveTileItem(const Tile* tile, const Position& pos, const ItemType& iType, const Item*)
{
if (!isMapLoaded) {
return;
}

if (iType.blockSolid || iType.blockPathFind || iType.isGroundTile()) {
if (pos.z == getPosition().z) {
updateTileCache(tile, pos);
}
}
}

void Creature::onCreatureAppear(Creature* creature, bool isLogin)
{
if (creature == this) {
if (useCacheMap()) {
isMapLoaded = true;
updateMapCache();
}

if (isLogin) {
setLastPosition(getPosition());
}
} else if (isMapLoaded) {
if (creature->getPosition().z == getPosition().z) {
updateTileCache(creature->getTile(), creature->getPosition());
}
}
}

void Creature::onRemoveCreature(Creature* creature, bool)
{
onCreatureDisappear(creature, true);
if (creature != this && isMapLoaded) {
if (creature->getPosition().z == getPosition().z) {
updateTileCache(creature->getTile(), creature->getPosition());
}
}
}
void Creature::onRemoveCreature(Creature* creature, bool) { onCreatureDisappear(creature, true); }

void Creature::onCreatureDisappear(const Creature* creature, bool isLogout)
{
Expand Down Expand Up @@ -519,103 +401,6 @@ void Creature::onCreatureMove(Creature* creature, const Tile* newTile, const Pos
g_events->eventCreatureOnChangeZone(this, oldTile->getZone(), newTile->getZone());
onChangeZone(getZone());
}

// update map cache
if (isMapLoaded) {
if (teleport || oldPos.z != newPos.z) {
updateMapCache();
} else {
const Position& myPos = getPosition();

if (oldPos.y > newPos.y) { // north
// shift y south
for (int32_t y = mapWalkHeight - 1; --y >= 0;) {
memcpy(localMapCache[y + 1], localMapCache[y], sizeof(localMapCache[y]));
}

// update 0
for (int32_t x = -maxWalkCacheWidth; x <= maxWalkCacheWidth; ++x) {
Tile* cacheTile =
g_game.map.getTile(myPos.getX() + x, myPos.getY() - maxWalkCacheHeight, myPos.z);
updateTileCache(cacheTile, x, -maxWalkCacheHeight);
}
} else if (oldPos.y < newPos.y) { // south
// shift y north
for (int32_t y = 0; y <= mapWalkHeight - 2; ++y) {
memcpy(localMapCache[y], localMapCache[y + 1], sizeof(localMapCache[y]));
}

// update mapWalkHeight - 1
for (int32_t x = -maxWalkCacheWidth; x <= maxWalkCacheWidth; ++x) {
Tile* cacheTile =
g_game.map.getTile(myPos.getX() + x, myPos.getY() + maxWalkCacheHeight, myPos.z);
updateTileCache(cacheTile, x, maxWalkCacheHeight);
}
}

if (oldPos.x < newPos.x) { // east
// shift y west
int32_t starty = 0;
int32_t endy = mapWalkHeight - 1;
int32_t dy = oldPos.getDistanceY(newPos);

if (dy < 0) {
endy += dy;
} else if (dy > 0) {
starty = dy;
}

for (int32_t y = starty; y <= endy; ++y) {
for (int32_t x = 0; x <= mapWalkWidth - 2; ++x) {
localMapCache[y][x] = localMapCache[y][x + 1];
}
}

// update mapWalkWidth - 1
for (int32_t y = -maxWalkCacheHeight; y <= maxWalkCacheHeight; ++y) {
Tile* cacheTile = g_game.map.getTile(myPos.x + maxWalkCacheWidth, myPos.y + y, myPos.z);
updateTileCache(cacheTile, maxWalkCacheWidth, y);
}
} else if (oldPos.x > newPos.x) { // west
// shift y east
int32_t starty = 0;
int32_t endy = mapWalkHeight - 1;
int32_t dy = oldPos.getDistanceY(newPos);

if (dy < 0) {
endy += dy;
} else if (dy > 0) {
starty = dy;
}

for (int32_t y = starty; y <= endy; ++y) {
for (int32_t x = mapWalkWidth - 1; --x >= 0;) {
localMapCache[y][x + 1] = localMapCache[y][x];
}
}

// update 0
for (int32_t y = -maxWalkCacheHeight; y <= maxWalkCacheHeight; ++y) {
Tile* cacheTile = g_game.map.getTile(myPos.x - maxWalkCacheWidth, myPos.y + y, myPos.z);
updateTileCache(cacheTile, -maxWalkCacheWidth, y);
}
}

updateTileCache(oldTile, oldPos);
}
}
} else {
if (isMapLoaded) {
const Position& myPos = getPosition();

if (newPos.z == myPos.z) {
updateTileCache(newTile, newPos);
}

if (oldPos.z == myPos.z) {
updateTileCache(oldTile, oldPos);
}
}
}

if (creature == followCreature || (creature == this && followCreature)) {
Expand Down
21 changes: 4 additions & 17 deletions src/creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,11 @@ class Creature : virtual public Thing
virtual void onWalk();
virtual bool getNextStep(Direction& dir, uint32_t& flags);

void onAddTileItem(const Tile* tile, const Position& pos);
virtual void onAddTileItem(const Tile* tile, const Position& pos) {}

Check failure on line 285 in src/creature.h

View workflow job for this annotation

GitHub Actions / test

unused parameter ‘tile’ [-Werror=unused-parameter]

Check failure on line 285 in src/creature.h

View workflow job for this annotation

GitHub Actions / test

unused parameter ‘pos’ [-Werror=unused-parameter]
virtual void onUpdateTileItem(const Tile* tile, const Position& pos, const Item* oldItem, const ItemType& oldType,

Check failure on line 286 in src/creature.h

View workflow job for this annotation

GitHub Actions / test

unused parameter ‘tile’ [-Werror=unused-parameter]

Check failure on line 286 in src/creature.h

View workflow job for this annotation

GitHub Actions / test

unused parameter ‘pos’ [-Werror=unused-parameter]

Check failure on line 286 in src/creature.h

View workflow job for this annotation

GitHub Actions / test

unused parameter ‘oldItem’ [-Werror=unused-parameter]

Check failure on line 286 in src/creature.h

View workflow job for this annotation

GitHub Actions / test

unused parameter ‘oldType’ [-Werror=unused-parameter]
const Item* newItem, const ItemType& newType);
virtual void onRemoveTileItem(const Tile* tile, const Position& pos, const ItemType& iType, const Item* item);
const Item* newItem, const ItemType& newType)

Check failure on line 287 in src/creature.h

View workflow job for this annotation

GitHub Actions / test

unused parameter ‘newItem’ [-Werror=unused-parameter]

Check failure on line 287 in src/creature.h

View workflow job for this annotation

GitHub Actions / test

unused parameter ‘newType’ [-Werror=unused-parameter]
{}
virtual void onRemoveTileItem(const Tile* tile, const Position& pos, const ItemType& iType, const Item* item) {}

Check failure on line 289 in src/creature.h

View workflow job for this annotation

GitHub Actions / test

unused parameter ‘tile’ [-Werror=unused-parameter]

Check failure on line 289 in src/creature.h

View workflow job for this annotation

GitHub Actions / test

unused parameter ‘pos’ [-Werror=unused-parameter]

virtual void onCreatureAppear(Creature* creature, bool isLogin);
virtual void onRemoveCreature(Creature* creature, bool isLogout);
Expand Down Expand Up @@ -328,8 +329,6 @@ class Creature : virtual public Thing
Tile* getTile() override final { return tile; }
const Tile* getTile() const override final { return tile; }

int32_t getWalkCache(const Position& pos) const;

const Position& getLastPosition() const { return lastPosition; }
void setLastPosition(Position newLastPos) { lastPosition = newLastPos; }

Expand All @@ -355,19 +354,12 @@ class Creature : virtual public Thing
decltype(auto) getStorageMap() const { return storageMap; }

protected:
virtual bool useCacheMap() const { return false; }

struct CountBlock_t
{
int32_t total;
int64_t ticks;
};

static constexpr int32_t mapWalkWidth = Map::maxViewportX * 2 + 1;
static constexpr int32_t mapWalkHeight = Map::maxViewportY * 2 + 1;
static constexpr int32_t maxWalkCacheWidth = (mapWalkWidth - 1) / 2;
static constexpr int32_t maxWalkCacheHeight = (mapWalkHeight - 1) / 2;

Position position;

using CountMap = std::map<uint32_t, CountBlock_t>;
Expand Down Expand Up @@ -411,9 +403,7 @@ class Creature : virtual public Thing
Direction direction = DIRECTION_SOUTH;
Skulls_t skull = SKULL_NONE;

bool localMapCache[mapWalkHeight][mapWalkWidth] = {{false}};
bool isInternalRemoved = false;
bool isMapLoaded = false;
bool isUpdatingPath = false;
bool creatureCheck = false;
bool inCheckCreaturesVector = false;
Expand All @@ -433,9 +423,6 @@ class Creature : virtual public Thing
}
CreatureEventList getCreatureEvents(CreatureEventType_t type);

void updateMapCache();
void updateTileCache(const Tile* tile, int32_t dx, int32_t dy);
void updateTileCache(const Tile* tile, const Position& pos);
void onCreatureDisappear(const Creature* creature, bool isLogout);
virtual void doAttacking(uint32_t) {}
virtual bool hasExtraSwing() { return false; }
Expand Down
12 changes: 7 additions & 5 deletions src/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -631,11 +631,13 @@ bool Map::isSightClear(const Position& fromPos, const Position& toPos, bool same

const Tile* Map::canWalkTo(const Creature& creature, const Position& pos) const
{
int32_t walkCache = creature.getWalkCache(pos);
if (walkCache == 0) {
return nullptr;
} else if (walkCache == 1) {
return getTile(pos.x, pos.y, pos.z);
if (auto monster = creature.getMonster()) {
auto walk_cache = monster->getWalkCache(pos);
if (walk_cache == 0) {
return nullptr;
} else if (walk_cache == 1) {
return getTile(pos.x, pos.y, pos.z);
}
}

// used for non-cached tiles
Expand Down
Loading

0 comments on commit eb06511

Please sign in to comment.