diff options
36 files changed, 322 insertions, 216 deletions
diff --git a/sql/updates/world/master/2018_09_15_00_world.sql b/sql/updates/world/master/2018_09_15_00_world.sql new file mode 100644 index 00000000000..7a0b0d08040 --- /dev/null +++ b/sql/updates/world/master/2018_09_15_00_world.sql @@ -0,0 +1,12 @@ +DELETE FROM `conditions` WHERE `ConditionTypeOrReference`=19 AND `SourceEntry` IN (13604,13817,50452,50453); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(10,34379,50453,0,0,49,0,6,0,0,0,0,0,'','Ring of Rotting Sinew only 25 heroic'), +(10,34379,50452,0,0,49,0,6,0,0,0,0,0,'','Wodin\'s Lucky Necklace only 25 heroic'); + +ALTER TABLE `creature` ADD `spawnDifficulties` VARCHAR(100) NOT NULL DEFAULT '0' AFTER `spawnMask`; +UPDATE `creature` SET `spawnDifficulties`=MAKE_SET(`spawnMask`,"0","1","2","3","4","5","6","7","8","9",NULL,"11","12",NULL,"14","15","16","17","18","19","20",NULL,NULL,"23","24","25","26","27",NULL,"29","30",NULL,"32","33","34"); +ALTER TABLE `creature` DROP `spawnMask`; + +ALTER TABLE `gameobject` ADD `spawnDifficulties` VARCHAR(100) NOT NULL DEFAULT '0' AFTER `spawnMask`; +UPDATE `gameobject` SET `spawnDifficulties`=MAKE_SET(`spawnMask`,"0","1","2","3","4","5","6","7","8","9",NULL,"11","12",NULL,"14","15","16","17","18","19","20",NULL,NULL,"23","24","25","26","27",NULL,"29","30",NULL,"32","33","34"); +ALTER TABLE `gameobject` DROP `spawnMask`; diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index f937c32c0a3..458a4b28c84 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -128,7 +128,7 @@ ScriptedAI::ScriptedAI(Creature* creature) : CreatureAI(creature), _isCombatMovementAllowed(true) { _isHeroic = me->GetMap()->IsHeroic(); - _difficulty = Difficulty(me->GetMap()->GetSpawnMode()); + _difficulty = me->GetMap()->GetDifficultyID(); } void ScriptedAI::AttackStartNoMove(Unit* who) diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 83e5d00ec63..79af3ea66b9 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -3871,9 +3871,29 @@ void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEn { if (obj && obj->GetMap()->IsDungeon()) { - if ((1 << (obj->GetMap()->GetSpawnMode()+1)) & (*i).event.event_flags) + // TODO: fix it for new maps and difficulties + switch (obj->GetMap()->GetDifficultyID()) { - mEvents.push_back((*i)); + case DIFFICULTY_NORMAL: + case DIFFICULTY_10_N: + if (i->event.event_flags & SMART_EVENT_FLAG_DIFFICULTY_0) + mEvents.emplace_back(std::move(*i)); + break; + case DIFFICULTY_HEROIC: + case DIFFICULTY_25_N: + if (i->event.event_flags & SMART_EVENT_FLAG_DIFFICULTY_1) + mEvents.emplace_back(std::move(*i)); + break; + case DIFFICULTY_10_HC: + if (i->event.event_flags & SMART_EVENT_FLAG_DIFFICULTY_2) + mEvents.emplace_back(std::move(*i)); + break; + case DIFFICULTY_25_HC: + if (i->event.event_flags & SMART_EVENT_FLAG_DIFFICULTY_3) + mEvents.emplace_back(std::move(*i)); + break; + default: + break; } } continue; @@ -3890,24 +3910,24 @@ void SmartScript::GetScript() e = sSmartScriptMgr->GetScript(-((int32)me->GetSpawnId()), mScriptType); if (e.empty()) e = sSmartScriptMgr->GetScript((int32)me->GetEntry(), mScriptType); - FillScript(e, me, nullptr, nullptr); + FillScript(std::move(e), me, nullptr, nullptr); } else if (go) { e = sSmartScriptMgr->GetScript(-((int32)go->GetSpawnId()), mScriptType); if (e.empty()) e = sSmartScriptMgr->GetScript((int32)go->GetEntry(), mScriptType); - FillScript(e, go, nullptr, nullptr); + FillScript(std::move(e), go, nullptr, nullptr); } else if (trigger) { e = sSmartScriptMgr->GetScript((int32)trigger->ID, mScriptType); - FillScript(e, nullptr, trigger, nullptr); + FillScript(std::move(e), nullptr, trigger, nullptr); } else if (sceneTemplate) { e = sSmartScriptMgr->GetScript(sceneTemplate->SceneId, mScriptType); - FillScript(e, nullptr, nullptr, sceneTemplate); + FillScript(std::move(e), nullptr, nullptr, sceneTemplate); } } diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 50726b91cad..bad5c195667 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -121,7 +121,8 @@ ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[COND { "Pet type", true, false, false }, { "On Taxi", false, false, false }, { "Quest state mask", true, true, false }, - { "Objective Complete", true, false, false } + { "Objective Complete", true, false, false }, + { "Map Difficulty", true, false, false } }; // Checks if object meets the condition @@ -423,11 +424,6 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const condMeets = player->HasTitle(ConditionValue1); break; } - case CONDITION_SPAWNMASK: - { - condMeets = ((UI64LIT(1) << object->GetMap()->GetSpawnMode()) & ConditionValue1) != 0; - break; - } case CONDITION_UNIT_STATE: { if (Unit* unit = object->ToUnit()) @@ -523,6 +519,11 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const } break; } + case CONDITION_DIFFICULTY_ID: + { + condMeets = object->GetMap()->GetDifficultyID() == ConditionValue1; + break; + } default: condMeets = false; break; @@ -680,9 +681,6 @@ uint32 Condition::GetSearcherTypeMaskForCondition() const case CONDITION_TITLE: mask |= GRID_MAP_TYPE_MASK_PLAYER; break; - case CONDITION_SPAWNMASK: - mask |= GRID_MAP_TYPE_MASK_ALL; - break; case CONDITION_GENDER: mask |= GRID_MAP_TYPE_MASK_PLAYER; break; @@ -722,6 +720,9 @@ uint32 Condition::GetSearcherTypeMaskForCondition() const case CONDITION_QUEST_OBJECTIVE_COMPLETE: mask |= GRID_MAP_TYPE_MASK_PLAYER; break; + case CONDITION_DIFFICULTY_ID: + mask |= GRID_MAP_TYPE_MASK_ALL; + break; default: ASSERT(false && "Condition::GetSearcherTypeMaskForCondition - missing condition handling!"); break; @@ -2261,15 +2262,10 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) const } break; } - case CONDITION_SPAWNMASK: + case CONDITION_SPAWNMASK_DEPRECATED: { - /// @todo: ConditionValue need to be extended to uint64 - if (uint64(cond->ConditionValue1) >= (UI64LIT(1) << MAX_DIFFICULTY)) - { - TC_LOG_ERROR("sql.sql", "%s has non existing SpawnMask in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); - return false; - } - break; + TC_LOG_ERROR("sql.sql", "%s using deprecated condition type CONDITION_SPAWNMASK.", cond->ToString(true).c_str()); + return false; } case CONDITION_UNIT_STATE: { @@ -2346,6 +2342,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) const case CONDITION_CHARMED: case CONDITION_TAXI: break; + case CONDITION_DIFFICULTY_ID: + if (!sDifficultyStore.LookupEntry(cond->ConditionValue1)) + { + TC_LOG_ERROR("sql.sql", "%s has non existing difficulty in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1); + return false; + } + break; default: TC_LOG_ERROR("sql.sql", "%s Invalid ConditionType in `condition` table, ignoring.", cond->ToString().c_str()); return false; diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index a94a14c6f71..f0c711adbbc 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -71,7 +71,7 @@ enum ConditionTypes CONDITION_RACE = 16, // race 0 0 true if player's race is equal to race CONDITION_ACHIEVEMENT = 17, // achievement_id 0 0 true if achievement is complete CONDITION_TITLE = 18, // title id 0 0 true if player has title - CONDITION_SPAWNMASK = 19, // spawnMask 0 0 true if in spawnMask + CONDITION_SPAWNMASK_DEPRECATED = 19, // DEPRECATED CONDITION_GENDER = 20, // gender 0 0 true if player's gender is equal to gender CONDITION_UNIT_STATE = 21, // unitState 0 0 true if unit has unitState CONDITION_MAPID = 22, // map_id 0 0 true if in map_id @@ -101,7 +101,8 @@ enum ConditionTypes CONDITION_TAXI = 46, // 0 0 0 true if player is on taxi CONDITION_QUESTSTATE = 47, // quest_id state_mask 0 true if player is in any of the provided quest states for the quest (1 = not taken, 2 = completed, 8 = in progress, 32 = failed, 64 = rewarded) CONDITION_QUEST_OBJECTIVE_COMPLETE = 48, // ID 0 0 true if player has ID objective complete, but quest not yet rewarded - CONDITION_MAX = 49 // MAX + CONDITION_DIFFICULTY_ID = 49, // Difficulty 0 0 true is map has difficulty id + CONDITION_MAX }; /*! Documentation on implementing a new ConditionSourceType: diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 105a780beca..8f2c6980762 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -307,7 +307,7 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/) // get difficulty 1 mode entry CreatureTemplate const* cinfo = nullptr; - DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(GetMap()->GetSpawnMode()); + DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(GetMap()->GetDifficultyID()); while (!cinfo && difficultyEntry) { int32 idx = CreatureTemplate::DifficultyIDToDifficultyEntryIndex(difficultyEntry->ID); @@ -1103,10 +1103,10 @@ void Creature::SaveToDB() } uint32 mapId = GetTransport() ? GetTransport()->GetGOInfo()->moTransport.SpawnMap : GetMapId(); - SaveToDB(mapId, data->spawnMask); + SaveToDB(mapId, data->spawnDifficulties); } -void Creature::SaveToDB(uint32 mapid, uint64 spawnMask) +void Creature::SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDifficulties) { // update in loaded data if (!m_spawnId) @@ -1174,7 +1174,7 @@ void Creature::SaveToDB(uint32 mapid, uint64 spawnMask) // prevent add data integrity problems data.movementType = !m_respawnradius && GetDefaultMovementType() == RANDOM_MOTION_TYPE ? IDLE_MOTION_TYPE : GetDefaultMovementType(); - data.spawnMask = spawnMask; + data.spawnDifficulties = spawnDifficulties; data.npcflag = npcflag; data.unit_flags = unitFlags; data.unit_flags2 = unitFlags2; @@ -1197,7 +1197,7 @@ void Creature::SaveToDB(uint32 mapid, uint64 spawnMask) stmt->setUInt64(index++, m_spawnId); stmt->setUInt32(index++, GetEntry()); stmt->setUInt16(index++, uint16(mapid)); - stmt->setUInt64(index++, spawnMask); + stmt->setString(index++, StringJoin(data.spawnDifficulties, ",")); stmt->setUInt32(index++, data.phaseId); stmt->setUInt32(index++, data.phaseGroup); stmt->setUInt32(index++, displayId); diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 0470a4cc41f..d87db9be2ca 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -187,7 +187,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma public: void SaveToDB(); // overriden in Pet - virtual void SaveToDB(uint32 mapid, uint64 spawnMask); + virtual void SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDifficulties); virtual void DeleteFromDB(); // overriden in Pet Loot loot; diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h index e1d0fea528e..45a13c6f603 100644 --- a/src/server/game/Entities/Creature/CreatureData.h +++ b/src/server/game/Entities/Creature/CreatureData.h @@ -500,7 +500,7 @@ struct CreatureData CreatureData() : id(0), mapid(0), displayid(0), equipmentId(0), posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), spawntimesecs(0), spawndist(0.0f), currentwaypoint(0), curhealth(0), curmana(0), movementType(0), - spawnMask(0), npcflag(0), unit_flags(0), unit_flags2(0), unit_flags3(0), dynamicflags(0), + spawnDifficulties(), npcflag(0), unit_flags(0), unit_flags2(0), unit_flags3(0), dynamicflags(0), phaseUseFlags(0), phaseId(0), phaseGroup(0), terrainSwapMap(-1), ScriptId(0), dbData(true) { } uint32 id; // entry in creature_template uint16 mapid; @@ -516,7 +516,7 @@ struct CreatureData uint32 curhealth; uint32 curmana; uint8 movementType; - uint64 spawnMask; + std::vector<Difficulty> spawnDifficulties; uint64 npcflag; uint32 unit_flags; // enum UnitFlags mask values uint32 unit_flags2; // enum UnitFlags2 mask values diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index 785b848529b..f4a05581ea5 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -53,7 +53,7 @@ class TC_GAME_API TempSummon : public Creature virtual void UnSummon(uint32 msTime = 0); void RemoveFromWorld() override; void SetTempSummonType(TempSummonType type); - void SaveToDB(uint32 /*mapid*/, uint64 /*spawnMask*/) override { } + void SaveToDB(uint32 /*mapid*/, std::vector<Difficulty> const& /*spawnDifficulties*/) override { } Unit* GetSummoner() const; Creature* GetSummonerCreatureBase() const; ObjectGuid GetSummonerGUID() const { return m_summonerGUID; } diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index d0a458a7946..89b59a11ab2 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -911,10 +911,10 @@ void GameObject::SaveToDB() return; } - SaveToDB(GetMapId(), data->spawnMask); + SaveToDB(GetMapId(), data->spawnDifficulties); } -void GameObject::SaveToDB(uint32 mapid, uint64 spawnMask) +void GameObject::SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDifficulties) { const GameObjectTemplate* goI = GetGOInfo(); @@ -938,7 +938,7 @@ void GameObject::SaveToDB(uint32 mapid, uint64 spawnMask) data.spawntimesecs = m_spawnedByDefault ? m_respawnDelayTime : -(int32)m_respawnDelayTime; data.animprogress = GetGoAnimProgress(); data.go_state = GetGoState(); - data.spawnMask = spawnMask; + data.spawnDifficulties = spawnDifficulties; data.artKit = GetGoArtKit(); data.phaseId = GetDBPhase() > 0 ? GetDBPhase() : data.phaseId; @@ -957,7 +957,7 @@ void GameObject::SaveToDB(uint32 mapid, uint64 spawnMask) stmt->setUInt64(index++, m_spawnId); stmt->setUInt32(index++, GetEntry()); stmt->setUInt16(index++, uint16(mapid)); - stmt->setUInt64(index++, spawnMask); + stmt->setString(index++, StringJoin(data.spawnDifficulties, ",")); stmt->setUInt32(index++, data.phaseId); stmt->setUInt32(index++, data.phaseGroup); stmt->setFloat(index++, GetPositionX()); diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 12ff942a6ba..24b70b9ce73 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -119,7 +119,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> std::string const& GetNameForLocaleIdx(LocaleConstant locale_idx) const override; void SaveToDB(); - void SaveToDB(uint32 mapid, uint64 spawnMask); + void SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDifficulties); bool LoadFromDB(ObjectGuid::LowType spawnId, Map* map) { return LoadGameObjectFromDB(spawnId, map, false); } private: bool LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap); diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h index 7491a3d8ac9..c6411c24f0a 100644 --- a/src/server/game/Entities/GameObject/GameObjectData.h +++ b/src/server/game/Entities/GameObject/GameObjectData.h @@ -855,7 +855,7 @@ struct GameObjectAddon struct GameObjectData { explicit GameObjectData() : id(0), mapid(0), posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), spawntimesecs(0), - animprogress(0), go_state(GO_STATE_ACTIVE), spawnMask(0), artKit(0), + animprogress(0), go_state(GO_STATE_ACTIVE), spawnDifficulties(), artKit(0), phaseUseFlags(0), phaseId(0), phaseGroup(0), terrainSwapMap(-1), ScriptId(0), dbData(true) { } uint32 id; // entry in gamobject_template uint16 mapid; @@ -867,7 +867,7 @@ struct GameObjectData int32 spawntimesecs; uint32 animprogress; GOState go_state; - uint64 spawnMask; + std::vector<Difficulty> spawnDifficulties; uint8 artKit; uint8 phaseUseFlags; uint32 phaseId; diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index e6652501b86..e411d2251af 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -160,7 +160,7 @@ class TC_GAME_API Pet : public Guardian uint16 m_petSpecialization; private: - void SaveToDB(uint32, uint64) override // override of Creature::SaveToDB - must not be called + void SaveToDB(uint32, std::vector<Difficulty> const&) override // override of Creature::SaveToDB - must not be called { ABORT(); } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 2aae0333ebf..f956d970992 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -397,8 +397,8 @@ void Player::CleanupsBeforeDelete(bool finalCleanup) Unit::CleanupsBeforeDelete(finalCleanup); // clean up player-instance binds, may unload some instance saves - for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) - for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr) + for (auto difficultyItr = m_boundInstances.begin(); difficultyItr != m_boundInstances.end(); ++difficultyItr) + for (auto itr = difficultyItr->second.begin(); itr != difficultyItr->second.end(); ++itr) itr->second.save->RemovePlayer(this); } @@ -19428,8 +19428,7 @@ void Player::_LoadGroup(PreparedQueryResult result) void Player::_LoadBoundInstances(PreparedQueryResult result) { - for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) - m_boundInstances[i].clear(); + m_boundInstances.clear(); Group* group = GetGroup(); @@ -19514,8 +19513,12 @@ InstancePlayerBind* Player::GetBoundInstance(uint32 mapid, Difficulty difficulty if (!mapDiff) return nullptr; - BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid); - if (itr != m_boundInstances[difficulty].end()) + auto difficultyItr = m_boundInstances.find(difficulty); + if (difficultyItr == m_boundInstances.end()) + return nullptr; + + auto itr = difficultyItr->second.find(mapid); + if (itr != difficultyItr->second.end()) if (itr->second.extendState || withExpired) return &itr->second; return nullptr; @@ -19528,8 +19531,12 @@ InstancePlayerBind const* Player::GetBoundInstance(uint32 mapid, Difficulty diff if (!mapDiff) return nullptr; - auto itr = m_boundInstances[difficulty].find(mapid); - if (itr != m_boundInstances[difficulty].end()) + auto difficultyItr = m_boundInstances.find(difficulty); + if (difficultyItr == m_boundInstances.end()) + return nullptr; + + auto itr = difficultyItr->second.find(mapid); + if (itr != difficultyItr->second.end()) return &itr->second; return nullptr; @@ -19550,13 +19557,18 @@ InstanceSave* Player::GetInstanceSave(uint32 mapid) void Player::UnbindInstance(uint32 mapid, Difficulty difficulty, bool unload) { - BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid); - UnbindInstance(itr, difficulty, unload); + auto difficultyItr = m_boundInstances.find(difficulty); + if (difficultyItr != m_boundInstances.end()) + { + auto itr = difficultyItr->second.find(mapid); + if (itr != difficultyItr->second.end()) + UnbindInstance(itr, difficultyItr, unload); + } } -void Player::UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficulty, bool unload) +void Player::UnbindInstance(BoundInstancesMap::mapped_type::iterator& itr, BoundInstancesMap::iterator& difficultyItr, bool unload) { - if (itr != m_boundInstances[difficulty].end()) + if (itr != difficultyItr->second.end()) { if (!unload) { @@ -19572,7 +19584,7 @@ void Player::UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficu GetSession()->SendCalendarRaidLockout(itr->second.save, false); itr->second.save->RemovePlayer(this); // save can become invalid - m_boundInstances[difficulty].erase(itr++); + difficultyItr->second.erase(itr++); } } @@ -19669,9 +19681,9 @@ void Player::SendRaidInfo() time_t now = time(nullptr); - for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) + for (auto difficultyItr = m_boundInstances.begin(); difficultyItr != m_boundInstances.end(); ++difficultyItr) { - for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr) + for (auto itr = difficultyItr->second.begin(); itr != difficultyItr->second.end(); ++itr) { InstancePlayerBind const& bind = itr->second; if (bind.perm) @@ -21193,7 +21205,11 @@ void Player::ResetInstances(uint8 method, bool isRaid, bool isLegacy) diff = GetLegacyRaidDifficultyID(); } - for (BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();) + auto difficultyItr = m_boundInstances.find(diff); + if (difficultyItr == m_boundInstances.end()) + return; + + for (auto itr = difficultyItr->second.begin(); itr != difficultyItr->second.end();) { InstanceSave* p = itr->second.save; const MapEntry* entry = sMapStore.LookupEntry(itr->first); @@ -21227,7 +21243,7 @@ void Player::ResetInstances(uint8 method, bool isRaid, bool isLegacy) SendResetInstanceSuccess(p->GetMapId()); p->DeleteFromDB(); - m_boundInstances[diff].erase(itr++); + difficultyItr->second.erase(itr++); // the following should remove the instance save from the manager and delete it as well p->RemovePlayer(this); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 7cbea6951f0..fd2b6e9a049 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2234,20 +2234,20 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> /*** INSTANCE SYSTEM ***/ /*********************************************************/ - typedef std::unordered_map< uint32 /*mapId*/, InstancePlayerBind > BoundInstancesMap; + typedef std::unordered_map<Difficulty, std::unordered_map<uint32 /*mapId*/, InstancePlayerBind>> BoundInstancesMap; void UpdateHomebindTime(uint32 time); uint32 m_HomebindTimer; bool m_InstanceValid; // permanent binds and solo binds by difficulty - BoundInstancesMap m_boundInstances[MAX_DIFFICULTY]; + BoundInstancesMap m_boundInstances; InstancePlayerBind* GetBoundInstance(uint32 mapid, Difficulty difficulty, bool withExpired = false); InstancePlayerBind const* GetBoundInstance(uint32 mapid, Difficulty difficulty) const; - BoundInstancesMap& GetBoundInstances(Difficulty difficulty) { return m_boundInstances[difficulty]; } + BoundInstancesMap::iterator GetBoundInstances(Difficulty difficulty) { return m_boundInstances.find(difficulty); } InstanceSave* GetInstanceSave(uint32 mapid); void UnbindInstance(uint32 mapid, Difficulty difficulty, bool unload = false); - void UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficulty, bool unload = false); + void UnbindInstance(BoundInstancesMap::mapped_type::iterator& itr, BoundInstancesMap::iterator& difficultyItr, bool unload = false); InstancePlayerBind* BindToInstance(InstanceSave* save, bool permanent, BindExtensionState extendState = EXTEND_STATE_NORMAL, bool load = false); void BindToInstance(); void SetPendingBind(uint32 instanceId, uint32 bindTimer); diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index bd86313e004..50b1897e2c5 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -529,7 +529,7 @@ void Transport::LoadStaticPassengers() { if (uint32 mapId = GetGOInfo()->moTransport.SpawnMap) { - CellObjectGuidsMap const& cells = sObjectMgr->GetMapObjectGuids(mapId, GetMap()->GetSpawnMode()); + CellObjectGuidsMap const& cells = sObjectMgr->GetMapObjectGuids(mapId, GetMap()->GetDifficultyID()); CellGuidSet::const_iterator guidEnd; for (CellObjectGuidsMap::const_iterator cellItr = cells.begin(); cellItr != cells.end(); ++cellItr) { diff --git a/src/server/game/Garrison/Garrison.cpp b/src/server/game/Garrison/Garrison.cpp index 6a966ccb5d9..7e3f3f988bd 100644 --- a/src/server/game/Garrison/Garrison.cpp +++ b/src/server/game/Garrison/Garrison.cpp @@ -757,7 +757,7 @@ GameObject* Garrison::Plot::CreateGameObject(Map* map, GarrisonFactionIndex fact if (building->GetGoType() == GAMEOBJECT_TYPE_GARRISON_BUILDING && building->GetGOInfo()->garrisonBuilding.SpawnMap) { - for (CellObjectGuidsMap::value_type const& cellGuids : sObjectMgr->GetMapObjectGuids(building->GetGOInfo()->garrisonBuilding.SpawnMap, map->GetSpawnMode())) + for (CellObjectGuidsMap::value_type const& cellGuids : sObjectMgr->GetMapObjectGuids(building->GetGOInfo()->garrisonBuilding.SpawnMap, map->GetDifficultyID())) { for (ObjectGuid::LowType spawnId : cellGuids.second.creatures) if (Creature* spawn = BuildingSpawnHelper<Creature, &Creature::SetHomePosition>(building, spawnId, map)) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 1811ac2a4f9..746782fa1ec 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1594,7 +1594,8 @@ void ObjectMgr::LoadLinkedRespawn() break; } - if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty) + // they must have a possibility to meet (normal/heroic difficulty) + if (!Trinity::Containers::Intersects(master->spawnDifficulties.begin(), master->spawnDifficulties.end(), slave->spawnDifficulties.begin(), slave->spawnDifficulties.end())) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Creature '" UI64FMTD "' linking to Creature '" UI64FMTD "' with not corresponding spawnMask", guidLow, linkedGuidLow); error = true; @@ -1631,7 +1632,8 @@ void ObjectMgr::LoadLinkedRespawn() break; } - if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty) + // they must have a possibility to meet (normal/heroic difficulty) + if (!Trinity::Containers::Intersects(master->spawnDifficulties.begin(), master->spawnDifficulties.end(), slave->spawnDifficulties.begin(), slave->spawnDifficulties.end())) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Creature '" UI64FMTD "' linking to Gameobject '" UI64FMTD "' with not corresponding spawnMask", guidLow, linkedGuidLow); error = true; @@ -1668,7 +1670,8 @@ void ObjectMgr::LoadLinkedRespawn() break; } - if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty) + // they must have a possibility to meet (normal/heroic difficulty) + if (!Trinity::Containers::Intersects(master->spawnDifficulties.begin(), master->spawnDifficulties.end(), slave->spawnDifficulties.begin(), slave->spawnDifficulties.end())) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '" UI64FMTD "' linking to Gameobject '" UI64FMTD "' with not corresponding spawnMask", guidLow, linkedGuidLow); error = true; @@ -1705,7 +1708,8 @@ void ObjectMgr::LoadLinkedRespawn() break; } - if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty) + // they must have a possibility to meet (normal/heroic difficulty) + if (!Trinity::Containers::Intersects(master->spawnDifficulties.begin(), master->spawnDifficulties.end(), slave->spawnDifficulties.begin(), slave->spawnDifficulties.end())) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '" UI64FMTD "' linking to Creature '" UI64FMTD "' with not corresponding spawnMask", guidLow, linkedGuidLow); error = true; @@ -1758,7 +1762,8 @@ bool ObjectMgr::SetCreatureLinkedRespawn(ObjectGuid::LowType guidLow, ObjectGuid return false; } - if (!(master->spawnMask & slave->spawnMask)) // they must have a possibility to meet (normal/heroic difficulty) + // they must have a possibility to meet (normal/heroic difficulty) + if (!Trinity::Containers::Intersects(master->spawnDifficulties.begin(), master->spawnDifficulties.end(), slave->spawnDifficulties.begin(), slave->spawnDifficulties.end())) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Creature '" UI64FMTD "' linking to '" UI64FMTD "' with not corresponding spawnMask", guidLow, linkedGuidLow); return false; @@ -1862,14 +1867,44 @@ void ObjectMgr::LoadTempSummons() TC_LOG_INFO("server.loading", ">> Loaded %u temp summons in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } +inline std::vector<Difficulty> ParseSpawnDifficulties(std::string const& difficultyString, std::string const& table, ObjectGuid::LowType spawnId, uint32 mapId, + std::set<Difficulty> const& mapDifficulties) +{ + Tokenizer tokens(difficultyString, ',', 0, false); + std::vector<Difficulty> difficulties; + bool isTransportMap = sObjectMgr->IsTransportMap(mapId); + for (char const* token : tokens) + { + Difficulty difficultyId = Difficulty(strtoul(token, nullptr, 10)); + if (difficultyId && !sDifficultyStore.LookupEntry(difficultyId)) + { + TC_LOG_ERROR("sql.sql", "Table `%s` has %s (GUID: " UI64FMTD ") with non invalid difficulty id %u, skipped.", + table.c_str(), table.c_str(), spawnId, difficultyId); + continue; + } + + if (!isTransportMap && mapDifficulties.find(difficultyId) == mapDifficulties.end()) + { + TC_LOG_ERROR("sql.sql", "Table `%s` has %s (GUID: " UI64FMTD ") has unsupported difficulty %u for map (Id: %u).", + table.c_str(), table.c_str(), spawnId, difficultyId, mapId); + continue; + } + + difficulties.push_back(difficultyId); + } + + std::sort(difficulties.begin(), difficulties.end()); + return difficulties; +} + void ObjectMgr::LoadCreatures() { uint32 oldMSTime = getMSTime(); // 0 1 2 3 4 5 6 7 8 9 10 QueryResult result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, " - // 11 12 13 14 15 16 17 18 19 20 21 - "currentwaypoint, curhealth, curmana, MovementType, spawnMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.unit_flags2, creature.unit_flags3, " + // 11 12 13 14 15 16 17 18 19 20 21 + "currentwaypoint, curhealth, curmana, MovementType, spawnDifficulties, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.unit_flags2, creature.unit_flags3, " // 22 23 24 25 26 27 "creature.dynamicflags, creature.phaseUseFlags, creature.phaseid, creature.phasegroup, creature.terrainSwapMap, creature.ScriptName " "FROM creature " @@ -1883,10 +1918,10 @@ void ObjectMgr::LoadCreatures() } // Build single time for check spawnmask - std::map<uint32, uint64> spawnMasks; + std::unordered_map<uint32, std::set<Difficulty>> spawnMasks; for (auto& mapDifficultyPair : sDB2Manager.GetMapDifficulties()) for (auto& difficultyPair : mapDifficultyPair.second) - spawnMasks[mapDifficultyPair.first] |= UI64LIT(1) << difficultyPair.first; + spawnMasks[mapDifficultyPair.first].insert(Difficulty(difficultyPair.first)); PhaseShift phaseShift; @@ -1921,7 +1956,7 @@ void ObjectMgr::LoadCreatures() data.curhealth = fields[12].GetUInt32(); data.curmana = fields[13].GetUInt32(); data.movementType = fields[14].GetUInt8(); - data.spawnMask = fields[15].GetUInt64(); + data.spawnDifficulties = ParseSpawnDifficulties(fields[15].GetString(), "creature", guid, data.mapid, spawnMasks[data.mapid]); int16 gameEvent = fields[16].GetInt8(); uint32 PoolId = fields[17].GetUInt32(); data.npcflag = fields[18].GetUInt64(); @@ -1945,6 +1980,7 @@ void ObjectMgr::LoadCreatures() } if (sWorld->getBoolConfig(CONFIG_CREATURE_CHECK_INVALID_POSITION)) + { if (VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager()) { if (vmgr->isMapLoadingEnabled() && !IsTransportMap(data.mapid)) @@ -1959,10 +1995,13 @@ void ObjectMgr::LoadCreatures() guid, data.id, data.mapid, data.posX, data.posY, data.posZ); } } + } - // Skip spawnMask check for transport maps - if (!IsTransportMap(data.mapid) && data.spawnMask & ~spawnMasks[data.mapid]) - TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD ") that have wrong spawn mask " UI64FMTD " including unsupported difficulty modes for map (Id: %u).", guid, data.spawnMask, data.mapid); + if (data.spawnDifficulties.empty()) + { + TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD ") that is not spawned in any difficulty, skipped.", guid); + continue; + } bool ok = true; for (uint32 diff = 0; diff < MAX_CREATURE_DIFFICULTIES && ok; ++diff) @@ -2100,29 +2139,21 @@ void ObjectMgr::LoadCreatures() void ObjectMgr::AddCreatureToGrid(ObjectGuid::LowType guid, CreatureData const* data) { - uint64 mask = data->spawnMask; - for (uint8 i = 0; mask != 0; i++, mask >>= 1) + for (Difficulty difficulty : data->spawnDifficulties) { - if (mask & 1) - { - CellCoord cellCoord = Trinity::ComputeCellCoord(data->posX, data->posY); - CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()]; - cell_guids.creatures.insert(guid); - } + CellCoord cellCoord = Trinity::ComputeCellCoord(data->posX, data->posY); + CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, difficulty)][cellCoord.GetId()]; + cell_guids.creatures.insert(guid); } } void ObjectMgr::RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData const* data) { - uint64 mask = data->spawnMask; - for (uint8 i = 0; mask != 0; i++, mask >>= 1) + for (Difficulty difficulty : data->spawnDifficulties) { - if (mask & 1) - { - CellCoord cellCoord = Trinity::ComputeCellCoord(data->posX, data->posY); - CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()]; - cell_guids.creatures.erase(guid); - } + CellCoord cellCoord = Trinity::ComputeCellCoord(data->posX, data->posY); + CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, difficulty)][cellCoord.GetId()]; + cell_guids.creatures.erase(guid); } } @@ -2150,7 +2181,7 @@ ObjectGuid::LowType ObjectMgr::AddGOData(uint32 entry, uint32 mapId, float x, fl data.rotation.w = rotation3; data.spawntimesecs = spawntimedelay; data.animprogress = 100; - data.spawnMask = SPAWNMASK_CONTINENT; + data.spawnDifficulties.push_back(DIFFICULTY_NONE); data.go_state = GO_STATE_READY; data.artKit = goinfo->type == GAMEOBJECT_TYPE_CONTROL_ZONE ? 21 : 0; data.dbData = false; @@ -2202,7 +2233,7 @@ ObjectGuid::LowType ObjectMgr::AddCreatureData(uint32 entry, uint32 mapId, float data.curhealth = stats->GenerateHealth(cInfo); data.curmana = stats->GenerateMana(cInfo); data.movementType = cInfo->MovementType; - data.spawnMask = SPAWNMASK_CONTINENT; + data.spawnDifficulties.push_back(DIFFICULTY_NONE); data.dbData = false; data.npcflag = cInfo->npcflag; data.unit_flags = cInfo->unit_flags; @@ -2230,8 +2261,8 @@ void ObjectMgr::LoadGameobjects() // 0 1 2 3 4 5 6 QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, " - // 7 8 9 10 11 12 13 14 15 16 - "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, eventEntry, pool_entry, " + // 7 8 9 10 11 12 13 14 15 16 + "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnDifficulties, eventEntry, pool_entry, " // 17 18 19 20 21 "phaseUseFlags, phaseid, phasegroup, terrainSwapMap, ScriptName " "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid " @@ -2244,10 +2275,10 @@ void ObjectMgr::LoadGameobjects() } // build single time for check spawnmask - std::map<uint32, uint64> spawnMasks; + std::unordered_map<uint32, std::set<Difficulty>> spawnMasks; for (auto& mapDifficultyPair : sDB2Manager.GetMapDifficulties()) for (auto& difficultyPair : mapDifficultyPair.second) - spawnMasks[mapDifficultyPair.first] |= UI64LIT(1) << difficultyPair.first; + spawnMasks[mapDifficultyPair.first].insert(Difficulty(difficultyPair.first)); PhaseShift phaseShift; @@ -2308,6 +2339,7 @@ void ObjectMgr::LoadGameobjects() } if (sWorld->getBoolConfig(CONFIG_GAME_OBJECT_CHECK_INVALID_POSITION)) + { if (VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager()) { if (vmgr->isMapLoadingEnabled() && !IsTransportMap(data.mapid)) @@ -2322,6 +2354,7 @@ void ObjectMgr::LoadGameobjects() guid, data.id, data.mapid, data.posX, data.posY, data.posZ); } } + } if (data.spawntimesecs == 0 && gInfo->IsDespawnAtAction()) { @@ -2342,10 +2375,12 @@ void ObjectMgr::LoadGameobjects() } data.go_state = GOState(go_state); - data.spawnMask = fields[14].GetUInt64(); - - if (!IsTransportMap(data.mapid) && data.spawnMask & ~spawnMasks[data.mapid]) - TC_LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: " UI64FMTD " Entry: %u) that has wrong spawn mask " UI64FMTD " including unsupported difficulty modes for map (Id: %u), skip", guid, data.id, data.spawnMask, data.mapid); + data.spawnDifficulties = ParseSpawnDifficulties(fields[14].GetString(), "gameobject", guid, data.mapid, spawnMasks[data.mapid]); + if (data.spawnDifficulties.empty()) + { + TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD ") that is not spawned in any difficulty, skipped.", guid); + continue; + } int16 gameEvent = fields[15].GetInt8(); uint32 PoolId = fields[16].GetUInt32(); @@ -2472,29 +2507,21 @@ void ObjectMgr::LoadGameobjects() void ObjectMgr::AddGameobjectToGrid(ObjectGuid::LowType guid, GameObjectData const* data) { - uint64 mask = data->spawnMask; - for (uint8 i = 0; mask != 0; i++, mask >>= 1) + for (Difficulty difficulty : data->spawnDifficulties) { - if (mask & 1) - { - CellCoord cellCoord = Trinity::ComputeCellCoord(data->posX, data->posY); - CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()]; - cell_guids.gameobjects.insert(guid); - } + CellCoord cellCoord = Trinity::ComputeCellCoord(data->posX, data->posY); + CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, difficulty)][cellCoord.GetId()]; + cell_guids.gameobjects.insert(guid); } } void ObjectMgr::RemoveGameobjectFromGrid(ObjectGuid::LowType guid, GameObjectData const* data) { - uint64 mask = data->spawnMask; - for (uint8 i = 0; mask != 0; i++, mask >>= 1) + for (Difficulty difficulty : data->spawnDifficulties) { - if (mask & 1) - { - CellCoord cellCoord = Trinity::ComputeCellCoord(data->posX, data->posY); - CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, i)][cellCoord.GetId()]; - cell_guids.gameobjects.erase(guid); - } + CellCoord cellCoord = Trinity::ComputeCellCoord(data->posX, data->posY); + CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapid, difficulty)][cellCoord.GetId()]; + cell_guids.gameobjects.erase(guid); } } diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp index 63517e5b342..4c0a9a07dea 100644 --- a/src/server/game/Grids/ObjectGridLoader.cpp +++ b/src/server/game/Grids/ObjectGridLoader.cpp @@ -136,14 +136,14 @@ void LoadHelper(CellGuidSet const& guid_set, CellCoord &cell, GridRefManager<T> void ObjectGridLoader::Visit(GameObjectMapType &m) { CellCoord cellCoord = i_cell.GetCellCoord(); - CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cellCoord.GetId()); + CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetDifficultyID(), cellCoord.GetId()); LoadHelper(cell_guids.gameobjects, cellCoord, m, i_gameObjects, i_map); } void ObjectGridLoader::Visit(CreatureMapType &m) { CellCoord cellCoord = i_cell.GetCellCoord(); - CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetSpawnMode(), cellCoord.GetId()); + CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), i_map->GetDifficultyID(), cellCoord.GetId()); LoadHelper(cell_guids.creatures, cellCoord, m, i_creatures, i_map); } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index a3e008e3d93..184bd97e17d 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -97,8 +97,8 @@ Group::~Group() } // this may unload some instance saves - for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) - for (BoundInstancesMap::iterator itr2 = m_boundInstances[i].begin(); itr2 != m_boundInstances[i].end(); ++itr2) + for (auto difficultyItr = m_boundInstances.begin(); difficultyItr != m_boundInstances.end(); ++difficultyItr) + for (auto itr2 = difficultyItr->second.begin(); itr2 != difficultyItr->second.end(); ++itr2) itr2->second.save->RemoveGroup(this); // Sub group counters clean up @@ -708,9 +708,9 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid, int8 partyIndex) SQLTransaction trans = CharacterDatabase.BeginTransaction(); // Remove the groups permanent instance bindings - for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) + for (auto difficultyItr = m_boundInstances.begin(); difficultyItr != m_boundInstances.end(); ++difficultyItr) { - for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end();) + for (auto itr = difficultyItr->second.begin(); itr != difficultyItr->second.end();) { // Do not unbind saves of instances that already had map created (a newLeader entered) // forcing a new instance with another leader requires group disbanding (confirmed on retail) @@ -722,7 +722,7 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid, int8 partyIndex) trans->Append(stmt); itr->second.save->RemoveGroup(this); - m_boundInstances[i].erase(itr++); + difficultyItr->second.erase(itr++); } else ++itr; @@ -762,9 +762,9 @@ void Group::ConvertLeaderInstancesToGroup(Player* player, Group* group, bool swi { // copy all binds to the group, when changing leader it's assumed the character // will not have any solo binds - for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) + for (auto difficultyItr = player->m_boundInstances.begin(); difficultyItr != player->m_boundInstances.end(); ++difficultyItr) { - for (Player::BoundInstancesMap::iterator itr = player->m_boundInstances[i].begin(); itr != player->m_boundInstances[i].end();) + for (auto itr = difficultyItr->second.begin(); itr != difficultyItr->second.end();) { if (!switchLeader || !group->GetBoundInstance(itr->second.save->GetDifficultyID(), itr->first)) if (itr->second.extendState) // not expired @@ -774,7 +774,7 @@ void Group::ConvertLeaderInstancesToGroup(Player* player, Group* group, bool swi if (switchLeader && !itr->second.perm) { // increments itr in call - player->UnbindInstance(itr, Difficulty(i), false); + player->UnbindInstance(itr, difficultyItr, false); } else ++itr; @@ -2014,7 +2014,11 @@ void Group::ResetInstances(uint8 method, bool isRaid, bool isLegacy, Player* Sen diff = GetLegacyRaidDifficultyID(); } - for (BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();) + auto difficultyItr = m_boundInstances.find(diff); + if (difficultyItr == m_boundInstances.end()) + return; + + for (auto itr = difficultyItr->second.begin(); itr != difficultyItr->second.end();) { InstanceSave* instanceSave = itr->second.save; const MapEntry* entry = sMapStore.LookupEntry(itr->first); @@ -2080,9 +2084,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, bool isLegacy, Player* Sen } - // i don't know for sure if hash_map iterators - m_boundInstances[diff].erase(itr); - itr = m_boundInstances[diff].begin(); + itr = difficultyItr->second.erase(itr); // this unloads the instance save unless online players are bound to it // (eg. permanent binds or GM solo binds) instanceSave->RemoveGroup(this); @@ -2118,11 +2120,15 @@ InstanceGroupBind* Group::GetBoundInstance(Difficulty difficulty, uint32 mapId) // some instances only have one difficulty sDB2Manager.GetDownscaledMapDifficultyData(mapId, difficulty); - BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapId); - if (itr != m_boundInstances[difficulty].end()) + auto difficultyItr = m_boundInstances.find(difficulty); + if (difficultyItr == m_boundInstances.end()) + return nullptr; + + auto itr = difficultyItr->second.find(mapId); + if (itr != difficultyItr->second.end()) return &itr->second; else - return NULL; + return nullptr; } InstanceGroupBind* Group::BindToInstance(InstanceSave* save, bool permanent, bool load) @@ -2160,8 +2166,12 @@ InstanceGroupBind* Group::BindToInstance(InstanceSave* save, bool permanent, boo void Group::UnbindInstance(uint32 mapid, uint8 difficulty, bool unload) { - BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid); - if (itr != m_boundInstances[difficulty].end()) + auto difficultyItr = m_boundInstances.find(Difficulty(difficulty)); + if (difficultyItr == m_boundInstances.end()) + return; + + auto itr = difficultyItr->second.find(mapid); + if (itr != difficultyItr->second.end()) { if (!unload) { @@ -2174,7 +2184,7 @@ void Group::UnbindInstance(uint32 mapid, uint8 difficulty, bool unload) } itr->second.save->RemoveGroup(this); // save can become invalid - m_boundInstances[difficulty].erase(itr); + difficultyItr->second.erase(itr); } } @@ -2601,9 +2611,14 @@ void Group::DelinkMember(ObjectGuid guid) } } -Group::BoundInstancesMap& Group::GetBoundInstances(Difficulty difficulty) +Group::BoundInstancesMap::iterator Group::GetBoundInstances(Difficulty difficulty) +{ + return m_boundInstances.find(difficulty); +} + +Group::BoundInstancesMap::iterator Group::GetBoundInstanceEnd() { - return m_boundInstances[difficulty]; + return m_boundInstances.end(); } void Group::_initRaidSubGroupsCounter() diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index d7141458152..af586563803 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -234,7 +234,7 @@ class TC_GAME_API Group typedef std::list<MemberSlot> MemberSlotList; typedef MemberSlotList::const_iterator member_citerator; - typedef std::unordered_map< uint32 /*mapId*/, InstanceGroupBind> BoundInstancesMap; + typedef std::unordered_map<Difficulty, std::unordered_map<uint32 /*mapId*/, InstanceGroupBind>> BoundInstancesMap; protected: typedef MemberSlotList::iterator member_witerator; typedef std::set<Player*> InvitesList; @@ -408,7 +408,8 @@ class TC_GAME_API Group InstanceGroupBind* GetBoundInstance(Map* aMap); InstanceGroupBind* GetBoundInstance(MapEntry const* mapEntry); InstanceGroupBind* GetBoundInstance(Difficulty difficulty, uint32 mapId); - BoundInstancesMap& GetBoundInstances(Difficulty difficulty); + BoundInstancesMap::iterator GetBoundInstances(Difficulty difficulty); + BoundInstancesMap::iterator GetBoundInstanceEnd(); // FG: evil hacks void BroadcastGroupUpdate(void); @@ -442,7 +443,7 @@ class TC_GAME_API Group ObjectGuid m_looterGuid; ObjectGuid m_masterLooterGuid; Rolls RollId; - BoundInstancesMap m_boundInstances[MAX_DIFFICULTY]; + BoundInstancesMap m_boundInstances; uint8* m_subGroupsCounts; ObjectGuid m_guid; uint32 m_maxEnchantingLevel; diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index 5ce188e9b20..bf9ddd12b7b 100644 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -92,20 +92,23 @@ void WorldSession::HandleCalendarGetCalendar(WorldPackets::Calendar::CalendarGet for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { - Player::BoundInstancesMap boundInstances = _player->GetBoundInstances(Difficulty(i)); - for (auto const& boundInstance : boundInstances) + auto boundInstances = _player->GetBoundInstances(Difficulty(i)); + if (boundInstances != _player->m_boundInstances.end()) { - if (boundInstance.second.perm) + for (auto const& boundInstance : boundInstances->second) { - WorldPackets::Calendar::CalendarSendCalendarRaidLockoutInfo lockoutInfo; - - InstanceSave const* save = boundInstance.second.save; - lockoutInfo.MapID = save->GetMapId(); - lockoutInfo.DifficultyID = save->GetDifficultyID(); - lockoutInfo.ExpireTime = save->GetResetTime() - currTime; - lockoutInfo.InstanceID = save->GetInstanceId(); // instance save id as unique instance copy id - - packet.RaidLockouts.push_back(lockoutInfo); + if (boundInstance.second.perm) + { + WorldPackets::Calendar::CalendarSendCalendarRaidLockoutInfo lockoutInfo; + + InstanceSave const* save = boundInstance.second.save; + lockoutInfo.MapID = save->GetMapId(); + lockoutInfo.DifficultyID = save->GetDifficultyID(); + lockoutInfo.ExpireTime = save->GetResetTime() - currTime; + lockoutInfo.InstanceID = save->GetInstanceId(); // instance save id as unique instance copy id + + packet.RaidLockouts.push_back(lockoutInfo); + } } } } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index be1a3760e4c..e840569672e 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -263,7 +263,7 @@ void Map::DeleteStateMachine() delete si_GridStates[GRID_STATE_REMOVAL]; } -Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent): +Map::Map(uint32 id, time_t expiry, uint32 InstanceId, Difficulty SpawnMode, Map* _parent): _creatureToMoveLock(false), _gameObjectsToMoveLock(false), _dynamicObjectsToMoveLock(false), _areaTriggersToMoveLock(false), i_mapEntry(sMapStore.LookupEntry(id)), i_spawnMode(SpawnMode), i_InstanceId(InstanceId), m_unloadTimer(0), m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE), @@ -3325,7 +3325,7 @@ template TC_GAME_API void Map::RemoveFromMap(Conversation*, bool); /* ******* Dungeon Instance Maps ******* */ -InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent) +InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, Difficulty SpawnMode, Map* _parent) : Map(id, expiry, InstanceId, SpawnMode, _parent), m_resetAfterUnload(false), m_unloadWhenEmpty(false), i_data(NULL), i_script_id(0), i_scenario(nullptr) @@ -3358,7 +3358,7 @@ Map::EnterState InstanceMap::CannotEnter(Player* player) { if (player->GetMapRef().getTarget() == this) { - TC_LOG_ERROR("maps", "InstanceMap::CannotEnter - player %s(%s) already in map %d, %d, %d!", player->GetName().c_str(), player->GetGUID().ToString().c_str(), GetId(), GetInstanceId(), GetSpawnMode()); + TC_LOG_ERROR("maps", "InstanceMap::CannotEnter - player %s(%s) already in map %d, %d, %d!", player->GetName().c_str(), player->GetGUID().ToString().c_str(), GetId(), GetInstanceId(), GetDifficultyID()); ABORT(); return CANNOT_ENTER_ALREADY_IN_MAP; } @@ -3416,14 +3416,14 @@ bool InstanceMap::AddPlayerToMap(Player* player, bool initPlayer /*= true*/) InstanceSave* mapSave = sInstanceSaveMgr->GetInstanceSave(GetInstanceId()); if (!mapSave) { - TC_LOG_DEBUG("maps", "InstanceMap::Add: creating instance save for map %d spawnmode %d with instance id %d", GetId(), GetSpawnMode(), GetInstanceId()); - mapSave = sInstanceSaveMgr->AddInstanceSave(GetId(), GetInstanceId(), Difficulty(GetSpawnMode()), 0, 0, true); + TC_LOG_DEBUG("maps", "InstanceMap::Add: creating instance save for map %d spawnmode %d with instance id %d", GetId(), GetDifficultyID(), GetInstanceId()); + mapSave = sInstanceSaveMgr->AddInstanceSave(GetId(), GetInstanceId(), GetDifficultyID(), 0, 0, true); } ASSERT(mapSave); // check for existing instance binds - InstancePlayerBind* playerBind = player->GetBoundInstance(GetId(), Difficulty(GetSpawnMode())); + InstancePlayerBind* playerBind = player->GetBoundInstance(GetId(), GetDifficultyID()); if (playerBind && playerBind->perm) { // cannot enter other instances if bound permanently @@ -3714,10 +3714,10 @@ void InstanceMap::SetResetSchedule(bool on) if (IsDungeon() && !HavePlayers() && !IsRaidOrHeroicDungeon()) { if (InstanceSave* save = sInstanceSaveMgr->GetInstanceSave(GetInstanceId())) - sInstanceSaveMgr->ScheduleReset(on, save->GetResetTime(), InstanceSaveManager::InstResetEvent(0, GetId(), Difficulty(GetSpawnMode()), GetInstanceId())); + sInstanceSaveMgr->ScheduleReset(on, save->GetResetTime(), InstanceSaveManager::InstResetEvent(0, GetId(), GetDifficultyID(), GetInstanceId())); else TC_LOG_ERROR("maps", "InstanceMap::SetResetSchedule: cannot turn schedule %s, there is no save information for instance (map [id: %u, name: %s], instance id: %u, difficulty: %u)", - on ? "on" : "off", GetId(), GetMapName(), GetInstanceId(), Difficulty(GetSpawnMode())); + on ? "on" : "off", GetId(), GetMapName(), GetInstanceId(), GetDifficultyID()); } } @@ -3831,7 +3831,7 @@ uint32 InstanceMap::GetMaxResetDelay() const /* ******* Battleground Instance Maps ******* */ -BattlegroundMap::BattlegroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent, uint8 spawnMode) +BattlegroundMap::BattlegroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent, Difficulty spawnMode) : Map(id, expiry, InstanceId, spawnMode, _parent), m_bg(NULL) { //lets initialize visibility distance for BG/Arenas diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 8140d60c4a7..7d453f0406a 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -260,7 +260,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> { friend class MapReference; public: - Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent = NULL); + Map(uint32 id, time_t, uint32 InstanceId, Difficulty SpawnMode, Map* _parent = NULL); virtual ~Map(); MapEntry const* GetEntry() const { return i_mapEntry; } @@ -370,7 +370,6 @@ class TC_GAME_API Map : public GridRefManager<NGridType> bool CheckGridIntegrity(Creature* c, bool moved) const; uint32 GetInstanceId() const { return i_InstanceId; } - uint8 GetSpawnMode() const { return (i_spawnMode); } enum EnterState { @@ -391,7 +390,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> const char* GetMapName() const; // have meaning only for instanced map (that have set real difficulty) - Difficulty GetDifficultyID() const { return Difficulty(GetSpawnMode()); } + Difficulty GetDifficultyID() const { return Difficulty(i_spawnMode); } MapDifficultyEntry const* GetMapDifficulty() const; uint8 GetDifficultyLootItemContext() const; @@ -402,7 +401,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> bool IsRaid() const; bool IsRaidOrHeroicDungeon() const; bool IsHeroic() const; - bool Is25ManRaid() const; // since 25man difficulties are 1 and 3, we can check them like that + bool Is25ManRaid() const; bool IsBattleground() const; bool IsBattleArena() const; bool IsBattlegroundOrArena() const; @@ -642,7 +641,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> std::mutex _gridLock; MapEntry const* i_mapEntry; - uint8 i_spawnMode; + Difficulty i_spawnMode; uint32 i_InstanceId; uint32 m_unloadTimer; float m_VisibleDistance; @@ -766,7 +765,7 @@ enum InstanceResetMethod class TC_GAME_API InstanceMap : public Map { public: - InstanceMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent); + InstanceMap(uint32 id, time_t, uint32 InstanceId, Difficulty SpawnMode, Map* _parent); ~InstanceMap(); bool AddPlayerToMap(Player* player, bool initPlayer = true) override; void RemovePlayerFromMap(Player*, bool) override; @@ -804,7 +803,7 @@ class TC_GAME_API InstanceMap : public Map class TC_GAME_API BattlegroundMap : public Map { public: - BattlegroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent, uint8 spawnMode); + BattlegroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent, Difficulty spawnMode); ~BattlegroundMap(); bool AddPlayerToMap(Player* player, bool initPlayer = true) override; diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index 8f1f2b98120..cf1d0fe3543 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -156,7 +156,7 @@ public: } // fill the gameobject data and save to the db - object->SaveToDB(map->GetId(), UI64LIT(1) << map->GetSpawnMode()); + object->SaveToDB(map->GetId(), { map->GetDifficultyID() }); ObjectGuid::LowType spawnId = object->GetSpawnId(); // delete the old object and do a clean load from DB with a fresh new GameObject instance. diff --git a/src/server/scripts/Commands/cs_instance.cpp b/src/server/scripts/Commands/cs_instance.cpp index a68d74a4ec6..10abea19971 100644 --- a/src/server/scripts/Commands/cs_instance.cpp +++ b/src/server/scripts/Commands/cs_instance.cpp @@ -81,13 +81,16 @@ public: uint32 counter = 0; for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { - Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); - for (Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) + auto binds = player->GetBoundInstances(Difficulty(i)); + if (binds != player->m_boundInstances.end()) { - InstanceSave* save = itr->second.save; - std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", itr->second.extendState == EXTEND_STATE_EXPIRED ? "expired" : itr->second.extendState == EXTEND_STATE_EXTENDED ? "yes" : "no", save->GetDifficultyID(), save->CanReset() ? "yes" : "no", timeleft.c_str()); - counter++; + for (auto itr = binds->second.begin(); itr != binds->second.end(); ++itr) + { + InstanceSave* save = itr->second.save; + std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); + handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", itr->second.extendState == EXTEND_STATE_EXPIRED ? "expired" : itr->second.extendState == EXTEND_STATE_EXTENDED ? "yes" : "no", save->GetDifficultyID(), save->CanReset() ? "yes" : "no", timeleft.c_str()); + counter++; + } } } handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_PLAYER_BINDS, counter); @@ -97,13 +100,16 @@ public: { for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { - Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i)); - for (Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr) + auto binds = group->GetBoundInstances(Difficulty(i)); + if (binds != group->GetBoundInstanceEnd()) { - InstanceSave* save = itr->second.save; - std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", "-", save->GetDifficultyID(), save->CanReset() ? "yes" : "no", timeleft.c_str()); - counter++; + for (auto itr = binds->second.begin(); itr != binds->second.end(); ++itr) + { + InstanceSave* save = itr->second.save; + std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); + handler->PSendSysMessage(LANG_COMMAND_LIST_BIND_INFO, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", "-", save->GetDifficultyID(), save->CanReset() ? "yes" : "no", timeleft.c_str()); + counter++; + } } } } @@ -138,19 +144,22 @@ public: for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { - Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i)); - for (Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();) + auto binds = player->GetBoundInstances(Difficulty(i)); + if (binds != player->m_boundInstances.end()) { - InstanceSave* save = itr->second.save; - if (itr->first != player->GetMapId() && (!MapId || MapId == itr->first) && (diff == -1 || diff == save->GetDifficultyID())) + for (auto itr = binds->second.begin(); itr != binds->second.end();) { - std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); - handler->PSendSysMessage(LANG_COMMAND_INST_UNBIND_UNBINDING, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficultyID(), save->CanReset() ? "yes" : "no", timeleft.c_str()); - player->UnbindInstance(itr, Difficulty(i)); - counter++; + InstanceSave* save = itr->second.save; + if (itr->first != player->GetMapId() && (!MapId || MapId == itr->first) && (diff == -1 || diff == save->GetDifficultyID())) + { + std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL)); + handler->PSendSysMessage(LANG_COMMAND_INST_UNBIND_UNBINDING, itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficultyID(), save->CanReset() ? "yes" : "no", timeleft.c_str()); + player->UnbindInstance(itr, binds); + counter++; + } + else + ++itr; } - else - ++itr; } } handler->PSendSysMessage(LANG_COMMAND_INST_UNBIND_UNBOUND, counter); diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 7b9d16502bb..c72893c77a9 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -301,7 +301,7 @@ public: Creature* creature = trans->CreateNPCPassenger(guid, &data); - creature->SaveToDB(trans->GetGOInfo()->moTransport.SpawnMap, UI64LIT(1) << map->GetSpawnMode()); + creature->SaveToDB(trans->GetGOInfo()->moTransport.SpawnMap, { map->GetDifficultyID() }); sObjectMgr->AddCreatureToGrid(guid, &data); return true; @@ -312,7 +312,7 @@ public: return false; PhasingHandler::InheritPhaseShift(creature, chr); - creature->SaveToDB(map->GetId(), UI64LIT(1) << map->GetSpawnMode()); + creature->SaveToDB(map->GetId(), { map->GetDifficultyID() }); ObjectGuid::LowType db_guid = creature->GetSpawnId(); diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index 47f466c7c61..8e6f486448a 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -674,7 +674,7 @@ public: } PhasingHandler::InheritPhaseShift(wpCreature, chr); - wpCreature->SaveToDB(map->GetId(), UI64LIT(1) << map->GetSpawnMode()); + wpCreature->SaveToDB(map->GetId(), { map->GetDifficultyID() }); ObjectGuid::LowType dbGuid = wpCreature->GetSpawnId(); @@ -892,7 +892,7 @@ public: } PhasingHandler::InheritPhaseShift(wpCreature, chr); - wpCreature->SaveToDB(map->GetId(), UI64LIT(1) << map->GetSpawnMode()); + wpCreature->SaveToDB(map->GetId(), { map->GetDifficultyID() }); ObjectGuid::LowType dbGuid = wpCreature->GetSpawnId(); @@ -961,7 +961,7 @@ public: } PhasingHandler::InheritPhaseShift(creature, chr); - creature->SaveToDB(map->GetId(), UI64LIT(1) << map->GetSpawnMode()); + creature->SaveToDB(map->GetId(), { map->GetDifficultyID() }); ObjectGuid::LowType dbGuid = creature->GetSpawnId(); @@ -1018,7 +1018,7 @@ public: } PhasingHandler::InheritPhaseShift(creature, chr); - creature->SaveToDB(map->GetId(), UI64LIT(1) << map->GetSpawnMode()); + creature->SaveToDB(map->GetId(), { map->GetDifficultyID() }); ObjectGuid::LowType dbGuid = creature->GetSpawnId(); diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp index f6d8ef2b6fc..617ed7cd697 100644 --- a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp +++ b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp @@ -112,7 +112,7 @@ public: //THIS GOB IS A TRAP - What shall i do? =( //Cast it spell? Copyed Heigan method floorEruption->SendCustomAnim(floorEruption->GetGoAnimProgress()); - floorEruption->CastSpell(nullptr, Difficulty(instance->GetSpawnMode()) == DIFFICULTY_10_N ? 17731 : 69294); //pFloorEruption->GetGOInfo()->trap.spellId + floorEruption->CastSpell(nullptr, instance->GetDifficultyID() == DIFFICULTY_10_N ? 17731 : 69294); //pFloorEruption->GetGOInfo()->trap.spellId //Get all immediatly nearby floors std::list<GameObject*> nearFloorList; diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp index 7d8813d0b7e..f43052ebb0a 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp @@ -232,7 +232,7 @@ class spell_saviana_conflagration_init : public SpellScriptLoader void FilterTargets(std::list<WorldObject*>& targets) { targets.remove_if(ConflagrationTargetSelector()); - uint8 maxSize = uint8(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 6 : 3); + uint8 maxSize = uint8(GetCaster()->GetMap()->Is25ManRaid() ? 6 : 3); if (targets.size() > maxSize) Trinity::Containers::RandomResize(targets, maxSize); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp index cc95ecc3dbf..49d0737f00c 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp @@ -282,7 +282,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript { EventStage = 6000; uint32 tributeChest = 0; - if (instance->GetSpawnMode() == DIFFICULTY_10_HC) + if (instance->GetDifficultyID() == DIFFICULTY_10_HC) { if (TrialCounter >= 50) tributeChest = GO_TRIBUTE_CHEST_10H_99; @@ -299,7 +299,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript } } } - else if (instance->GetSpawnMode() == DIFFICULTY_25_HC) + else if (instance->GetDifficultyID() == DIFFICULTY_25_HC) { if (TrialCounter >= 50) tributeChest = GO_TRIBUTE_CHEST_25H_99; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp index 8ac469533c7..8ccc4c621d8 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp @@ -135,7 +135,7 @@ Position const mincharPos = {4629.3711f, 2782.6089f, 424.6390f, 0.000000f}; bool IsVampire(Unit const* unit) { for (uint8 i = 0; i < 3; ++i) - if (unit->HasAura(vampireAuras[i][unit->GetMap()->GetSpawnMode() - DIFFICULTY_10_N])) + if (unit->HasAura(vampireAuras[i][unit->GetMap()->GetDifficultyID() - DIFFICULTY_10_N])) return true; return false; } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp index 96c6c810789..fd4cb1abd6e 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp @@ -642,7 +642,7 @@ class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader if (Creature* marrowgar = GetCaster()->ToCreature()) { CreatureAI* marrowgarAI = marrowgar->AI(); - uint8 boneSpikeCount = uint8(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 3 : 1); + uint8 boneSpikeCount = uint8(GetCaster()->GetMap()->Is25ManRaid() ? 3 : 1); std::list<Unit*> targets; marrowgarAI->SelectTargetList(targets, BoneSpikeTargetSelector(marrowgarAI), boneSpikeCount, SELECT_TARGET_RANDOM); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index d9ca5815904..b680ecb8075 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -1006,7 +1006,7 @@ class spell_putricide_slime_puddle_aura : public SpellScriptLoader void ReplaceAura() { if (Unit* target = GetHitUnit()) - GetCaster()->AddAura((GetCaster()->GetMap()->GetSpawnMode() & 1) ? 72456 : 70346, target); + GetCaster()->AddAura(GetCaster()->GetMap()->Is25ManRaid() ? 72456 : 70346, target); } void Register() override @@ -1316,7 +1316,7 @@ class spell_putricide_mutated_plague : public SpellScriptLoader int32 damage = spell->GetEffect(EFFECT_0)->CalcValue(caster); float multiplier = 2.0f; - if (GetTarget()->GetMap()->GetSpawnMode() & 1) + if (GetTarget()->GetMap()->Is25ManRaid()) multiplier = 3.0f; damage *= int32(pow(multiplier, GetStackAmount())); @@ -1416,7 +1416,7 @@ class spell_putricide_mutation_init : public SpellScriptLoader void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { uint32 spellId = 70311; - if (GetTarget()->GetMap()->GetSpawnMode() & 1) + if (GetTarget()->GetMap()->Is25ManRaid()) spellId = 71503; GetTarget()->CastSpell(GetTarget(), spellId, true); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index 4c2cc426a40..7748759cb98 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -1162,7 +1162,7 @@ class spell_sindragosa_unchained_magic : public SpellScriptLoader void FilterTargets(std::list<WorldObject*>& unitList) { unitList.remove_if(UnchainedMagicTargetSelector()); - uint32 maxSize = uint32(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 6 : 2); + uint32 maxSize = uint32(GetCaster()->GetMap()->Is25ManRaid() ? 6 : 2); if (unitList.size() > maxSize) Trinity::Containers::RandomResize(unitList, maxSize); } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index eb61348e114..193e5d8427d 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -372,7 +372,7 @@ class instance_icecrown_citadel : public InstanceMapScript { if (WeeklyQuestData[questIndex].creatureEntry == entry) { - uint8 diffIndex = uint8(instance->GetSpawnMode() & 1); + uint8 diffIndex = instance->Is25ManRaid() ? 1 : 0; if (!sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[questIndex].questId[diffIndex])) return 0; break; @@ -961,7 +961,7 @@ class instance_icecrown_citadel : public InstanceMapScript case DATA_VALITHRIA_DREAMWALKER: if (state == DONE) { - if (sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[8].questId[instance->GetSpawnMode() & 1])) + if (sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[8].questId[instance->Is25ManRaid() ? 1 : 0])) instance->SummonCreature(NPC_VALITHRIA_DREAMWALKER_QUEST, ValithriaSpawnPos); if (GameObject* teleporter = instance->GetGameObject(TeleporterSindragosaGUID)) SetTeleporterState(teleporter, true); @@ -1066,7 +1066,7 @@ class instance_icecrown_citadel : public InstanceMapScript break; // 5 is the index of Blood Quickening - if (!sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[5].questId[instance->GetSpawnMode() & 1])) + if (!sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[5].questId[instance->Is25ManRaid() ? 1 : 0])) break; switch (data) |