void Creature::onUpdateTileItem(const Tile* tile, const Position& pos, const Item*, const ItemType& oldType, const Item*, const ItemType& newType) { if(isMapLoaded && (oldType.blockSolid || oldType.blockPathFind || newType.blockPathFind || newType.blockSolid) && pos.z == getPosition().z) updateTileCache(tile, pos); }
void Creature::onAddTileItem(const Tile* tile, const Position& pos, const Item* item) { if(isMapLoaded){ if(pos.z == getPosition().z){ updateTileCache(tile, pos); } } }
void Creature::updateTileCache(const Tile* tile, const Position& pos) { const Position& myPos = getPosition(); if (pos.z == myPos.z) { int32_t dx = Position::getOffsetX(pos, myPos); int32_t dy = Position::getOffsetY(pos, myPos); updateTileCache(tile, dx, dy); } }
void Creature::updateTileCache(const Tile* tile, const Position& pos) { const Position& myPos = getPosition(); if(pos.z == myPos.z){ int32_t dx = pos.x - myPos.x; int32_t dy = pos.y - myPos.y; updateTileCache(tile, dx, dy); } }
void Creature::onCreatureDisappear(const Creature* creature, bool isLogout) { internalCreatureDisappear(creature, true); if(creature != this && isMapLoaded && creature->getPosition().z == getPosition().z) { updateTileCache(creature->getTile(), creature->getPosition()); CreatureEventList disappearEvents = getCreatureEvents(CREATURE_EVENT_DISAPPEAR); for(CreatureEventList::iterator it = disappearEvents.begin(); it != disappearEvents.end(); ++it) (*it)->executeDisappear(this, creature); } }
void Creature::onRemoveTileItem(const Tile* tile, const Position& pos, const ItemType& iType, const Item* item) { if(isMapLoaded){ if(iType.blockSolid || iType.blockPathFind || iType.isGroundTile()){ if(pos.z == getPosition().z){ updateTileCache(tile, pos); } } } }
void Creature::onCreatureAppear(Creature* creature, bool) { if (creature == this) { if (useCacheMap()) { isMapLoaded = true; updateMapCache(); } } else if (isMapLoaded) { if (creature->getPosition().z == getPosition().z) { updateTileCache(creature->getTile(), creature->getPosition()); } } }
void Creature::onCreatureDisappear(const Creature* creature, bool isLogout) { internalCreatureDisappear(creature, true); if(creature == this){ // } else if(isMapLoaded){ if(creature->getPosition().z == getPosition().z){ updateTileCache(creature->getParentTile(), creature->getPosition()); } } }
void Creature::onUpdateTileItem(const Tile* tile, const Position& pos, const Item* oldItem, const ItemType& oldType, const Item* newItem, 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::onCreatureDisappear(const Creature* creature, uint32_t stackpos, bool isLogout) { onCreatureDisappear(creature, true); if (creature == this) { if (getMaster() && !getMaster()->isRemoved()) { getMaster()->removeSummon(this); } } 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) { if (master && !master->isRemoved()) { master->removeSummon(this); } } else if (isMapLoaded) { if (creature->getPosition().z == getPosition().z) { updateTileCache(creature->getTile(), creature->getPosition()); } } }
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::updateMapCache() { Tile* tile; const Position& myPos = getPosition(); Position pos(0, 0, myPos.z); for (int32_t y = -((mapWalkHeight - 1) / 2); y <= ((mapWalkHeight - 1) / 2); ++y) { for (int32_t x = -((mapWalkWidth - 1) / 2); x <= ((mapWalkWidth - 1) / 2); ++x) { pos.x = myPos.getX() + x; pos.y = myPos.getY() + y; tile = g_game.getTile(pos.x, pos.y, myPos.z); updateTileCache(tile, pos); } } }
void Creature::updateMapCache() { const Position& pos = getPosition(); Position dest(0, 0, pos.z); Tile* tile = NULL; for(int32_t y = -((mapWalkHeight - 1) / 2); y <= ((mapWalkHeight - 1) / 2); ++y) { for(int32_t x = -((mapWalkWidth - 1) / 2); x <= ((mapWalkWidth - 1) / 2); ++x) { dest.x = pos.x + x; dest.y = pos.y + y; if((tile = g_game.getTile(dest))) updateTileCache(tile, dest); } } }
void Creature::onCreatureAppear(const Creature* creature, bool isLogin) { if(creature == this){ if(useCacheMap()){ isMapLoaded = true; updateMapCache(); } } else if(isMapLoaded){ if(creature->getPosition().z == getPosition().z){ updateTileCache(creature->getParentTile(), creature->getPosition()); } } if(creature != this){ g_game.onSpotCreature(this, const_cast<Creature*>(creature)); } }
void Creature::onCreatureAppear(const Creature* creature) { if(creature == this) { if(useCacheMap()) { isMapLoaded = true; updateMapCache(); } } else if(isMapLoaded && creature->getPosition().z == getPosition().z) { updateTileCache(creature->getTile(), creature->getPosition()); CreatureEventList disappearEvents = getCreatureEvents(CREATURE_EVENT_APPEAR); for(CreatureEventList::iterator it = disappearEvents.begin(); it != disappearEvents.end(); ++it) (*it)->executeDisappear(this, creature); } }
void Creature::onCreatureMove(const Creature* creature, const Tile* newTile, const Position& newPos, const Tile* oldTile, const Position& oldPos, bool teleport) { if (creature == this) { lastStep = OTSYS_TIME(); lastStepCost = 1; if (!teleport) { if (oldPos.z != newPos.z) { //floor change extra cost lastStepCost = 2; } else if (Position::getDistanceX(newPos, oldPos) >= 1 && Position::getDistanceY(newPos, oldPos) >= 1) { //diagonal extra cost lastStepCost = 2; } } else { stopEventWalk(); } if (!summons.empty()) { //check if any of our summons is out of range (+/- 2 floors or 30 tiles away) std::list<Creature*> despawnList; std::list<Creature*>::iterator cit; for (cit = summons.begin(); cit != summons.end(); ++cit) { const Position pos = (*cit)->getPosition(); if (Position::getDistanceZ(newPos, pos) > 2 || (std::max<int32_t>(Position::getDistanceX(newPos, pos), Position::getDistanceY(newPos, pos)) > 30)) { despawnList.push_back((*cit)); } } for (cit = despawnList.begin(); cit != despawnList.end(); ++cit) { g_game.removeCreature((*cit), true); } } if (newTile->getZone() != oldTile->getZone()) { onChangeZone(getZone()); } //update map cache if (isMapLoaded) { if (teleport || oldPos.z != newPos.z) { updateMapCache(); } else { Tile* tile; const Position& myPos = getPosition(); Position pos; if (oldPos.y > newPos.y) { //north //shift y south for (int32_t y = mapWalkHeight - 1 - 1; y >= 0; --y) { memcpy(localMapCache[y + 1], localMapCache[y], sizeof(localMapCache[y])); } //update 0 for (int32_t x = -((mapWalkWidth - 1) / 2); x <= ((mapWalkWidth - 1) / 2); ++x) { tile = g_game.getTile(myPos.getX() + x, myPos.getY() - ((mapWalkHeight - 1) / 2), myPos.z); updateTileCache(tile, x, -((mapWalkHeight - 1) / 2)); } } else if (oldPos.y < newPos.y) { // south //shift y north for (int32_t y = 0; y <= mapWalkHeight - 1 - 1; ++y) { memcpy(localMapCache[y], localMapCache[y + 1], sizeof(localMapCache[y])); } //update mapWalkHeight - 1 for (int32_t x = -((mapWalkWidth - 1) / 2); x <= ((mapWalkWidth - 1) / 2); ++x) { tile = g_game.getTile(myPos.getX() + x, myPos.getY() + ((mapWalkHeight - 1) / 2), myPos.z); updateTileCache(tile, x, (mapWalkHeight - 1) / 2); } } if (oldPos.x < newPos.x) { // east //shift y west int32_t starty = 0; int32_t endy = mapWalkHeight - 1; int32_t dy = Position::getDistanceY(oldPos, 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 = -((mapWalkHeight - 1) / 2); y <= ((mapWalkHeight - 1) / 2); ++y) { tile = g_game.getTile(myPos.x + ((mapWalkWidth - 1) / 2), myPos.y + y, myPos.z); updateTileCache(tile, (mapWalkWidth - 1) / 2, y); } } else if (oldPos.x > newPos.x) { // west //shift y east int32_t starty = 0; int32_t endy = mapWalkHeight - 1; int32_t dy = Position::getDistanceY(oldPos, 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 - 2; x >= 0; --x) { localMapCache[y][x + 1] = localMapCache[y][x]; } } //update 0 for (int32_t y = -((mapWalkHeight - 1) / 2); y <= ((mapWalkHeight - 1) / 2); ++y) { tile = g_game.getTile(myPos.x - ((mapWalkWidth - 1) / 2), myPos.y + y, myPos.z); updateTileCache(tile, -((mapWalkWidth - 1) / 2), 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)) { if (hasFollowPath) { isUpdatingPath = true; } if (newPos.z != oldPos.z || !canSee(followCreature->getPosition())) { onCreatureDisappear(followCreature, false); } } if (creature == attackedCreature || (creature == this && attackedCreature)) { if (newPos.z != oldPos.z || !canSee(attackedCreature->getPosition())) { onCreatureDisappear(attackedCreature, false); } else { if (hasExtraSwing()) { //our target is moving lets see if we can get in hit g_dispatcher.addTask(createTask(boost::bind(&Game::checkCreatureAttack, &g_game, getID()))); } if (newTile->getZone() != oldTile->getZone()) { onAttackedCreatureChangeZone(attackedCreature->getZone()); } } } }
void Creature::updateTileCache(const Tile* tile) { if(isMapLoaded && tile->getPosition().z == getPosition().z) updateTileCache(tile, tile->getPosition()); }
void Creature::updateTileCache(const Tile* tile, const Position& pos) { const Position& myPos = getPosition(); if(pos.z == myPos.z) updateTileCache(tile, pos.x - myPos.x, pos.y - myPos.y); }
void Creature::onCreatureMove(const Creature* creature, const Tile* newTile, const Position& newPos, const Tile* oldTile, const Position& oldPos, bool teleport) { if(creature == this) { if(!oldTile->floorChange() && !oldTile->positionChange()) setLastPosition(oldPos); lastStep = OTSYS_TIME(); lastStepCost = 1; if(!teleport) { if(std::abs(newPos.x - oldPos.x) >= 1 && std::abs(newPos.y - oldPos.y) >= 1) lastStepCost = 3; } else stopEventWalk(); if(!summons.empty() && (!g_config.getBool(ConfigManager::TELEPORT_SUMMONS) || (g_config.getBool(ConfigManager::TELEPORT_PLAYER_SUMMONS) && !getPlayer()))) { std::list<Creature*>::iterator cit; std::list<Creature*> despawnList; for(cit = summons.begin(); cit != summons.end(); ++cit) { const Position pos = (*cit)->getPosition(); if((std::abs(pos.z - newPos.z) > 2) || (std::max(std::abs(( newPos.x) - pos.x), std::abs((newPos.y - 1) - pos.y)) > 30)) despawnList.push_back(*cit); } for(cit = despawnList.begin(); cit != despawnList.end(); ++cit) g_game.removeCreature((*cit), true); } if(newTile->getZone() != oldTile->getZone()) onChangeZone(getZone()); //update map cache if(isMapLoaded) { if(!teleport && oldPos.z == newPos.z) { Tile* tile = NULL; const Position& myPos = getPosition(); if(oldPos.y > newPos.y) //north { //shift y south for(int32_t y = mapWalkHeight - 1 - 1; y >= 0; --y) memcpy(localMapCache[y + 1], localMapCache[y], sizeof(localMapCache[y])); //update 0 for(int32_t x = -((mapWalkWidth - 1) / 2); x <= ((mapWalkWidth - 1) / 2); ++x) { tile = g_game.getTile(myPos.x + x, myPos.y - ((mapWalkHeight - 1) / 2), myPos.z); updateTileCache(tile, x, -((mapWalkHeight - 1) / 2)); } } else if(oldPos.y < newPos.y) // south { //shift y north for(int32_t y = 0; y <= mapWalkHeight - 1 - 1; ++y) memcpy(localMapCache[y], localMapCache[y + 1], sizeof(localMapCache[y])); //update mapWalkHeight - 1 for(int32_t x = -((mapWalkWidth - 1) / 2); x <= ((mapWalkWidth - 1) / 2); ++x) { tile = g_game.getTile(myPos.x + x, myPos.y + ((mapWalkHeight - 1) / 2), myPos.z); updateTileCache(tile, x, (mapWalkHeight - 1) / 2); } } if(oldPos.x < newPos.x) // east { //shift y west int32_t starty = 0, endy = mapWalkHeight - 1, dy = (oldPos.y - newPos.y); if(dy < 0) endy = endy + dy; else if(dy > 0) starty = starty + dy; for(int32_t y = starty; y <= endy; ++y) { for(int32_t x = 0; x <= mapWalkWidth - 1 - 1; ++x) localMapCache[y][x] = localMapCache[y][x + 1]; } //update mapWalkWidth - 1 for(int32_t y = -((mapWalkHeight - 1) / 2); y <= ((mapWalkHeight - 1) / 2); ++y) { tile = g_game.getTile(myPos.x + ((mapWalkWidth - 1) / 2), myPos.y + y, myPos.z); updateTileCache(tile, (mapWalkWidth - 1) / 2, y); } } else if(oldPos.x > newPos.x) // west { //shift y east int32_t starty = 0, endy = mapWalkHeight - 1, dy = (oldPos.y - newPos.y); if(dy < 0) endy = endy + dy; else if(dy > 0) starty = starty + dy; for(int32_t y = starty; y <= endy; ++y) { for(int32_t x = mapWalkWidth - 1 - 1; x >= 0; --x) localMapCache[y][x + 1] = localMapCache[y][x]; } //update 0 for(int32_t y = -((mapWalkHeight - 1) / 2); y <= ((mapWalkHeight - 1) / 2); ++y) { tile = g_game.getTile(myPos.x - ((mapWalkWidth - 1) / 2), myPos.y + y, myPos.z); updateTileCache(tile, -((mapWalkWidth - 1) / 2), y); } } updateTileCache(oldTile, oldPos); #ifdef __DEBUG__ validateMapCache(); #endif } else updateMapCache(); } } 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)) { if(hasFollowPath) { isUpdatingPath = true; Dispatcher::getInstance().addTask(createTask( boost::bind(&Game::updateCreatureWalk, &g_game, getID()))); } if(newPos.z != oldPos.z || !canSee(followCreature->getPosition())) internalCreatureDisappear(followCreature, false); } if(creature == attackedCreature || (creature == this && attackedCreature)) { if(newPos.z == oldPos.z && canSee(attackedCreature->getPosition())) { if(hasExtraSwing()) //our target is moving lets see if we can get in hit Dispatcher::getInstance().addTask(createTask( boost::bind(&Game::checkCreatureAttack, &g_game, getID()))); if(newTile->getZone() != oldTile->getZone()) onTargetChangeZone(attackedCreature->getZone()); } else internalCreatureDisappear(attackedCreature, false); } }