bool Noun::read( const InStream & input ) { if (! NodeTransform::read( input ) ) return false; // update the frame of this object.. m_Frame = Matrix33( m_vOrientation ); // ensure the parent pointer is set correctly on our traits for(size_t i=0;i<m_Traits.size();) { if (! m_Traits[i].valid() ) { LOG_ERROR( "Noun", "Noun::read() - NULL Trait object." ); m_Traits.erase( m_Traits.begin() + i ); continue; } m_Traits[i]->setParent( this ); ++i; } // make sure traits are sorted by name std::sort( m_Traits.begin(), m_Traits.end(), SortTraits ); m_bPostInit = postInitialize(); // set the last position to the current position setLastPosition( position() ); return true; }
void Creature::onCreatureAppear(const 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::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); } }