GridMapLiquidStatus TerrainInfo::getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, GridMapLiquidData* data) const { GridMapLiquidStatus result = LIQUID_MAP_NO_WATER; VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); uint32 liquid_type = 0; float liquid_level = INVALID_HEIGHT_VALUE; float ground_level = GetHeightStatic(x, y, z, true, DEFAULT_WATER_SEARCH); if (vmgr->GetLiquidLevel(GetMapId(), x, y, z, ReqLiquidType, liquid_level, ground_level, liquid_type)) { // DEBUG_LOG("getLiquidStatus(): vmap liquid level: %f ground: %f type: %u", liquid_level, ground_level, liquid_type); // Check water level and ground level if (liquid_level > ground_level && z > ground_level - 2) { // All ok in water -> store data if (data) { // hardcoded in client like this if (GetMapId() == 530 && liquid_type == 2) liquid_type = 15; uint32 liquidFlagType = 0; if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(liquid_type)) liquidFlagType = liq->Type; if (liquid_type && liquid_type < 21) { if (AreaTableEntry const* area = GetAreaEntryByAreaFlagAndMap(GetAreaFlag(x, y, z), GetMapId())) { uint32 overrideLiquid = area->LiquidTypeOverride[liquidFlagType]; if (!overrideLiquid && area->zone) { area = GetAreaEntryByAreaID(area->zone); if (area) overrideLiquid = area->LiquidTypeOverride[liquidFlagType]; } if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(overrideLiquid)) { liquid_type = overrideLiquid; liquidFlagType = liq->Type; } } } data->level = liquid_level; data->depth_level = ground_level; data->entry = liquid_type; data->type_flags = 1 << liquidFlagType; } // For speed check as int values int delta = int((liquid_level - z) * 10); // Get position delta if (delta > 20) // Under water return LIQUID_MAP_UNDER_WATER; if (delta > 0) // In water return LIQUID_MAP_IN_WATER; if (delta > -1) // Walk on water return LIQUID_MAP_WATER_WALK; result = LIQUID_MAP_ABOVE_WATER; } } else if (GridMap* gmap = const_cast<TerrainInfo*>(this)->GetGrid(x, y)) { GridMapLiquidData map_data; GridMapLiquidStatus map_result = gmap->getLiquidStatus(x, y, z, ReqLiquidType, &map_data); // Not override LIQUID_MAP_ABOVE_WATER with LIQUID_MAP_NO_WATER: if (map_result != LIQUID_MAP_NO_WATER && (map_data.level > ground_level)) { if (data) { // hardcoded in client like this if (GetMapId() == 530 && map_data.entry == 2) map_data.entry = 15; *data = map_data; } return map_result; } } return result; }
bool BattlegroundNA::HandlePlayerUnderMap(Player *player) { player->TeleportTo(GetMapId(), 4055.504395f, 2919.660645f, 13.611241f, player->GetOrientation(), false); return true; }
bool BattleGroundDS::HandlePlayerUnderMap(Player *player) { player->TeleportTo(GetMapId(),1299.046f,784.825f,9.338f,player->GetOrientation(),false); return true; }
// to cache or not to cache, that is the question InstanceTemplate const* DungeonPersistentState::GetTemplate() const { return ObjectMgr::GetInstanceTemplate(GetMapId()); }
bool BattleGroundBE::HandlePlayerUnderMap(Player* player) { player->TeleportTo(GetMapId(), 6238.930176f, 262.963470f, 0.889519f, player->GetOrientation()); return true; }
void Arena::EndBattleground(uint32 winner) { // arena rating calculation if (isRated()) { uint32 loserTeamRating = 0; uint32 loserMatchmakerRating = 0; int32 loserChange = 0; int32 loserMatchmakerChange = 0; uint32 winnerTeamRating = 0; uint32 winnerMatchmakerRating = 0; int32 winnerChange = 0; int32 winnerMatchmakerChange = 0; ArenaTeam* winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner)); ArenaTeam* loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(GetOtherTeam(winner))); if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) { loserTeamRating = loserArenaTeam->GetRating(); loserMatchmakerRating = GetArenaMatchmakerRating(GetOtherTeam(winner)); winnerTeamRating = winnerArenaTeam->GetRating(); winnerMatchmakerRating = GetArenaMatchmakerRating(winner); if (winner != 0) { winnerMatchmakerChange = winnerArenaTeam->WonAgainst(winnerMatchmakerRating, loserMatchmakerRating, winnerChange); loserMatchmakerChange = loserArenaTeam->LostAgainst(loserMatchmakerRating, winnerMatchmakerRating, loserChange); TC_LOG_DEBUG("bg.arena", "match Type: %u --- Winner: old rating: %u, rating gain: %d, old MMR: %u, MMR gain: %d --- Loser: old rating: %u, rating loss: %d, old MMR: %u, MMR loss: %d ---", GetArenaType(), winnerTeamRating, winnerChange, winnerMatchmakerRating, winnerMatchmakerChange, loserTeamRating, loserChange, loserMatchmakerRating, loserMatchmakerChange); SetArenaMatchmakerRating(winner, winnerMatchmakerRating + winnerMatchmakerChange); SetArenaMatchmakerRating(GetOtherTeam(winner), loserMatchmakerRating + loserMatchmakerChange); // bg team that the client expects is different to TeamId // alliance 1, horde 0 uint8 winnerTeam = winner == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; uint8 loserTeam = winner == ALLIANCE ? BG_TEAM_HORDE : BG_TEAM_ALLIANCE; _arenaTeamScores[winnerTeam].Assign(winnerChange, winnerMatchmakerRating, winnerArenaTeam->GetName()); _arenaTeamScores[loserTeam].Assign(loserChange, loserMatchmakerRating, loserArenaTeam->GetName()); TC_LOG_DEBUG("bg.arena", "Arena match Type: %u for Team1Id: %u - Team2Id: %u ended. WinnerTeamId: %u. Winner rating: +%d, Loser rating: %d", GetArenaType(), GetArenaTeamIdByIndex(TEAM_ALLIANCE), GetArenaTeamIdByIndex(TEAM_HORDE), winnerArenaTeam->GetId(), winnerChange, loserChange); if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO)) for (auto const& score : PlayerScores) if (Player* player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HighGuid::Player, score.first))) { TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: %u, Team: %d, IP: %s): %s", GetArenaType(), player->GetName().c_str(), score.first, player->GetArenaTeamId(GetArenaType() == 5 ? 2 : GetArenaType() == 3), player->GetSession()->GetRemoteAddress().c_str(), score.second->ToString().c_str()); } } // Deduct 16 points from each teams arena-rating if there are no winners after 45+2 minutes else { _arenaTeamScores[BG_TEAM_ALLIANCE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, winnerMatchmakerRating, winnerArenaTeam->GetName()); _arenaTeamScores[BG_TEAM_HORDE].Assign(ARENA_TIMELIMIT_POINTS_LOSS, loserMatchmakerRating, loserArenaTeam->GetName()); winnerArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); loserArenaTeam->FinishGame(ARENA_TIMELIMIT_POINTS_LOSS); } uint8 aliveWinners = GetAlivePlayersCountByTeam(winner); for (auto const& i : GetPlayers()) { uint32 team = i.second.Team; if (i.second.OfflineRemoveTime) { // if rated arena match - make member lost! if (team == winner) winnerArenaTeam->OfflineMemberLost(i.first, loserMatchmakerRating, winnerMatchmakerChange); else loserArenaTeam->OfflineMemberLost(i.first, winnerMatchmakerRating, loserMatchmakerChange); continue; } Player* player = _GetPlayer(i.first, i.second.OfflineRemoveTime != 0, "Arena::EndBattleground"); if (!player) continue; // per player calculation if (team == winner) { // update achievement BEFORE personal rating update uint32 rating = player->GetArenaPersonalRating(winnerArenaTeam->GetSlot()); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1); player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA, GetMapId()); // Last standing - Rated 5v5 arena & be solely alive player if (GetArenaType() == ARENA_TYPE_5v5 && aliveWinners == 1 && player->IsAlive()) player->CastSpell(player, SPELL_LAST_MAN_STANDING, true); winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange); } else { loserArenaTeam->MemberLost(player, winnerMatchmakerRating, loserMatchmakerChange); // Arena lost => reset the win_rated_arena having the "no_lose" condition player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE); } } // save the stat changes winnerArenaTeam->SaveToDB(); loserArenaTeam->SaveToDB(); // send updated arena team stats to players // this way all arena team members will get notified, not only the ones who participated in this match winnerArenaTeam->NotifyStatsChanged(); loserArenaTeam->NotifyStatsChanged(); } } // end battleground Battleground::EndBattleground(winner); }
DungeonPersistentState::~DungeonPersistentState() { DEBUG_LOG("Unloading DungeonPersistantState of map %u instance %u", GetMapId(), GetInstanceId()); UnbindThisState(); }
bool Game_Vehicle::IsInCurrentMap() const { return GetMapId() == Game_Map::GetMapId(); }
void Transport::Update(uint32 /*p_time*/) { if (m_WayPoints.size() <= 1) return; m_timer = getMSTime() % m_period; while (((m_timer - m_curr->first) % m_pathTime) > ((m_next->first - m_curr->first) % m_pathTime)) { m_curr = GetNextWayPoint(); m_next = GetNextWayPoint(); // first check help in case client-server transport coordinates de-synchronization if (m_curr->second.mapid != GetMapId() || m_curr->second.teleport) { TeleportTransport(m_curr->second.mapid, m_curr->second.x, m_curr->second.y, m_curr->second.z); } else { Relocate(m_curr->second.x, m_curr->second.y, m_curr->second.z); } /* if (m_curr->second.delayed) { switch (GetEntry()) { case 176495: case 164871: case 175080: SendPlaySound(11804, false); break; // ZeppelinDocked case 20808: case 181646: case 176231: case 176244: case 176310: case 177233: SendPlaySound(5495, false);break; // BoatDockingWarning default: SendPlaySound(5154, false); break; // ShipDocked } } */ /* for (PlayerSet::const_iterator itr = m_passengers.begin(); itr != m_passengers.end();) { PlayerSet::const_iterator it2 = itr; ++itr; //(*it2)->SetPosition( m_curr->second.x + (*it2)->GetTransOffsetX(), m_curr->second.y + (*it2)->GetTransOffsetY(), m_curr->second.z + (*it2)->GetTransOffsetZ(), (*it2)->GetTransOffsetO() ); } */ m_nextNodeTime = m_curr->first; if (m_curr == m_WayPoints.begin() && (sLog.getLogFilter() & LOG_FILTER_TRANSPORT_MOVES)==0) sLog.outDetail(" ************ BEGIN ************** %s", this->m_name.c_str()); if ((sLog.getLogFilter() & LOG_FILTER_TRANSPORT_MOVES)==0) sLog.outDetail("%s moved to %d %f %f %f %d", this->m_name.c_str(), m_curr->second.id, m_curr->second.x, m_curr->second.y, m_curr->second.z, m_curr->second.mapid); //Transport Event System CheckForEvent(this->GetEntry(), m_curr->second.id); } }
void MapMgr::ChangeObjectLocation( Object *obj ) { // Items and containers are of no interest for us if( obj->GetTypeId() == TYPEID_ITEM || obj->GetTypeId() == TYPEID_CONTAINER || obj->GetMapMgr() != this ) { return; } Player* plObj; ByteBuffer * buf = 0; if( obj->GetTypeId() == TYPEID_PLAYER ) { plObj = static_cast< Player* >( obj ); } else { plObj = NULL; } Object* curObj; float fRange; /////////////////////////////////////// // Update in-range data for old objects /////////////////////////////////////// /** let's duplicate some code here :P Less branching is always good. * - Burlex */ /*#define IN_RANGE_LOOP \ for (Object::InRangeSet::iterator iter = obj->GetInRangeSetBegin(), iter2; \ iter != obj->GetInRangeSetEnd();) \ { \ curObj = *iter; \ iter2 = iter; \ ++iter; \ if(curObj->IsPlayer() && obj->IsPlayer() && plObj->m_TransporterGUID && plObj->m_TransporterGUID == static_cast< Player* >( curObj )->m_TransporterGUID ) \ fRange = 0.0f; \ else if((curObj->GetGUIDHigh() == HIGHGUID_TRANSPORTER || obj->GetGUIDHigh() == HIGHGUID_TRANSPORTER)) \ fRange = 0.0f; \ else if((curObj->GetGUIDHigh() == HIGHGUID_GAMEOBJECT && curObj->GetUInt32Value(GAMEOBJECT_TYPE_ID) == GAMEOBJECT_TYPE_TRANSPORT || obj->GetGUIDHigh() == HIGHGUID_GAMEOBJECT && obj->GetUInt32Value(GAMEOBJECT_TYPE_ID) == GAMEOBJECT_TYPE_TRANSPORT)) \ fRange = 0.0f; \ else \ fRange = m_UpdateDistance; \ if (curObj->GetDistance2dSq(obj) > fRange && fRange > 0) \ #define END_IN_RANGE_LOOP } \ if(plObj) { IN_RANGE_LOOP { plObj->RemoveIfVisible(curObj); plObj->RemoveInRangeObject(iter2); if(curObj->NeedsInRangeSet()) curObj->RemoveInRangeObject(obj); if(curObj->IsPlayer()) static_cast< Player* >( curObj )->RemoveIfVisible(obj); } END_IN_RANGE_LOOP } else if(obj->NeedsInRangeSet()) { IN_RANGE_LOOP { if(curObj->NeedsInRangeSet()) curObj->RemoveInRangeObject(obj); if(curObj->IsPlayer()) static_cast< Player* >( curObj )->RemoveIfVisible(obj); obj->RemoveInRangeObject(iter2); } END_IN_RANGE_LOOP } else { IN_RANGE_LOOP { if(curObj->NeedsInRangeSet()) curObj->RemoveInRangeObject(obj); if(curObj->IsPlayer()) { static_cast< Player* >( curObj )->RemoveIfVisible(obj); obj->RemoveInRangePlayer(curObj); } } END_IN_RANGE_LOOP } #undef IN_RANGE_LOOP #undef END_IN_RANGE_LOOP*/ if(obj->HasInRangeObjects()) { for (Object::InRangeSet::iterator iter = obj->GetInRangeSetBegin(), iter2; iter != obj->GetInRangeSetEnd();) { curObj = *iter; iter2 = iter++; if( curObj->IsPlayer() && obj->IsPlayer() && plObj->m_TransporterGUID && plObj->m_TransporterGUID == static_cast< Player* >( curObj )->m_TransporterGUID ) fRange = 0.0f; // unlimited distance for people on same boat else if( curObj->GetTypeFromGUID() == HIGHGUID_TYPE_TRANSPORTER ) fRange = 0.0f; // unlimited distance for transporters (only up to 2 cells +/- anyway.) else fRange = m_UpdateDistance; // normal distance if( fRange > 0.0f && curObj->GetDistance2dSq(obj) > fRange ) { if( plObj ) plObj->RemoveIfVisible(curObj); if( curObj->IsPlayer() ) static_cast< Player* >( curObj )->RemoveIfVisible(obj); curObj->RemoveInRangeObject(obj); if( obj->GetMapMgr() != this ) { /* Something removed us. */ return; } obj->RemoveInRangeObject(iter2); } } } /////////////////////////// // Get new cell coordinates /////////////////////////// if(obj->GetMapMgr() != this) { /* Something removed us. */ return; } if(obj->GetPositionX() >= _maxX || obj->GetPositionX() <= _minX || obj->GetPositionY() >= _maxY || obj->GetPositionY() <= _minY) { if(obj->IsPlayer()) { Player* plr = static_cast< Player* >( obj ); if(plr->GetBindMapId() != GetMapId()) { plr->SafeTeleport(plr->GetBindMapId(),0,plr->GetBindPositionX(),plr->GetBindPositionY(),plr->GetBindPositionZ(),0); plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries."); return; } else { obj->GetPositionV()->ChangeCoords(plr->GetBindPositionX(),plr->GetBindPositionY(),plr->GetBindPositionZ(),0); plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries."); WorldPacket * data = plr->BuildTeleportAckMsg(plr->GetPosition()); plr->GetSession()->SendPacket(data); delete data; } } else { obj->GetPositionV()->ChangeCoords(0,0,0,0); } } uint32 cellX = GetPosX(obj->GetPositionX()); uint32 cellY = GetPosY(obj->GetPositionY()); if(cellX >= _sizeX || cellY >= _sizeY) { return; } MapCell *objCell = GetCell(cellX, cellY); MapCell * pOldCell = obj->GetMapCell(); if (!objCell) { objCell = Create(cellX,cellY); objCell->Init(cellX, cellY, _mapId, this); } // If object moved cell if (objCell != obj->GetMapCell()) { // THIS IS A HACK! // Current code, if a creature on a long waypoint path moves from an active // cell into an inactive one, it will disable itself and will never return. // This is to prevent cpu leaks. I will think of a better solution very soon :P if(!objCell->IsActive() && !plObj && obj->Active) obj->Deactivate(this); if(obj->GetMapCell()) obj->GetMapCell()->RemoveObject(obj); objCell->AddObject(obj); obj->SetMapCell(objCell); // if player we need to update cell activity // radius = 2 is used in order to update both // old and new cells if(obj->GetTypeId() == TYPEID_PLAYER) { // have to unlock/lock here to avoid a deadlock situation. UpdateCellActivity(cellX, cellY, 2); if( pOldCell != NULL ) { // only do the second check if theres -/+ 2 difference if( abs( (int)cellX - (int)pOldCell->_x ) > 2 || abs( (int)cellY - (int)pOldCell->_y ) > 2 ) { UpdateCellActivity( pOldCell->_x, pOldCell->_y, 2 ); } } } } ////////////////////////////////////// // Update in-range set for new objects ////////////////////////////////////// uint32 endX = cellX <= _sizeX ? cellX + 1 : (_sizeX-1); uint32 endY = cellY <= _sizeY ? cellY + 1 : (_sizeY-1); uint32 startX = cellX > 0 ? cellX - 1 : 0; uint32 startY = cellY > 0 ? cellY - 1 : 0; uint32 posX, posY; MapCell *cell; MapCell::ObjectSet::iterator iter; for (posX = startX; posX <= endX; ++posX ) { for (posY = startY; posY <= endY; ++posY ) { cell = GetCell(posX, posY); if (cell) UpdateInRangeSet(obj, plObj, cell, &buf); } } if(buf) delete buf; }
void BattleGroundDS::Update(uint32 diff) { BattleGround::Update(diff); if (GetStatus() == STATUS_IN_PROGRESS) { // push people from the tubes if (pushbackCheck) { // knockback if (m_uiKnockback < diff) { for (BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) { Player *plr = sObjectMgr.GetPlayer(itr->first); if (!plr) continue; if (GameObject* obj = plr->GetGameObject(48018)) // Remove Demonic Circle obj->Delete(); if (plr->GetPositionZ() < 11.0f) continue; float angle = (plr->GetBGTeam() == ALLIANCE /*gold*/) ? plr->GetAngle(1259.58f, 764.43f) : plr->GetAngle(1325.84f, 817.304f); plr->KnockBackPlayerWithAngle(angle, 45, 7); if (plr->IsWithinDist2d(1214, 765, 50) && plr->IsWithinLOS(1214, 765, 14)) plr->KnockBackPlayerWithAngle(6.40f,55,7); if (plr->IsWithinDist2d(1369, 817, 50) && plr->IsWithinLOS(1369, 817, 14)) plr->KnockBackPlayerWithAngle(3.03f,55,7); } pushbackCheck = false; m_uiKnockback = 1000; } else m_uiKnockback -= diff; } // in case pushback failed if (teleportCheck) { if (m_uiTeleport < diff) { for (BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) { if (Player *plr = sObjectMgr.GetPlayer(itr->first)) { if (plr->GetPositionZ() < 11.0f) continue; float x, y; if (plr->GetBGTeam() == ALLIANCE) { x = 1259.58f; y = 764.43f; } else { x = 1325.84f; y = 817.304f; } plr->TeleportTo(GetMapId(), x + urand(0,2), y + urand(0,2), 3.15f, plr->GetOrientation()); } } teleportCheck = false; // close the gate OpenDoorEvent(BG_EVENT_DOOR); } else m_uiTeleport -= diff; } // Waterfall if (m_uiWaterfall < diff) { if (waterfallActivated) { SpawnEvent(WATERFALL_EVENT, 0, false); waterfallActivated = false; } else { SpawnEvent(WATERFALL_EVENT, 0, true); waterfallActivated = true; for (BattleGroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) { Player * plr = sObjectMgr.GetPlayer(itr->first); if (plr && plr->GetDistance2d(1291, 790) <= 6) plr->KnockBackFrom(plr, -20.0f, 9.0f); } } m_uiWaterfall = urand(30,45)*IN_MILLISECONDS; } else m_uiWaterfall -= diff; } }
bool MapMgr::Do() { #ifdef WIN32 threadid=GetCurrentThreadId(); #endif thread_running = true; ThreadState =THREADSTATE_BUSY; SetThreadName("Map mgr - M%u|I%u",this->_mapId ,this->m_instanceID); ObjectSet::iterator i; uint32 last_exec=getMSTime(); /* create static objects */ for(GOSpawnList::iterator itr = _map->staticSpawns.GOSpawns.begin(); itr != _map->staticSpawns.GOSpawns.end(); ++itr) { GameObject * obj = CreateGameObject((*itr)->entry); obj->Load((*itr)); _mapWideStaticObjects.insert(obj); } for(CreatureSpawnList::iterator itr = _map->staticSpawns.CreatureSpawns.begin(); itr != _map->staticSpawns.CreatureSpawns.end(); ++itr) { Creature * obj = CreateCreature((*itr)->entry); obj->Load(*itr, 0, pMapInfo); _mapWideStaticObjects.insert(obj); } /* add static objects */ for(set<Object*>::iterator itr = _mapWideStaticObjects.begin(); itr != _mapWideStaticObjects.end(); ++itr) PushStaticObject(*itr); /* load corpses */ objmgr.LoadCorpses(this); // always declare local variables outside of the loop! // otherwise theres a lot of sub esp; going on. uint32 exec_time, exec_start; #ifdef WIN32 HANDLE hThread = GetCurrentThread(); #endif while((ThreadState != THREADSTATE_TERMINATE) && !_shutdown) { exec_start=getMSTime(); //first push to world new objects m_objectinsertlock.Acquire();//<<<<<<<<<<<<<<<< if(m_objectinsertpool.size()) { for(i=m_objectinsertpool.begin();i!=m_objectinsertpool.end();i++) { //PushObject(*i); (*i)->PushToWorld(this); } m_objectinsertpool.clear(); } m_objectinsertlock.Release();//>>>>>>>>>>>>>>>> //------------------------------------------------------- //Now update sessions of this map + objects _PerformObjectDuties(); last_exec=getMSTime(); exec_time=last_exec-exec_start; if(exec_time<MAP_MGR_UPDATE_PERIOD) { /* The common place I see this is waiting for a Win32 thread to exit. I used to come up with all sorts of goofy, elaborate event-based systems to do this myself until I discovered that thread handles are waitable. Just use WaitForSingleObject() on the thread handle and you're done. No risking race conditions with the thread exit code. I think pthreads has pthread_join() for this too. - http://www.virtualdub.org/blog/pivot/entry.php?id=62 */ #ifdef WIN32 WaitForSingleObject(hThread, MAP_MGR_UPDATE_PERIOD-exec_time); #else Sleep(MAP_MGR_UPDATE_PERIOD-exec_time); #endif } ////////////////////////////////////////////////////////////////////////// // Check if we have to die :P ////////////////////////////////////////////////////////////////////////// if(InactiveMoveTime && UNIXTIME >= InactiveMoveTime) break; } // Clear the instance's reference to us. if(m_battleground) { BattlegroundManager.DeleteBattleground(m_battleground); sInstanceMgr.DeleteBattlegroundInstance( GetMapId(), GetInstanceID() ); } if(pInstance) { // check for a non-raid instance, these expire after 10 minutes. if(GetMapInfo()->type == INSTANCE_NONRAID || pInstance->m_isBattleground) { pInstance->m_mapMgr = NULL; sInstanceMgr._DeleteInstance(pInstance, true); } else { // just null out the pointer pInstance->m_mapMgr=NULL; } } else if(GetMapInfo()->type == INSTANCE_NULL) sInstanceMgr.m_singleMaps[GetMapId()] = NULL; // Teleport any left-over players out. TeleportPlayers(); thread_running = false; if(thread_kill_only) return false; // delete ourselves delete this; // already deleted, so the threadpool doesn't have to. return false; }
void MapMgr::PushObject(Object *obj) { ///////////// // Assertions ///////////// ASSERT(obj); // That object types are not map objects. TODO: add AI groups here? if(obj->GetTypeId() == TYPEID_ITEM || obj->GetTypeId() == TYPEID_CONTAINER) { // mark object as updatable and exit return; } if(obj->GetTypeId() == TYPEID_CORPSE) { m_corpses.insert(((Corpse*)obj)); } obj->ClearInRangeSet(); ASSERT(obj->GetMapId() == _mapId); if(!(obj->GetPositionX() < _maxX && obj->GetPositionX() > _minX) || !(obj->GetPositionY() < _maxY && obj->GetPositionY() > _minY)) { if(obj->IsPlayer()) { Player * plr = static_cast< Player* >( obj ); if(plr->GetBindMapId() != GetMapId()) { plr->SafeTeleport(plr->GetBindMapId(),0,plr->GetBindPositionX(),plr->GetBindPositionY(),plr->GetBindPositionZ(),0); plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries."); return; } else { obj->GetPositionV()->ChangeCoords(plr->GetBindPositionX(),plr->GetBindPositionY(),plr->GetBindPositionZ(),0); plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries."); WorldPacket * data = plr->BuildTeleportAckMsg(plr->GetPosition()); plr->GetSession()->SendPacket(data); delete data; } } else { obj->GetPositionV()->ChangeCoords(0,0,0,0); } } ASSERT(obj->GetPositionY() < _maxY && obj->GetPositionY() > _minY); ASSERT(_cells); /////////////////////// // Get cell coordinates /////////////////////// uint32 x = GetPosX(obj->GetPositionX()); uint32 y = GetPosY(obj->GetPositionY()); if(x >= _sizeX || y >= _sizeY) { if(obj->IsPlayer()) { Player * plr = static_cast< Player* >( obj ); if(plr->GetBindMapId() != GetMapId()) { plr->SafeTeleport(plr->GetBindMapId(),0,plr->GetBindPositionX(),plr->GetBindPositionY(),plr->GetBindPositionZ(),0); plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries."); return; } else { obj->GetPositionV()->ChangeCoords(plr->GetBindPositionX(),plr->GetBindPositionY(),plr->GetBindPositionZ(),0); plr->GetSession()->SystemMessage("Teleported you to your hearthstone location as you were out of the map boundaries."); WorldPacket * data = plr->BuildTeleportAckMsg(plr->GetPosition()); plr->GetSession()->SendPacket(data); delete data; } } else { obj->GetPositionV()->ChangeCoords(0,0,0,0); } x = GetPosX(obj->GetPositionX()); y = GetPosY(obj->GetPositionY()); } MapCell *objCell = GetCell(x,y); if (!objCell) { objCell = Create(x,y); objCell->Init(x, y, _mapId, this); } uint32 endX = (x <= _sizeX) ? x + 1 : (_sizeX-1); uint32 endY = (y <= _sizeY) ? y + 1 : (_sizeY-1); uint32 startX = x > 0 ? x - 1 : 0; uint32 startY = y > 0 ? y - 1 : 0; uint32 posX, posY; MapCell *cell; MapCell::ObjectSet::iterator iter; ByteBuffer * buf = 0; uint32 count; Player *plObj; if(obj->GetTypeId() == TYPEID_PLAYER) plObj = static_cast< Player* >( obj ); else plObj = NULL; if(plObj) { sLog.outDetail("Creating player "I64FMT" for himself.", obj->GetGUID()); ByteBuffer pbuf(10000); count = plObj->BuildCreateUpdateBlockForPlayer(&pbuf, plObj); plObj->PushCreationData(&pbuf, count); } ////////////////////// // Build in-range data ////////////////////// for (posX = startX; posX <= endX; posX++ ) { for (posY = startY; posY <= endY; posY++ ) { cell = GetCell(posX, posY); if (cell) { UpdateInRangeSet(obj, plObj, cell, &buf); } } } //Add to the cell's object list objCell->AddObject(obj); obj->SetMapCell(objCell); //Add to the mapmanager's object list if(plObj) { m_PlayerStorage[plObj->GetLowGUID()] = plObj; UpdateCellActivity(x, y, 2); } else { switch(obj->GetTypeFromGUID()) { case HIGHGUID_TYPE_PET: m_PetStorage[obj->GetUIdFromGUID()] = static_cast< Pet* >( obj ); break; case HIGHGUID_TYPE_UNIT: { ASSERT((obj->GetUIdFromGUID()) <= m_CreatureHighGuid); m_CreatureStorage[obj->GetUIdFromGUID()] = (Creature*)obj; if(((Creature*)obj)->m_spawn != NULL) { _sqlids_creatures.insert(make_pair( ((Creature*)obj)->m_spawn->id, ((Creature*)obj) ) ); } }break; case HIGHGUID_TYPE_GAMEOBJECT: { m_GOStorage[obj->GetUIdFromGUID()] = (GameObject*)obj; if(((GameObject*)obj)->m_spawn != NULL) { _sqlids_gameobjects.insert(make_pair( ((GameObject*)obj)->m_spawn->id, ((GameObject*)obj) ) ); } }break; case HIGHGUID_TYPE_DYNAMICOBJECT: m_DynamicObjectStorage[obj->GetLowGUID()] = (DynamicObject*)obj; break; } } // Handle activation of that object. if(objCell->IsActive() && obj->CanActivate()) obj->Activate(this); // Add the session to our set if it is a player. if(plObj) { Sessions.insert(plObj->GetSession()); // Change the instance ID, this will cause it to be removed from the world thread (return value 1) plObj->GetSession()->SetInstance(GetInstanceID()); /* Add the map wide objects */ if(_mapWideStaticObjects.size()) { if(!buf) buf = new ByteBuffer(300); for(set<Object*>::iterator itr = _mapWideStaticObjects.begin(); itr != _mapWideStaticObjects.end(); ++itr) { count = (*itr)->BuildCreateUpdateBlockForPlayer(buf, plObj); plObj->PushCreationData(buf, count); } } } if(buf) delete buf; if(plObj && InactiveMoveTime && !forced_expire) InactiveMoveTime = 0; }
void DynamicObject::Update(uint32 p_time) { // caster can be not in world at time dynamic object update, but dynamic object not yet deleted in Unit destructor Unit* caster = GetCaster(); if(!caster) { Delete(); return; } bool deleteThis = false; if(m_aliveDuration > int32(p_time)) m_aliveDuration -= p_time; else deleteThis = true; // TODO: make a timer and update this in larger intervals CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY())); Cell cell = RedZone::GetZone(p); cell.data.Part.reserved = ALL_DISTRICT; cell.SetNoCreate(); MaNGOS::DynamicObjectUpdater notifier(*this,caster); TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, WorldTypeMapContainer > world_object_notifier(notifier); TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, GridTypeMapContainer > grid_object_notifier(notifier); CellLock<GridReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(GetMapId(), this)); cell_lock->Visit(cell_lock, grid_object_notifier, *MapManager::Instance().GetMap(GetMapId(), this)); if(deleteThis) { caster->RemoveDynObjectWithGUID(GetGUID()); Delete(); } }
void GameObject::Update(uint32 diff) { if (IS_MO_TRANSPORT(GetGUID())) { //((Transport*)this)->Update(p_time); return; } switch (m_lootState) { case GO_NOT_READY: { switch(GetGoType()) { case GAMEOBJECT_TYPE_TRAP: { // Arming Time for GAMEOBJECT_TYPE_TRAP (6) Unit* owner = GetOwner(); if (owner && ((Player*)owner)->isInCombat()) m_cooldownTime = time(NULL) + GetGOInfo()->trap.startDelay; m_lootState = GO_READY; break; } case GAMEOBJECT_TYPE_FISHINGNODE: { // fishing code (bobber ready) if( time(NULL) > m_respawnTime - FISHING_BOBBER_READY_TIME ) { // splash bobber (bobber ready now) Unit* caster = GetOwner(); if(caster && caster->GetTypeId()==TYPEID_PLAYER) { SetGoState(0); SetUInt32Value(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN); UpdateData udata; WorldPacket packet; BuildValuesUpdateBlockForPlayer(&udata,((Player*)caster)); udata.BuildPacket(&packet); ((Player*)caster)->GetSession()->SendPacket(&packet); WorldPacket data(SMSG_GAMEOBJECT_CUSTOM_ANIM,8+4); data << GetGUID(); data << (uint32)(0); ((Player*)caster)->SendMessageToSet(&data,true); } m_lootState = GO_READY; // can be successfully open with some chance } return; } default: m_lootState = GO_READY; // for other GOis same switched without delay to GO_READY break; } // NO BREAK for switch (m_lootState) } case GO_READY: { if (m_respawnTime > 0) // timer on { if (m_respawnTime <= time(NULL)) // timer expired { m_respawnTime = 0; m_SkillupList.clear(); m_usetimes = 0; switch (GetGoType()) { case GAMEOBJECT_TYPE_FISHINGNODE: // can't fish now { Unit* caster = GetOwner(); if(caster && caster->GetTypeId()==TYPEID_PLAYER) { if(caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) { caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(false); } WorldPacket data(SMSG_FISH_NOT_HOOKED,0); ((Player*)caster)->GetSession()->SendPacket(&data); } // can be delete m_lootState = GO_JUST_DEACTIVATED; return; } case GAMEOBJECT_TYPE_DOOR: case GAMEOBJECT_TYPE_BUTTON: //we need to open doors if they are closed (add there another condition if this code breaks some usage, but it need to be here for battlegrounds) if( !GetGoState() ) SwitchDoorOrButton(false); //flags in AB are type_button and we need to add them here so no break! default: if(!m_spawnedByDefault) // despawn timer { // can be despawned or destroyed SetLootState(GO_JUST_DEACTIVATED); return; } // respawn timer MapManager::Instance().GetMap(GetMapId(), this)->Add(this); break; } } } // traps can have time and can not have GameObjectInfo const* goInfo = GetGOInfo(); if(goInfo->type == GAMEOBJECT_TYPE_TRAP) { // traps Unit* owner = GetOwner(); Unit* ok = NULL; // pointer to appropriate target if found any if(m_cooldownTime >= time(NULL)) return; bool IsBattleGroundTrap = false; //FIXME: this is activation radius (in different casting radius that must be selected from spell data) //TODO: move activated state code (cast itself) to GO_ACTIVATED, in this place only check activating and set state float radius = goInfo->trap.radius; if(!radius) { if(goInfo->trap.cooldown != 3) // cast in other case (at some triggering/linked go/etc explicit call) { // try to read radius from trap spell if(const SpellEntry *spellEntry = sSpellStore.LookupEntry(goInfo->trap.spellId)) radius = GetSpellRadius(spellEntry,0,false); // radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellEntry->EffectRadiusIndex[0])); if(!radius) break; } else { if(m_respawnTime > 0) break; radius = goInfo->trap.cooldown; // battlegrounds gameobjects has data2 == 0 && data5 == 3 IsBattleGroundTrap = true; } } bool NeedDespawn = (goInfo->trap.charges != 0); CellPair p(Trinity::ComputeCellPair(GetPositionX(),GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; // Note: this hack with search required until GO casting not implemented // search unfriendly creature if(owner && NeedDespawn) // hunter trap { Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck u_check(this, owner, radius); Trinity::UnitSearcher<Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck> checker(ok, u_check); CellLock<GridReadGuard> cell_lock(cell, p); TypeContainerVisitor<Trinity::UnitSearcher<Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker); cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); // or unfriendly player/pet if(!ok) { TypeContainerVisitor<Trinity::UnitSearcher<Trinity::AnyUnfriendlyNoTotemUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); } } else // environmental trap { // environmental damage spells already have around enemies targeting but this not help in case not existed GO casting support // affect only players Player* p_ok = NULL; Trinity::AnyPlayerInObjectRangeCheck p_check(this, radius); Trinity::PlayerSearcher<Trinity::AnyPlayerInObjectRangeCheck> checker(p_ok, p_check); CellLock<GridReadGuard> cell_lock(cell, p); TypeContainerVisitor<Trinity::PlayerSearcher<Trinity::AnyPlayerInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker); cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); ok = p_ok; } if (ok) { //Unit *caster = owner ? owner : ok; //caster->CastSpell(ok, goInfo->trap.spellId, true); CastSpell(ok, goInfo->trap.spellId); m_cooldownTime = time(NULL) + 4; // 4 seconds if(NeedDespawn) SetLootState(GO_JUST_DEACTIVATED); // can be despawned or destroyed if(IsBattleGroundTrap && ok->GetTypeId() == TYPEID_PLAYER) { //BattleGround gameobjects case if(((Player*)ok)->InBattleGround()) if(BattleGround *bg = ((Player*)ok)->GetBattleGround()) bg->HandleTriggerBuff(GetGUID()); } } } if (m_charges && m_usetimes >= m_charges) SetLootState(GO_JUST_DEACTIVATED); // can be despawned or destroyed break; } case GO_ACTIVATED: { switch(GetGoType()) { case GAMEOBJECT_TYPE_DOOR: case GAMEOBJECT_TYPE_BUTTON: if(GetAutoCloseTime() && (m_cooldownTime < time(NULL))) { SwitchDoorOrButton(false); SetLootState(GO_JUST_DEACTIVATED); } break; case GAMEOBJECT_TYPE_CHEST: if(m_groupLootTimer && lootingGroupLeaderGUID) { if(diff <= m_groupLootTimer) { m_groupLootTimer -= diff; } else { Group* group = objmgr.GetGroupByLeader(lootingGroupLeaderGUID); if (group) group->EndRoll(); m_groupLootTimer = 0; lootingGroupLeaderGUID = 0; } } break; } break; } case GO_JUST_DEACTIVATED: { //if Gameobject should cast spell, then this, but some GOs (type = 10) should be destroyed if (GetGoType() == GAMEOBJECT_TYPE_GOOBER) { uint32 spellId = GetGOInfo()->goober.spellId; if(spellId) { std::set<uint32>::iterator it = m_unique_users.begin(); std::set<uint32>::iterator end = m_unique_users.end(); for (; it != end; it++) { Unit* owner = Unit::GetUnit(*this, uint64(*it)); if (owner) owner->CastSpell(owner, spellId, false); } m_unique_users.clear(); m_usetimes = 0; } //any return here in case battleground traps } if(GetOwnerGUID()) { m_respawnTime = 0; Delete(); return; } //burning flags in some battlegrounds, if you find better condition, just add it if (GetGoAnimProgress() > 0) { SendObjectDeSpawnAnim(this->GetGUID()); //reset flags SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags); } loot.clear(); SetLootState(GO_READY); if(!m_respawnDelayTime) return; if(!m_spawnedByDefault) { m_respawnTime = 0; return; } m_respawnTime = time(NULL) + m_respawnDelayTime; // if option not set then object will be saved at grid unload if(sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY)) SaveRespawnTime(); ObjectAccessor::UpdateObjectVisibility(this); break; } } }
bool BattleGroundRV::HandlePlayerUnderMap(Player *player) { player->TeleportTo(GetMapId(), 763.5f, -284, 28.276f, player->GetOrientation(), false); return true; }
void GameObject::Use(Unit* user) { // by default spell caster is user Unit* spellCaster = user; uint32 spellId = 0; switch(GetGoType()) { case GAMEOBJECT_TYPE_DOOR: //0 case GAMEOBJECT_TYPE_BUTTON: //1 //doors/buttons never really despawn, only reset to default state/flags UseDoorOrButton(); // activate script sWorld.ScriptsStart(sGameObjectScripts, GetDBTableGUIDLow(), spellCaster, this); return; case GAMEOBJECT_TYPE_QUESTGIVER: //2 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; player->PrepareQuestMenu( GetGUID() ); player->SendPreparedQuest( GetGUID() ); return; } //Sitting: Wooden bench, chairs enzz case GAMEOBJECT_TYPE_CHAIR: //7 { GameObjectInfo const* info = GetGOInfo(); if(!info) return; if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; // a chair may have n slots. we have to calculate their positions and teleport the player to the nearest one // check if the db is sane if(info->chair.slots > 0) { float lowestDist = DEFAULT_VISIBILITY_DISTANCE; float x_lowest = GetPositionX(); float y_lowest = GetPositionY(); // the object orientation + 1/2 pi // every slot will be on that straight line float orthogonalOrientation = GetOrientation()+M_PI*0.5f; // find nearest slot for(uint32 i=0; i<info->chair.slots; i++) { // the distance between this slot and the center of the go - imagine a 1D space float relativeDistance = (info->size*i)-(info->size*(info->chair.slots-1)/2.0f); float x_i = GetPositionX() + relativeDistance * cos(orthogonalOrientation); float y_i = GetPositionY() + relativeDistance * sin(orthogonalOrientation); // calculate the distance between the player and this slot float thisDistance = player->GetDistance2d(x_i, y_i); /* debug code. It will spawn a npc on each slot to visualize them. Creature* helper = player->SummonCreature(14496, x_i, y_i, GetPositionZ(), GetOrientation(), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10000); std::ostringstream output; output << i << ": thisDist: " << thisDistance; helper->MonsterSay(output.str().c_str(), LANG_UNIVERSAL, 0); */ if(thisDistance <= lowestDist) { lowestDist = thisDistance; x_lowest = x_i; y_lowest = y_i; } } player->TeleportTo(GetMapId(), x_lowest, y_lowest, GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET); } else { // fallback, will always work player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET); } player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR+info->chair.height); return; } //big gun, its a spell/aura case GAMEOBJECT_TYPE_GOOBER: //10 { GameObjectInfo const* info = GetGOInfo(); if(user->GetTypeId()==TYPEID_PLAYER) { Player* player = (Player*)user; // show page if(info->goober.pageId) { WorldPacket data(SMSG_GAMEOBJECT_PAGETEXT, 8); data << GetGUID(); player->GetSession()->SendPacket(&data); } // possible quest objective for active quests player->CastedCreatureOrGO(info->id, GetGUID(), 0); } // cast this spell later if provided spellId = info->goober.spellId; break; } case GAMEOBJECT_TYPE_CAMERA: //13 { GameObjectInfo const* info = GetGOInfo(); if(!info) return; if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; if(info->camera.cinematicId) { WorldPacket data(SMSG_TRIGGER_CINEMATIC, 4); data << info->camera.cinematicId; player->GetSession()->SendPacket(&data); } return; } //fishing bobber case GAMEOBJECT_TYPE_FISHINGNODE: //17 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; if(player->GetGUID() != GetOwnerGUID()) return; switch(getLootState()) { case GO_READY: // ready for loot { // 1) skill must be >= base_zone_skill // 2) if skill == base_zone_skill => 5% chance // 3) chance is linear dependence from (base_zone_skill-skill) uint32 subzone = GetAreaId(); int32 zone_skill = objmgr.GetFishingBaseSkillLevel( subzone ); if(!zone_skill) zone_skill = objmgr.GetFishingBaseSkillLevel( GetZoneId() ); //provide error, no fishable zone or area should be 0 if(!zone_skill) sLog.outErrorDb("Fishable areaId %u are not properly defined in `skill_fishing_base_level`.",subzone); int32 skill = player->GetSkillValue(SKILL_FISHING); int32 chance = skill - zone_skill + 5; int32 roll = GetMap()->irand(1,100); DEBUG_LOG("Fishing check (skill: %i zone min skill: %i chance %i roll: %i",skill,zone_skill,chance,roll); if(skill >= zone_skill && chance >= roll) { // prevent removing GO at spell cancel player->RemoveGameObject(this,false); SetOwnerGUID(player->GetGUID()); //fish catched player->UpdateFishingSkill(); GameObject* ok = LookupFishingHoleAround(DEFAULT_VISIBILITY_DISTANCE); if (ok) { player->SendLoot(ok->GetGUID(),LOOT_FISHINGHOLE); SetLootState(GO_JUST_DEACTIVATED); } else player->SendLoot(GetGUID(),LOOT_FISHING); } else { // fish escaped, can be deleted now SetLootState(GO_JUST_DEACTIVATED); WorldPacket data(SMSG_FISH_ESCAPED, 0); player->GetSession()->SendPacket(&data); } break; } case GO_JUST_DEACTIVATED: // nothing to do, will be deleted at next update break; default: { SetLootState(GO_JUST_DEACTIVATED); WorldPacket data(SMSG_FISH_NOT_HOOKED, 0); player->GetSession()->SendPacket(&data); break; } } if(player->m_currentSpells[CURRENT_CHANNELED_SPELL]) { player->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); player->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(); } return; } case GAMEOBJECT_TYPE_SUMMONING_RITUAL: //18 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; Unit* caster = GetOwner(); GameObjectInfo const* info = GetGOInfo(); if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) return; // accept only use by player from same group for caster except caster itself if(((Player*)caster)==player || !((Player*)caster)->IsInSameRaidWith(player)) return; AddUniqueUse(player); // full amount unique participants including original summoner if(GetUniqueUseCount() < info->summoningRitual.reqParticipants) return; // in case summoning ritual caster is GO creator spellCaster = caster; if(!caster->m_currentSpells[CURRENT_CHANNELED_SPELL]) return; spellId = info->summoningRitual.spellId; // finish spell caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->SendChannelUpdate(0); caster->m_currentSpells[CURRENT_CHANNELED_SPELL]->finish(); // can be deleted now SetLootState(GO_JUST_DEACTIVATED); // go to end function to spell casting break; } case GAMEOBJECT_TYPE_SPELLCASTER: //22 { SetUInt32Value(GAMEOBJECT_FLAGS,2); GameObjectInfo const* info = GetGOInfo(); if(!info) return; if(info->spellcaster.partyOnly) { Unit* caster = GetOwner(); if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) return; if(user->GetTypeId()!=TYPEID_PLAYER || !((Player*)user)->IsInSameRaidWith((Player*)caster)) return; } spellId = info->spellcaster.spellId; AddUse(); break; } case GAMEOBJECT_TYPE_MEETINGSTONE: //23 { GameObjectInfo const* info = GetGOInfo(); if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; Player* targetPlayer = ObjectAccessor::FindPlayer(player->GetSelection()); // accept only use by player from same group for caster except caster itself if(!targetPlayer || targetPlayer == player || !targetPlayer->IsInSameGroupWith(player)) return; //required lvl checks! uint8 level = player->getLevel(); if (level < info->meetingstone.minLevel || level > info->meetingstone.maxLevel) return; level = targetPlayer->getLevel(); if (level < info->meetingstone.minLevel || level > info->meetingstone.maxLevel) return; spellId = 23598; break; } case GAMEOBJECT_TYPE_FLAGSTAND: // 24 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; if( player->isAllowUseBattleGroundObject() ) { // in battleground check BattleGround *bg = player->GetBattleGround(); if(!bg) return; // BG flag click // AB: // 15001 // 15002 // 15003 // 15004 // 15005 bg->EventPlayerClickedOnFlag(player, this); return; //we don;t need to delete flag ... it is despawned! } break; } case GAMEOBJECT_TYPE_FLAGDROP: // 26 { if(user->GetTypeId()!=TYPEID_PLAYER) return; Player* player = (Player*)user; if( player->isAllowUseBattleGroundObject() ) { // in battleground check BattleGround *bg = player->GetBattleGround(); if(!bg) return; // BG flag dropped // WS: // 179785 - Silverwing Flag // 179786 - Warsong Flag // EotS: // 184142 - Netherstorm Flag GameObjectInfo const* info = GetGOInfo(); if(info) { switch(info->id) { case 179785: // Silverwing Flag // check if it's correct bg if(bg->GetTypeID() == BATTLEGROUND_WS) bg->EventPlayerClickedOnFlag(player, this); break; case 179786: // Warsong Flag if(bg->GetTypeID() == BATTLEGROUND_WS) bg->EventPlayerClickedOnFlag(player, this); break; case 184142: // Netherstorm Flag if(bg->GetTypeID() == BATTLEGROUND_EY) bg->EventPlayerClickedOnFlag(player, this); break; } } //this cause to call return, all flags must be deleted here!! spellId = 0; Delete(); } break; } default: sLog.outDebug("Unknown Object Type %u", GetGoType()); break; } if(!spellId) return; SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellId ); if(!spellInfo) { if(user->GetTypeId()!=TYPEID_PLAYER || !sOutdoorPvPMgr.HandleCustomSpell((Player*)user,spellId,this)) sLog.outError("WORLD: unknown spell id %u at use action for gameobject (Entry: %u GoType: %u )", spellId,GetEntry(),GetGoType()); else sLog.outDebug("WORLD: %u non-dbc spell was handled by OutdoorPvP", spellId); return; } Spell *spell = new Spell(spellCaster, spellInfo, false); // spell target is user of GO SpellCastTargets targets; targets.setUnitTarget( user ); spell->prepare(&targets); }
void Player::Reputation_OnKilledUnit(Unit* pUnit, bool InnerLoop) { // add rep for on kill if(pUnit->GetTypeId() != TYPEID_UNIT || pUnit->IsPet()) return; Group * m_Group = m_playerInfo->m_Group; if(!InnerLoop && m_Group) { /* loop the rep for group members */ m_Group->getLock().Acquire(); GroupMembersSet::iterator it; for(uint32 i = 0; i < m_Group->GetSubGroupCount(); ++i) { for(it = m_Group->GetSubGroup(i)->GetGroupMembersBegin(); it != m_Group->GetSubGroup(i)->GetGroupMembersEnd(); ++it) { if((*it)->m_loggedInPlayer && (*it)->m_loggedInPlayer->isInRange(TO_PLAYER(this),100.0f)) (*it)->m_loggedInPlayer->Reputation_OnKilledUnit(pUnit, true); } } m_Group->getLock().Release(); return; } int team = GetTeam(); ReputationModifier * modifier = objmgr.GetReputationModifier(pUnit->GetEntry(), pUnit->m_factionDBC->ID); if(modifier != 0) { // Apply this data. for(vector<ReputationMod>::iterator itr = modifier->mods.begin(); itr != modifier->mods.end(); ++itr) { if(!(*itr).faction[team]) continue; /* rep limit? */ if (!IS_INSTANCE(GetMapId()) || (IS_INSTANCE(GetMapId()) && this->iInstanceType != MODE_5PLAYER_HEROIC)) { if((*itr).replimit) { if(GetStanding((*itr).faction[team]) >= (int32)(*itr).replimit) continue; } } int32 value = int32(float(itr->value) * sWorld.getRate(RATE_KILLREPUTATION)); //value *= sWorld.getRate(RATE_KILLREPUTATION); ModStanding(itr->faction[team], value); } } else { if(IS_INSTANCE(GetMapId()) && objmgr.HandleInstanceReputationModifiers(TO_PLAYER(this), pUnit)) return; if(pUnit->m_factionDBC->RepListId < 0) return; // decrease rep by 5. int change = -5; change = int32((float(change) * sWorld.getRate(RATE_KILLREPUTATION))); ModStanding(pUnit->m_factionDBC->ID, change); } }
void Player::UseResearchSite(uint32 id) { _researchSites.erase(id); GenerateResearchSiteInMap(GetMapId()); }
float TerrainInfo::GetHeight(float x, float y, float z, bool pUseVmaps, float maxSearchDist) const { // find raw .map surface under Z coordinates float mapHeight; float z2 = z + 2.f; if (GridMap *gmap = const_cast<TerrainInfo*>(this)->GetGrid(x, y)) { float _mapheight = gmap->getHeight(x,y); // look from a bit higher pos to find the floor, ignore under surface case if (z2 > _mapheight) mapHeight = _mapheight; else mapHeight = VMAP_INVALID_HEIGHT_VALUE; } else mapHeight = VMAP_INVALID_HEIGHT_VALUE; float vmapHeight; if (pUseVmaps) { VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager(); if (vmgr->isHeightCalcEnabled()) { // if mapHeight has been found search vmap height at least until mapHeight point // this prevent case when original Z "too high above ground and vmap height search fail" // this will not affect most normal cases (no map in instance, or stay at ground at continent) if (mapHeight > INVALID_HEIGHT && z2 - mapHeight > maxSearchDist) maxSearchDist = z2 - mapHeight + 1.0f; // 1.0 make sure that we not fail for case when map height near but above for vamp height // look from a bit higher pos to find the floor vmapHeight = vmgr->getHeight(GetMapId(), x, y, z2, maxSearchDist); } else vmapHeight = VMAP_INVALID_HEIGHT_VALUE; } else vmapHeight = VMAP_INVALID_HEIGHT_VALUE; //hack for LK frozen throne true height if (GetAreaId(x,y,z) == 4859) { mapHeight += 200.0f; vmapHeight += 200.0f; } // mapHeight set for any above raw ground Z or <= INVALID_HEIGHT // vmapheight set for any under Z value or <= INVALID_HEIGHT if (vmapHeight > INVALID_HEIGHT) { if (mapHeight > INVALID_HEIGHT) { // we have mapheight and vmapheight and must select more appropriate // we are already under the surface or vmap height above map heigt // or if the distance of the vmap height is less the land height distance if (z < mapHeight || vmapHeight > mapHeight || fabs(mapHeight-z) > fabs(vmapHeight-z)) return vmapHeight; else return mapHeight; // better use .map surface height } else return vmapHeight; // we have only vmapHeight (if have) } return mapHeight; }
/* Called from AddPersistentState */ void DungeonPersistentState::SaveToDB() { // state instance data too std::string data; if (Map* map = GetMap()) { InstanceData* iData = map->GetInstanceData(); if (iData && iData->Save()) { data = iData->Save(); CharacterDatabase.escape_string(data); } } CharacterDatabase.PExecute("INSERT INTO instance VALUES ('%u', '%u', '" UI64FMTD "', '%u', '%u', '%s')", GetInstanceId(), GetMapId(), (uint64)GetResetTimeForDB(), GetDifficulty(), GetCompletedEncountersMask(), data.c_str()); }
bool Creature::Load(CreatureSpawn *spawn, uint32 mode, MapInfo *info) { m_spawn = spawn; proto = CreatureProtoStorage.LookupEntry(spawn->entry); if(!proto) return false; creature_info = CreatureNameStorage.LookupEntry(spawn->entry); if(!creature_info) return false; spawnid = spawn->id; m_walkSpeed = m_base_walkSpeed = proto->walk_speed; //set speeds m_runSpeed = m_base_runSpeed = proto->run_speed; //set speeds m_flySpeed = proto->fly_speed; //Set fields SetUInt32Value(OBJECT_FIELD_ENTRY,proto->Id); SetFloatValue(OBJECT_FIELD_SCALE_X,proto->Scale); //SetUInt32Value(UNIT_FIELD_HEALTH, (mode ? long2int32(proto->Health * 1.5) : proto->Health)); //SetUInt32Value(UNIT_FIELD_BASE_HEALTH, (mode ? long2int32(proto->Health * 1.5) : proto->Health)); //SetUInt32Value(UNIT_FIELD_MAXHEALTH, (mode ? long2int32(proto->Health * 1.5) : proto->Health)); uint32 health = proto->MinHealth + RandomUInt(proto->MaxHealth - proto->MinHealth); if(mode) health = long2int32(double(health) * 1.5); SetUInt32Value(UNIT_FIELD_HEALTH, health); SetUInt32Value(UNIT_FIELD_MAXHEALTH, health); SetUInt32Value(UNIT_FIELD_BASE_HEALTH, health); SetUInt32Value(UNIT_FIELD_POWER1,proto->Mana); SetUInt32Value(UNIT_FIELD_MAXPOWER1,proto->Mana); SetUInt32Value(UNIT_FIELD_BASE_MANA,proto->Mana); // Whee, thank you blizz, I love patch 2.2! Later on, we can randomize male/female mobs! xD // Determine gender (for voices) //if(spawn->displayid != creature_info->Male_DisplayID) // setGender(1); // Female uint32 model; uint32 gender = creature_info->GenerateModelId(&model); setGender(gender); SetUInt32Value(UNIT_FIELD_DISPLAYID,model); SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID,model); SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,proto->MountedDisplayID); //SetUInt32Value(UNIT_FIELD_LEVEL, (mode ? proto->Level + (info ? info->lvl_mod_a : 0) : proto->Level)); SetUInt32Value(UNIT_FIELD_LEVEL, proto->MinLevel + (RandomUInt(proto->MaxLevel - proto->MinLevel))); if(mode && info) ModUnsigned32Value(UNIT_FIELD_LEVEL, info->lvl_mod_a); for(uint32 i = 0; i < 7; ++i) SetUInt32Value(UNIT_FIELD_RESISTANCES+i,proto->Resistances[i]); SetUInt32Value(UNIT_FIELD_BASEATTACKTIME,proto->AttackTime); SetFloatValue(UNIT_FIELD_MINDAMAGE, (mode ? proto->MinDamage * 1.5f : proto->MinDamage)); SetFloatValue(UNIT_FIELD_MAXDAMAGE, (mode ? proto->MaxDamage * 1.5f : proto->MaxDamage)); SetUInt32Value(UNIT_FIELD_RANGEDATTACKTIME,proto->RangedAttackTime); SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE,proto->RangedMinDamage); SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE,proto->RangedMaxDamage); SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, proto->Item1SlotDisplay); SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_01, proto->Item2SlotDisplay); SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY_02, proto->Item3SlotDisplay); SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, proto->Item1Info1); SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO_01, proto->Item1Info2); SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO_02, proto->Item2Info1); SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO_03, proto->Item2Info2); SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO_04, proto->Item3Info1); SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO_05, proto->Item3Info2); SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, spawn->factionid); SetUInt32Value(UNIT_FIELD_FLAGS, spawn->flags); SetUInt32Value(UNIT_NPC_EMOTESTATE, spawn->emote_state); SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, proto->BoundingRadius); SetFloatValue(UNIT_FIELD_COMBATREACH, proto->CombatReach); original_emotestate = spawn->emote_state; // set position m_position.ChangeCoords( spawn->x, spawn->y, spawn->z, spawn->o ); m_spawnLocation.ChangeCoords(spawn->x, spawn->y, spawn->z, spawn->o); m_aiInterface->setMoveType(spawn->movetype); m_aiInterface->m_waypoints = objmgr.GetWayPointMap(spawn->id); m_faction = dbcFactionTemplate.LookupEntry(spawn->factionid); if(m_faction) { m_factionDBC = dbcFaction.LookupEntry(m_faction->Faction); // not a neutral creature if(!(m_factionDBC->RepListId == -1 && m_faction->HostileMask == 0 && m_faction->FriendlyMask == 0)) { GetAIInterface()->m_canCallForHelp = true; } } //SETUP NPC FLAGS SetUInt32Value(UNIT_NPC_FLAGS,proto->NPCFLags); if ( HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_VENDOR ) ) m_SellItems = objmgr.GetVendorList(GetEntry()); if ( HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER ) ) _LoadQuests(); if ( HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TAXIVENDOR) ) m_TaxiNode = sTaxiMgr.GetNearestTaxiNode( m_position.x, m_position.y, m_position.z, GetMapId() ); if ( HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER) || HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_TRAINER_PROF)) mTrainer = objmgr.GetTrainer(GetEntry()); if ( HasFlag( UNIT_NPC_FLAGS, UNIT_NPC_FLAG_AUCTIONEER ) ) auctionHouse = sAuctionMgr.GetAuctionHouse(GetEntry()); //NPC FLAGS m_aiInterface->m_waypoints=objmgr.GetWayPointMap(spawn->id); //load resistances for(uint32 x=0;x<7;x++) BaseResistance[x]=GetUInt32Value(UNIT_FIELD_RESISTANCES+x); for(uint32 x=0;x<5;x++) BaseStats[x]=GetUInt32Value(UNIT_FIELD_STAT0+x); BaseDamage[0]=GetFloatValue(UNIT_FIELD_MINDAMAGE); BaseDamage[1]=GetFloatValue(UNIT_FIELD_MAXDAMAGE); BaseOffhandDamage[0]=GetFloatValue(UNIT_FIELD_MINOFFHANDDAMAGE); BaseOffhandDamage[1]=GetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE); BaseRangedDamage[0]=GetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE); BaseRangedDamage[1]=GetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE); BaseAttackType=proto->AttackType; SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); // better set this one SetUInt32Value(UNIT_FIELD_BYTES_0, spawn->bytes); SetUInt32Value(UNIT_FIELD_BYTES_2, spawn->bytes2); ////////////AI // kek for(list<AI_Spell*>::iterator itr = proto->spells.begin(); itr != proto->spells.end(); ++itr) { m_aiInterface->addSpellToList(*itr); } //m_aiInterface->m_canCallForHelp = proto->m_canCallForHelp; //m_aiInterface->m_CallForHelpHealth = proto->m_callForHelpHealth; m_aiInterface->m_canFlee = proto->m_canFlee; m_aiInterface->m_FleeHealth = proto->m_fleeHealth; m_aiInterface->m_FleeDuration = proto->m_fleeDuration; //these fields are always 0 in db GetAIInterface()->setMoveType(0); GetAIInterface()->setMoveRunFlag(0); // load formation data if( spawn->form != NULL ) { m_aiInterface->m_formationLinkSqlId = spawn->form->fol; m_aiInterface->m_formationFollowDistance = spawn->form->dist; m_aiInterface->m_formationFollowAngle = spawn->form->ang; } else { m_aiInterface->m_formationLinkSqlId = 0; m_aiInterface->m_formationFollowDistance = 0; m_aiInterface->m_formationFollowAngle = 0; } //////////////AI myFamily = dbcCreatureFamily.LookupEntry(creature_info->Family); // PLACE FOR DIRTY FIX BASTARDS // HACK! set call for help on civ health @ 100% if(creature_info->Civilian >= 1) m_aiInterface->m_CallForHelpHealth = 100; //HACK! if(m_uint32Values[UNIT_FIELD_DISPLAYID] == 17743 || m_uint32Values[UNIT_FIELD_DISPLAYID] == 20242 || m_uint32Values[UNIT_FIELD_DISPLAYID] == 15435 || (creature_info->Family == UNIT_TYPE_MISC)) { m_useAI = false; } /* more hacks! */ if(proto->Mana != 0) SetPowerType(POWER_TYPE_MANA); else SetPowerType(0); has_combat_text = objmgr.HasMonsterSay(GetEntry(), MONSTER_SAY_EVENT_ENTER_COMBAT); has_waypoint_text = objmgr.HasMonsterSay(GetEntry(), MONSTER_SAY_EVENT_RANDOM_WAYPOINT); m_aiInterface->m_isGuard = isGuard(GetEntry()); m_aiInterface->getMoveFlags(); /* creature death state */ if(proto->death_state == 1) { uint32 newhealth = m_uint32Values[UNIT_FIELD_HEALTH] / 100; if(!newhealth) newhealth = 1; SetUInt32Value(UNIT_FIELD_HEALTH, 1); m_limbostate = true; bInvincible = true; SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DEAD); } m_invisFlag = proto->invisibility_type; if( spawn->stand_state ) SetStandState( (uint8)spawn->stand_state ); return true; }
void DungeonPersistentState::UpdateEncounterState(EncounterCreditType type, uint32 creditEntry) { DungeonEncounterMapBounds bounds = sObjectMgr.GetDungeonEncounterBounds(creditEntry); for (DungeonEncounterMap::const_iterator iter = bounds.first; iter != bounds.second; ++iter) { DungeonEncounterEntry const* dbcEntry = iter->second->dbcEntry; if (iter->second->creditType == type && Difficulty(dbcEntry->Difficulty) == GetDifficulty() && dbcEntry->mapId == GetMapId()) { m_completedEncountersMask |= 1 << dbcEntry->encounterIndex; CharacterDatabase.PExecute("UPDATE instance SET encountersMask = '%u' WHERE id = '%u'", m_completedEncountersMask, GetInstanceId()); DEBUG_LOG("DungeonPersistentState: Dungeon %s (Id %u) completed encounter %s", GetMap()->GetMapName(), GetInstanceId(), dbcEntry->encounterName[sWorld.GetDefaultDbcLocale()]); if (/*uint32 dungeonId =*/ iter->second->lastEncounterDungeon) { DEBUG_LOG("DungeonPersistentState:: Dungeon %s (Instance-Id %u) completed last encounter %s", GetMap()->GetMapName(), GetInstanceId(), dbcEntry->encounterName[sWorld.GetDefaultDbcLocale()]); // Place LFG reward here } return; } } }
bool BattlegroundBE::HandlePlayerUnderMap(Player* player) { player->TeleportTo(GetMapId(), 6237.79768f, 261.142f, 2.0f, 4.0f, false); return true; }
void Corpse::SaveToDB() { //save corpse to DB std::stringstream ss; ss << "DELETE FROM corpses WHERE guid = " << GetLowGUID(); CharacterDatabase.Execute( ss.str( ).c_str( ) ); ss.rdbuf()->str(""); ss << "INSERT INTO corpses (guid, positionX, positionY, positionZ, orientation, zoneId, mapId, data, instanceId) VALUES (" << GetLowGUID() << ", '" << GetPositionX() << "', '" << GetPositionY() << "', '" << GetPositionZ() << "', '" << GetOrientation() << "', '" << GetZoneId() << "', '" << GetMapId() << "', '"; for(uint16 i = 0; i < m_valuesCount; i++ ) ss << GetUInt32Value(i) << " "; ss << "', " << GetInstanceID() << " )"; CharacterDatabase.Execute( ss.str().c_str() ); }
void DungeonPersistentState::UpdateEncounterState(EncounterCreditType type, uint32 creditEntry) { DungeonEncounterMapBounds bounds = sObjectMgr.GetDungeonEncounterBounds(creditEntry); for (DungeonEncounterMap::const_iterator itr = bounds.first; itr != bounds.second; ++itr) { DungeonEncounterEntry const* dbcEntry = itr->second->dbcEntry; if (itr->second->creditType == type && dbcEntry->Difficulty == GetDifficulty() && dbcEntry->mapId == GetMapId()) { uint32 oldMask = m_completedEncountersMask; m_completedEncountersMask |= 1 << dbcEntry->encounterIndex; if ( m_completedEncountersMask != oldMask) { CharacterDatabase.PExecute("UPDATE instance SET encountersMask = '%u' WHERE id = '%u'", m_completedEncountersMask, GetInstanceId()); DEBUG_LOG("DungeonPersistentState: Dungeon %s (Id %u) completed encounter %s", GetMap()->GetMapName(), GetInstanceId(), dbcEntry->encounterName[sWorld.GetDefaultDbcLocale()]); uint32 dungeonId = itr->second->lastEncounterDungeon; if (dungeonId) DEBUG_LOG("DungeonPersistentState:: Dungeon %s (Id %u) completed last encounter %s", GetMap()->GetMapName(), GetInstanceId(), dbcEntry->encounterName[sWorld.GetDefaultDbcLocale()]); DungeonMap* dungeon = (DungeonMap*)GetMap(); if (!dungeon || dungeon->GetPlayers().isEmpty()) return; Player* player = dungeon->GetPlayers().begin()->getSource(); if (dungeon && player) dungeon->PermBindAllPlayers(player, dungeon->IsRaidOrHeroicDungeon()); SaveToDB(); if (dungeon && player->GetGroup() && player->GetGroup()->isLFGGroup()) { sLFGMgr.DungeonEncounterReached(player->GetGroup()); if ((sWorld.getConfig(CONFIG_BOOL_LFG_ONLYLASTENCOUNTER) && dungeonId) || IsCompleted()) sLFGMgr.SendLFGRewards(player->GetGroup()); } } return; } } }
bool BattlegroundDS::HandlePlayerUnderMap(Player *player) { player->TeleportTo(GetMapId(), 1299.046, 784.825, 9.338, 2.422, false); return true; }
bool BattlegroundRV::HandlePlayerUnderMap(Player* player) { player->TeleportTo(GetMapId(), 763.5f, -284, 28.276f, 2.422f, false); return true; }
bool BattlegroundRL::HandlePlayerUnderMap(Player* player) { player->TeleportTo(GetMapId(), 1285.810547f, 1667.896851f, 39.957642f, player->GetOrientation(), false); return true; }
void Vehicle::InstallAccessories() { CreatureProtoVehicle* acc = CreatureProtoVehicleStorage.LookupEntry(GetEntry()); if(acc == NULL) { sLog.outDetail("Vehicle %u has no accessories.", GetEntry()); return; } MapMgr* map = (GetMapMgr() ? GetMapMgr() : sInstanceMgr.GetMapMgr(GetMapId())); if(map == NULL) // Shouldn't ever really happen. return; for(int i = 0; i < 8; i++) { SeatInfo seatinfo = acc->seats[i]; if(!seatinfo.accessoryentry || (seatinfo.accessoryentry == GetEntry())) continue; if(m_vehicleSeats[i] == NULL) { sLog.outDetail("No seatmap for selected seat.\n"); continue; } // Load the Proto CreatureProto* proto = CreatureProtoStorage.LookupEntry(seatinfo.accessoryentry); CreatureInfo* info = CreatureNameStorage.LookupEntry(seatinfo.accessoryentry); if(!proto || !info) { sLog.outError("No proto/info for vehicle accessory %u in vehicle %u", seatinfo.accessoryentry, GetEntry()); continue; } // Remove any passengers. if(m_passengers[i]) RemovePassenger(m_passengers[i]); if(proto->vehicle_entry > 0) { // Create the Vehicle! Vehicle* pass = map->CreateVehicle(seatinfo.accessoryentry); if(pass != NULL && pass) { pass->Load(proto, (IsInInstance() ? map->iInstanceMode : MODE_5PLAYER_NORMAL), GetPositionX()+m_vehicleSeats[i]->m_attachmentOffsetX, GetPositionY()+m_vehicleSeats[i]->m_attachmentOffsetY, GetPositionZ()+m_vehicleSeats[i]->m_attachmentOffsetZ); pass->Init(); pass->m_TransporterGUID = GetGUID(); pass->InitSeats(proto->vehicle_entry); if(pass->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK)) pass->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); // Accessory AddPassenger(pass, i, true); pass->PushToWorld(map); } } else { // Create the Unit! Creature* pass = map->CreateCreature(seatinfo.accessoryentry); if(pass != NULL) { pass->Load(proto, map->iInstanceMode, GetPositionX()+m_vehicleSeats[i]->m_attachmentOffsetX, GetPositionY()+m_vehicleSeats[i]->m_attachmentOffsetY, GetPositionZ()+m_vehicleSeats[i]->m_attachmentOffsetZ); pass->Init(); pass->m_TransporterGUID = GetGUID(); AddPassenger(pass, i, true); pass->PushToWorld(map); } } } }