diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 2451aac3d..a3823112b 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -39,6 +39,7 @@
#include "MapMgr.h"
#include "ObjectMgr.h"
#include "Player.h"
+#include "RaceMgr.h"
#include "ReputationMgr.h"
#include "ScriptMgr.h"
#include "SpellMgr.h"
@@ -115,7 +116,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
criteria->ID, criteria->requiredType, dataType, classRace.class_id);
return false;
}
- if (classRace.race_id && ((1 << (classRace.race_id - 1)) & RACEMASK_ALL_PLAYABLE) == 0)
+ if (classRace.race_id && ((1 << (classRace.race_id - 1)) & sRaceMgr->GetPlayableRaceMask()) == 0)
{
LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: {} Type: {}) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE ({}) has non-existing race in value2 ({}), ignored.",
criteria->ID, criteria->requiredType, dataType, classRace.race_id);
@@ -275,7 +276,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
criteria->ID, criteria->requiredType, dataType, classRace.class_id);
return false;
}
- if (classRace.race_id && ((1 << (classRace.race_id - 1)) & RACEMASK_ALL_PLAYABLE) == 0)
+ if (classRace.race_id && ((1 << (classRace.race_id - 1)) & sRaceMgr->GetPlayableRaceMask()) == 0)
{
LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: {} Type: {}) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE ({}) has non-existing race in value2 ({}), ignored.",
criteria->ID, criteria->requiredType, dataType, classRace.race_id);
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 688820001..213ee742f 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -24,6 +24,7 @@
#include "ObjectMgr.h"
#include "Pet.h"
#include "Player.h"
+#include "RaceMgr.h"
#include "ReputationMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
@@ -2082,9 +2083,9 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
}
case CONDITION_RACE:
{
- if (!(cond->ConditionValue1 & RACEMASK_ALL_PLAYABLE))
+ if (!(cond->ConditionValue1 & sRaceMgr->GetPlayableRaceMask()))
{
- LOG_ERROR("sql.sql", "Race condition has non existing racemask ({}), skipped", cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE);
+ LOG_ERROR("sql.sql", "Race condition has non existing racemask ({}), skipped", cond->ConditionValue1 & ~sRaceMgr->GetPlayableRaceMask());
return false;
}
diff --git a/src/server/game/Entities/Player/RaceMgr.cpp b/src/server/game/Entities/Player/RaceMgr.cpp
new file mode 100644
index 000000000..b1ac288cb
--- /dev/null
+++ b/src/server/game/Entities/Player/RaceMgr.cpp
@@ -0,0 +1,77 @@
+/*
+ * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#include "RaceMgr.h"
+#include "AccountMgr.h"
+#include "DatabaseEnv.h"
+#include "ObjectMgr.h"
+#include "Player.h"
+#include "Util.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
+
+uint8 RaceMgr::_maxRaces = 0;
+
+uint32 RaceMgr::_playableRaceMask = 0;
+uint32 RaceMgr::_allianceRaceMask = 0;
+uint32 RaceMgr::_hordeRaceMask = 0;
+
+RaceMgr::RaceMgr()
+{
+}
+
+RaceMgr::~RaceMgr()
+{
+}
+
+RaceMgr* RaceMgr::instance()
+{
+ static RaceMgr instance;
+ return &instance;
+}
+
+void RaceMgr::LoadRaces()
+{
+ SetMaxRaces(0 + 1);
+ _playableRaceMask = 0;
+ _hordeRaceMask = 0;
+ _allianceRaceMask = 0;
+
+ for (auto const& raceEntry : sChrRacesStore)
+ {
+ if (!raceEntry)
+ continue;
+
+ uint8 alliance = raceEntry->alliance;
+ uint8 raceId = raceEntry->RaceID;
+
+ if (raceEntry->Flags & CHRRACES_FLAGS_NOT_PLAYABLE)
+ continue;
+
+ if (GetMaxRaces() <= raceId)
+ SetMaxRaces(raceId + 1);
+
+ uint32 raceBit = (1 << (raceId - 1));
+
+ _playableRaceMask |= raceBit;
+
+ if (alliance == ALLIANCE_HORDE)
+ _hordeRaceMask |= raceBit;
+ else if (alliance == ALLIANCE_ALLIANCE)
+ _allianceRaceMask |= raceBit;
+ }
+}
diff --git a/src/server/game/Entities/Player/RaceMgr.h b/src/server/game/Entities/Player/RaceMgr.h
new file mode 100644
index 000000000..239e69070
--- /dev/null
+++ b/src/server/game/Entities/Player/RaceMgr.h
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#ifndef __ACORE_RACEMGR_H
+#define __ACORE_RACEMGR_H
+
+#include "DatabaseEnv.h"
+#include "ObjectGuid.h"
+#include "SharedDefines.h"
+#include