diff options
Diffstat (limited to 'src')
29 files changed, 224 insertions, 153 deletions
diff --git a/src/server/game/Achievements/CriteriaHandler.cpp b/src/server/game/Achievements/CriteriaHandler.cpp index a6ac438bf1e..288be7eea6f 100644 --- a/src/server/game/Achievements/CriteriaHandler.cpp +++ b/src/server/game/Achievements/CriteriaHandler.cpp @@ -118,7 +118,7 @@ bool CriteriaData::IsValid(Criteria const* criteria) criteria->ID, criteria->Entry->Type, DataType, ClassRace.Class); return false; } - if (ClassRace.Race && ((UI64LIT(1) << (ClassRace.Race-1)) & RACEMASK_ALL_PLAYABLE) == 0) + if (!Trinity::RaceMask<uint64>{ RACEMASK_ALL_PLAYABLE }.HasRace(ClassRace.Race)) { TC_LOG_ERROR("sql.sql", "Table `criteria_data` (Entry: %u Type: %u) for data type CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) contains a non-existing race in value2 (%u), ignored.", criteria->ID, criteria->Entry->Type, DataType, ClassRace.Race); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 7c71b4dad48..f5a339c4d5c 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -34,6 +34,7 @@ #include "PhasingHandler.h" #include "Player.h" #include "Pet.h" +#include "RaceMask.h" #include "Realm.h" #include "ReputationMgr.h" #include "ScriptMgr.h" @@ -205,7 +206,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const case CONDITION_RACE: { if (Unit* unit = object->ToUnit()) - condMeets = (unit->getRaceMask() & ConditionValue1) != 0; + condMeets = Trinity::RaceMask<uint32>{ ConditionValue1 }.HasRace(unit->getRace()); break; } case CONDITION_GENDER: @@ -2019,7 +2020,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) const } case CONDITION_RACE: { - if (cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE) + if (uint32(cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE)) // uint32 works thanks to weird index remapping in racemask { TC_LOG_ERROR("sql.sql", "%s has non existing racemask (" UI64FMTD "), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE); return false; @@ -2546,7 +2547,7 @@ bool ConditionMgr::IsPlayerMeetingCondition(Player const* player, PlayerConditio if (condition->MaxLevel && player->getLevel() > condition->MaxLevel) return false; - if (condition->RaceMask && !(player->getRaceMask() & condition->RaceMask)) + if (condition->RaceMask && !condition->RaceMask.HasRace(player->getRace())) return false; if (condition->ClassMask && !(player->getClassMask() & condition->ClassMask)) diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 17f8111abe5..c9defdcc578 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -2564,7 +2564,7 @@ SkillRaceClassInfoEntry const* DB2Manager::GetSkillRaceClassInfo(uint32 skill, u auto bounds = _skillRaceClassInfoBySkill.equal_range(skill); for (auto itr = bounds.first; itr != bounds.second; ++itr) { - if (itr->second->RaceMask && !(itr->second->RaceMask & (UI64LIT(1) << (race - 1)))) + if (itr->second->RaceMask && !(itr->second->RaceMask.HasRace(race))) continue; if (itr->second->ClassMask && !(itr->second->ClassMask & (1 << (class_ - 1)))) continue; diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index ad80e089dae..2a861ad2d2c 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -20,6 +20,7 @@ #include "Define.h" #include "DBCEnums.h" +#include "RaceMask.h" #include "Util.h" #pragma pack(push, 1) @@ -1063,7 +1064,7 @@ struct DurabilityQualityEntry struct EmotesEntry { uint32 ID; - int64 RaceMask; + Trinity::RaceMask<int64> RaceMask; char const* EmoteSlashCommand; int32 AnimID; uint32 EmoteFlags; @@ -1123,7 +1124,7 @@ struct ExpectedStatModEntry struct FactionEntry { - int64 ReputationRaceMask[4]; + Trinity::RaceMask<int64> ReputationRaceMask[4]; LocalizedString* Name; LocalizedString* Description; uint32 ID; @@ -1771,7 +1772,7 @@ struct ItemPriceBaseEntry struct ItemSearchNameEntry { - int64 AllowableRace; + Trinity::RaceMask<int64> AllowableRace; LocalizedString* Display; uint32 ID; uint8 OverallQualityID; @@ -1811,7 +1812,7 @@ struct ItemSetSpellEntry struct ItemSparseEntry { uint32 ID; - int64 AllowableRace; + Trinity::RaceMask<int64> AllowableRace; LocalizedString* Description; LocalizedString* Display3; LocalizedString* Display2; @@ -2215,7 +2216,7 @@ struct PhaseXPhaseGroupEntry struct PlayerConditionEntry { - int64 RaceMask; + Trinity::RaceMask<int64> RaceMask; LocalizedString* FailureDescription; uint32 ID; uint16 MinLevel; @@ -2547,7 +2548,7 @@ struct SkillLineEntry struct SkillLineAbilityEntry { - int64 RaceMask; + Trinity::RaceMask<int64> RaceMask; uint32 ID; int16 SkillLine; int32 Spell; @@ -2567,7 +2568,7 @@ struct SkillLineAbilityEntry struct SkillRaceClassInfoEntry { uint32 ID; - int64 RaceMask; + Trinity::RaceMask<int64> RaceMask; int16 SkillID; int32 ClassMask; uint16 Flags; diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h index 239fd77f2d2..4b3bbda378d 100644 --- a/src/server/game/Entities/Item/ItemTemplate.h +++ b/src/server/game/Entities/Item/ItemTemplate.h @@ -747,7 +747,7 @@ struct TC_GAME_API ItemTemplate uint32 GetSellPrice() const { return ExtendedData->SellPrice; } InventoryType GetInventoryType() const { return InventoryType(ExtendedData->InventoryType); } int32 GetAllowableClass() const { return ExtendedData->AllowableClass; } - int64 GetAllowableRace() const { return ExtendedData->AllowableRace; } + Trinity::RaceMask<int64> GetAllowableRace() const { return ExtendedData->AllowableRace; } uint32 GetBaseItemLevel() const { return ExtendedData->ItemLevel; } int32 GetBaseRequiredLevel() const { return ExtendedData->RequiredLevel; } uint32 GetRequiredSkill() const { return ExtendedData->RequiredSkill; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 86ed8138d7b..8268f98c37c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2481,7 +2481,7 @@ void Player::GiveLevel(uint8 level) if (Pet* pet = GetPet()) pet->SynchronizeLevelWithOwner(); - if (MailLevelReward const* mailReward = sObjectMgr->GetMailLevelReward(level, getRaceMask())) + if (MailLevelReward const* mailReward = sObjectMgr->GetMailLevelReward(level, getRace())) { /// @todo Poor design of mail system CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction(); @@ -11856,7 +11856,7 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const if ((proto->GetFlags2() & ITEM_FLAG2_FACTION_ALLIANCE) && GetTeam() != ALLIANCE) return EQUIP_ERR_CANT_EQUIP_EVER; - if ((proto->GetAllowableClass() & getClassMask()) == 0 || (proto->GetAllowableRace() & getRaceMask()) == 0) + if ((proto->GetAllowableClass() & getClassMask()) == 0 || !proto->GetAllowableRace().HasRace(getRace())) return EQUIP_ERR_CANT_EQUIP_EVER; if (proto->GetRequiredSkill() != 0) @@ -11907,7 +11907,7 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje return EQUIP_ERR_ITEM_NOT_FOUND; // Used by group, function GroupLoot, to know if a prototype can be used by a player - if ((proto->GetAllowableClass() & getClassMask()) == 0 || (proto->GetAllowableRace() & getRaceMask()) == 0) + if ((proto->GetAllowableClass() & getClassMask()) == 0 || !proto->GetAllowableRace().HasRace(getRace())) return EQUIP_ERR_CANT_EQUIP_EVER; if (proto->GetRequiredSpell() != 0 && !HasSpell(proto->GetRequiredSpell())) @@ -16030,10 +16030,7 @@ bool Player::SatisfyQuestClass(Quest const* qInfo, bool msg) const bool Player::SatisfyQuestRace(Quest const* qInfo, bool msg) const { - uint64 reqraces = qInfo->GetAllowableRaces(); - if (reqraces == uint64(-1)) - return true; - if ((reqraces & getRaceMask()) == 0) + if (!qInfo->GetAllowableRaces().HasRace(getRace())) { if (msg) { @@ -24372,7 +24369,7 @@ void Player::LearnQuestRewardedSpells() void Player::LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue) { - uint64 raceMask = getRaceMask(); + uint8 race = getRace(); uint32 classMask = getClassMask(); std::vector<SkillLineAbilityEntry const*> const* skillLineAbilities = sDB2Manager.GetSkillLineAbilitiesBySkill(skillId); if (!skillLineAbilities) @@ -24392,7 +24389,7 @@ void Player::LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue) continue; // Check race if set - if (ability->RaceMask && !(ability->RaceMask & raceMask)) + if (ability->RaceMask && !ability->RaceMask.HasRace(race)) continue; // Check class if set @@ -24726,7 +24723,7 @@ Player* Player::GetTrader() const bool Player::IsSpellFitByClassAndRace(uint32 spell_id) const { - uint64 racemask = getRaceMask(); + uint8 race = getRace(); uint32 classmask = getClassMask(); SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spell_id); @@ -24736,7 +24733,7 @@ bool Player::IsSpellFitByClassAndRace(uint32 spell_id) const for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx) { // skip wrong race skills - if (_spell_idx->second->RaceMask && (_spell_idx->second->RaceMask & racemask) == 0) + if (_spell_idx->second->RaceMask && !_spell_idx->second->RaceMask.HasRace(race)) continue; // skip wrong class skills diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 27049eb2d1b..895fbcea9f9 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1460,7 +1460,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> static bool IsValidGender(uint8 Gender) { return Gender <= GENDER_FEMALE; } static bool IsValidClass(uint8 Class) { return ((1 << (Class - 1)) & CLASSMASK_ALL_PLAYABLE) != 0; } - static bool IsValidRace(uint8 Race) { return ((UI64LIT(1) << (Race - 1)) & RACEMASK_ALL_PLAYABLE) != 0; } + static bool IsValidRace(uint8 Race) { return Trinity::RaceMask<uint64>{ RACEMASK_ALL_PLAYABLE }.HasRace(Race); } static bool ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 hairID, uint8 hairColor, uint8 faceID, uint8 facialHair, uint8 skinColor, std::array<uint8, PLAYER_CUSTOM_DISPLAY_SIZE> const& customDisplay, bool create = false); /*********************************************************/ diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 9e0771ab818..38cbbd8cae1 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -3423,7 +3423,7 @@ void ObjectMgr::LoadPlayerInfo() for (SkillRaceClassInfoEntry const* rcInfo : sSkillRaceClassInfoStore) if (rcInfo->Availability == 1) for (uint32 raceIndex = RACE_HUMAN; raceIndex < MAX_RACES; ++raceIndex) - if (rcInfo->RaceMask == -1 || ((UI64LIT(1) << (raceIndex - 1)) & rcInfo->RaceMask)) + if (rcInfo->RaceMask.HasRace(raceIndex)) for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex) if (rcInfo->ClassMask == -1 || ((1 << (classIndex - 1)) & rcInfo->ClassMask)) if (PlayerInfo* info = _playerInfo[raceIndex][classIndex]) @@ -3450,13 +3450,13 @@ void ObjectMgr::LoadPlayerInfo() do { Field* fields = result->Fetch(); - uint64 raceMask = fields[0].GetUInt64(); + Trinity::RaceMask<uint64> raceMask = { fields[0].GetUInt64() }; uint32 classMask = fields[1].GetUInt32(); uint32 spellId = fields[2].GetUInt32(); - if (raceMask != 0 && !(raceMask & RACEMASK_ALL_PLAYABLE)) + if (raceMask && !(raceMask.RawValue & RACEMASK_ALL_PLAYABLE)) { - TC_LOG_ERROR("sql.sql", "Wrong race mask " UI64FMTD " in `playercreateinfo_spell_custom` table, ignoring.", raceMask); + TC_LOG_ERROR("sql.sql", "Wrong race mask " UI64FMTD " in `playercreateinfo_spell_custom` table, ignoring.", raceMask.RawValue); continue; } @@ -3468,7 +3468,7 @@ void ObjectMgr::LoadPlayerInfo() for (uint32 raceIndex = RACE_HUMAN; raceIndex < MAX_RACES; ++raceIndex) { - if (raceMask == 0 || ((UI64LIT(1) << (raceIndex - 1)) & raceMask)) + if (!raceMask || raceMask.HasRace(raceIndex)) { for (uint32 classIndex = CLASS_WARRIOR; classIndex < MAX_CLASSES; ++classIndex) { @@ -4205,12 +4205,12 @@ void ObjectMgr::LoadQuests() } } // AllowableRaces, can be -1/RACEMASK_ALL_PLAYABLE to allow any race - if (qinfo->AllowableRaces != uint64(-1)) + if (qinfo->AllowableRaces.RawValue != uint64(-1)) { - if (qinfo->AllowableRaces > 0 && !(qinfo->AllowableRaces & RACEMASK_ALL_PLAYABLE)) + if (qinfo->AllowableRaces && !(qinfo->AllowableRaces.RawValue & RACEMASK_ALL_PLAYABLE)) { - TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable races in `AllowableRaces` (" UI64FMTD "), value set to 0 (all races).", qinfo->GetQuestId(), qinfo->AllowableRaces); - qinfo->AllowableRaces = uint64(-1); + TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable races in `AllowableRaces` (" UI64FMTD "), value set to -1 (all races).", qinfo->GetQuestId(), qinfo->AllowableRaces.RawValue); + qinfo->AllowableRaces.RawValue = uint64(-1); } } // RequiredSkillId, can be 0 @@ -8378,7 +8378,6 @@ int32 ObjectMgr::GetBaseReputationOf(FactionEntry const* factionEntry, uint8 rac if (!factionEntry) return 0; - uint64 raceMask = UI64LIT(1) << (race - 1); uint32 classMask = 1 << (playerClass - 1); for (int i = 0; i < 4; i++) @@ -8386,7 +8385,7 @@ int32 ObjectMgr::GetBaseReputationOf(FactionEntry const* factionEntry, uint8 rac if ((!factionEntry->ReputationClassMask[i] || factionEntry->ReputationClassMask[i] & classMask) && (!factionEntry->ReputationRaceMask[i] || - factionEntry->ReputationRaceMask[i] & raceMask)) + factionEntry->ReputationRaceMask[i].HasRace(race))) return factionEntry->ReputationBase[i]; } @@ -8624,7 +8623,7 @@ void ObjectMgr::LoadMailLevelRewards() continue; } - _mailLevelRewardStore[level].push_back(MailLevelReward(raceMask, mailTemplateId, senderEntry)); + _mailLevelRewardStore[level].emplace_back(raceMask, mailTemplateId, senderEntry); ++count; } diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 671fb4465f5..2ee934b7fe5 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -30,6 +30,7 @@ #include "ObjectGuid.h" #include "Position.h" #include "QuestDef.h" +#include "RaceMask.h" #include "SharedDefines.h" #include "Trainer.h" #include "VehicleDefines.h" @@ -610,10 +611,10 @@ struct PetLevelInfo struct MailLevelReward { - MailLevelReward() : raceMask(0), mailTemplateId(0), senderEntry(0) { } - MailLevelReward(uint64 _raceMask, uint32 _mailTemplateId, uint32 _senderEntry) : raceMask(_raceMask), mailTemplateId(_mailTemplateId), senderEntry(_senderEntry) { } + MailLevelReward() : raceMask({ 0 }), mailTemplateId(0), senderEntry(0) { } + MailLevelReward(uint64 _raceMask, uint32 _mailTemplateId, uint32 _senderEntry) : raceMask({ _raceMask }), mailTemplateId(_mailTemplateId), senderEntry(_senderEntry) { } - uint64 raceMask; + Trinity::RaceMask<uint64> raceMask; uint32 mailTemplateId; uint32 senderEntry; }; @@ -1346,14 +1347,14 @@ class TC_GAME_API ObjectMgr ExclusiveQuestGroups mExclusiveQuestGroups; - MailLevelReward const* GetMailLevelReward(uint8 level, uint64 raceMask) + MailLevelReward const* GetMailLevelReward(uint8 level, uint8 race) { MailLevelRewardContainer::const_iterator map_itr = _mailLevelRewardStore.find(level); if (map_itr == _mailLevelRewardStore.end()) return nullptr; for (auto const& mailLevelReward : map_itr->second) - if (mailLevelReward.raceMask & raceMask) + if (mailLevelReward.raceMask.HasRace(race)) return &mailLevelReward; return nullptr; diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index 5adb0af4701..3e36c839e11 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -21,6 +21,7 @@ #include "AchievementMgr.h" #include "DatabaseEnvFwd.h" #include "ObjectGuid.h" +#include "RaceMask.h" #include "SharedDefines.h" #include <unordered_map> @@ -251,7 +252,7 @@ struct GuildReward { uint32 ItemID; uint8 MinGuildRep; - uint64 RaceMask; + Trinity::RaceMask<uint64> RaceMask; uint64 Cost; std::vector<uint32> AchievementsRequired; }; diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp index e891f9a6d26..65ed69f79af 100644 --- a/src/server/game/Guilds/GuildMgr.cpp +++ b/src/server/game/Guilds/GuildMgr.cpp @@ -515,7 +515,7 @@ void GuildMgr::LoadGuildRewards() Field* fields = result->Fetch(); reward.ItemID = fields[0].GetUInt32(); reward.MinGuildRep = fields[1].GetUInt8(); - reward.RaceMask = fields[2].GetUInt64(); + reward.RaceMask.RawValue = fields[2].GetUInt64(); reward.Cost = fields[3].GetUInt64(); if (!sObjectMgr->GetItemTemplate(reward.ItemID)) diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 48adec75fa5..ea3ea2d0d6a 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -2181,7 +2181,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(std::shared_ptr<WorldPa { Quest const* quest = iter->second; uint64 newRaceMask = (newTeamId == TEAM_ALLIANCE) ? RACEMASK_ALLIANCE : RACEMASK_HORDE; - if (quest->GetAllowableRaces() != uint64(-1) && !(quest->GetAllowableRaces() & newRaceMask)) + if (quest->GetAllowableRaces().RawValue != uint64(-1) && !(quest->GetAllowableRaces().RawValue & newRaceMask)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST); stmt->setUInt64(0, lowGuid); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 83165155e50..04489bbb744 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -89,7 +89,7 @@ void WorldSession::HandleWhoOpcode(WorldPackets::Who::WhoRequestPkt& whoRequest) TC_LOG_DEBUG("network", "WorldSession::HandleWhoOpcode: MinLevel: %u, MaxLevel: %u, Name: %s (VirtualRealmName: %s), Guild: %s (GuildVirtualRealmName: %s), RaceFilter: " UI64FMTD ", ClassFilter: %d, Areas: " SZFMTD ", Words: " SZFMTD ".", request.MinLevel, request.MaxLevel, request.Name.c_str(), request.VirtualRealmName.c_str(), request.Guild.c_str(), request.GuildVirtualRealmName.c_str(), - request.RaceFilter, request.ClassFilter, whoRequest.Areas.size(), request.Words.size()); + request.RaceFilter.RawValue, request.ClassFilter, whoRequest.Areas.size(), request.Words.size()); // zones count, client limit = 10 (2.0.10) // can't be received from real client or broken packet @@ -167,7 +167,7 @@ void WorldSession::HandleWhoOpcode(WorldPackets::Who::WhoRequestPkt& whoRequest) continue; // check if race matches racemask - if (request.RaceFilter >= 0 && !(request.RaceFilter & (SI64LIT(1) << target.GetRace()))) + if (!request.RaceFilter.HasRace(target.GetRace())) continue; if (!whoRequest.Areas.empty()) diff --git a/src/server/game/Miscellaneous/RaceMask.h b/src/server/game/Miscellaneous/RaceMask.h new file mode 100644 index 00000000000..9e698769467 --- /dev/null +++ b/src/server/game/Miscellaneous/RaceMask.h @@ -0,0 +1,150 @@ +/* + * This file is part of the TrinityCore 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 <http://www.gnu.org/licenses/>. + */ + +#ifndef RaceMask_h__ +#define RaceMask_h__ + +#include "Define.h" +#include <type_traits> + +enum Races +{ + RACE_NONE = 0, + RACE_HUMAN = 1, + RACE_ORC = 2, + RACE_DWARF = 3, + RACE_NIGHTELF = 4, + RACE_UNDEAD_PLAYER = 5, + RACE_TAUREN = 6, + RACE_GNOME = 7, + RACE_TROLL = 8, + RACE_GOBLIN = 9, + RACE_BLOODELF = 10, + RACE_DRAENEI = 11, + //RACE_FEL_ORC = 12, + //RACE_NAGA = 13, + //RACE_BROKEN = 14, + //RACE_SKELETON = 15, + //RACE_VRYKUL = 16, + //RACE_TUSKARR = 17, + //RACE_FOREST_TROLL = 18, + //RACE_TAUNKA = 19, + //RACE_NORTHREND_SKELETON = 20, + //RACE_ICE_TROLL = 21, + RACE_WORGEN = 22, + //RACE_GILNEAN = 23, + RACE_PANDAREN_NEUTRAL = 24, + RACE_PANDAREN_ALLIANCE = 25, + RACE_PANDAREN_HORDE = 26, + RACE_NIGHTBORNE = 27, + RACE_HIGHMOUNTAIN_TAUREN = 28, + RACE_VOID_ELF = 29, + RACE_LIGHTFORGED_DRAENEI = 30, + RACE_ZANDALARI_TROLL = 31, + RACE_KUL_TIRAN = 32, + //RACE_THIN_HUMAN = 33, + RACE_DARK_IRON_DWARF = 34, // RaceMask bit 11 + RACE_VULPERA = 35, // RaceMask bit 12 + RACE_MAGHAR_ORC = 36, // RaceMask bit 13 + RACE_MECHAGNOME = 37 // RaceMask bit 14 +}; + +// max+1 for player race +#define MAX_RACES 38 + +namespace Trinity +{ +template<typename T> +struct RaceMask +{ + static_assert(std::is_integral<T>::value, "RaceMask<T> must be integral"); + + T RawValue; + + constexpr bool HasRace(uint8 raceId) const + { + if (raceId >= MAX_RACES || raceBits[raceId] < 0 || raceBits[raceId] >= 64) + return false; + + return (RawValue & (T(1) << raceBits[raceId])) != 0; + } + + static constexpr T GetMaskForRace(uint8 raceId) + { + return raceId < MAX_RACES ? (T(1) << raceBits[raceId]) : T(0); + } + + constexpr operator bool() const { return RawValue != T(0); } + constexpr bool operator!() const { return !operator bool(); } + +private: + static constexpr int32 raceBits[MAX_RACES] = + { + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 21, -1, 23, 24, 25, 26, 27, 28, + 29, 30, 31, -1, 11, 12, 13, 14 + }; +}; +} + +constexpr uint64 RACEMASK_ALL_PLAYABLE = + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_HUMAN) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_ORC) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_DWARF) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_NIGHTELF) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_UNDEAD_PLAYER) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_TAUREN) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_GNOME) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_TROLL) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_BLOODELF) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_DRAENEI) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_GOBLIN) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_WORGEN) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_PANDAREN_NEUTRAL) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_PANDAREN_ALLIANCE) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_PANDAREN_HORDE) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_NIGHTBORNE) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_HIGHMOUNTAIN_TAUREN) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_VOID_ELF) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_LIGHTFORGED_DRAENEI) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_ZANDALARI_TROLL) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_KUL_TIRAN) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_DARK_IRON_DWARF) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_VULPERA) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_MAGHAR_ORC) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_MECHAGNOME); + +constexpr uint64 RACEMASK_NEUTRAL = Trinity::RaceMask<uint64>::GetMaskForRace(RACE_PANDAREN_NEUTRAL); + +constexpr uint64 RACEMASK_ALLIANCE = + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_HUMAN) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_DWARF) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_NIGHTELF) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_GNOME) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_DRAENEI) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_WORGEN) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_PANDAREN_ALLIANCE) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_VOID_ELF) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_LIGHTFORGED_DRAENEI) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_KUL_TIRAN) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_DARK_IRON_DWARF) | + Trinity::RaceMask<uint64>::GetMaskForRace(RACE_MECHAGNOME); + +constexpr uint64 RACEMASK_HORDE = RACEMASK_ALL_PLAYABLE & ~(RACEMASK_NEUTRAL | RACEMASK_ALLIANCE); + +#endif // RaceMask_h__ diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index b1a996e33e3..96eefe37126 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -127,90 +127,6 @@ enum Gender GENDER_NONE = 2 }; -// ChrRaces.db2 (8.0.1.27075) -enum Races -{ - RACE_NONE = 0, - RACE_HUMAN = 1, - RACE_ORC = 2, - RACE_DWARF = 3, - RACE_NIGHTELF = 4, - RACE_UNDEAD_PLAYER = 5, - RACE_TAUREN = 6, - RACE_GNOME = 7, - RACE_TROLL = 8, - RACE_GOBLIN = 9, - RACE_BLOODELF = 10, - RACE_DRAENEI = 11, - //RACE_FEL_ORC = 12, - //RACE_NAGA = 13, - //RACE_BROKEN = 14, - //RACE_SKELETON = 15, - //RACE_VRYKUL = 16, - //RACE_TUSKARR = 17, - //RACE_FOREST_TROLL = 18, - //RACE_TAUNKA = 19, - //RACE_NORTHREND_SKELETON = 20, - //RACE_ICE_TROLL = 21, - RACE_WORGEN = 22, - //RACE_GILNEAN = 23, - RACE_PANDAREN_NEUTRAL = 24, - RACE_PANDAREN_ALLIANCE = 25, - RACE_PANDAREN_HORDE = 26, - RACE_NIGHTBORNE = 27, - RACE_HIGHMOUNTAIN_TAUREN = 28, - RACE_VOID_ELF = 29, - RACE_LIGHTFORGED_DRAENEI = 30, - //RACE_ZANDALARI_TROLL = 31, - //RACE_KUL_TIRAN = 32, - //RACE_THIN_HUMAN = 33, - RACE_DARK_IRON_DWARF = 34, - //RACE_VULPERA = 35, - RACE_MAGHAR_ORC = 36 -}; - -// max+1 for player race -#define MAX_RACES 37 - -#define RACEMASK_ALL_PLAYABLE \ - ((UI64LIT(1)<<(RACE_HUMAN-1)) | \ - (UI64LIT(1)<<(RACE_ORC-1)) | \ - (UI64LIT(1)<<(RACE_DWARF-1)) | \ - (UI64LIT(1)<<(RACE_NIGHTELF-1)) | \ - (UI64LIT(1)<<(RACE_UNDEAD_PLAYER-1)) | \ - (UI64LIT(1)<<(RACE_TAUREN-1)) | \ - (UI64LIT(1)<<(RACE_GNOME-1)) | \ - (UI64LIT(1)<<(RACE_TROLL-1)) | \ - (UI64LIT(1)<<(RACE_BLOODELF-1)) | \ - (UI64LIT(1)<<(RACE_DRAENEI-1)) | \ - (UI64LIT(1)<<(RACE_GOBLIN-1)) | \ - (UI64LIT(1)<<(RACE_WORGEN-1)) | \ - (UI64LIT(1)<<(RACE_PANDAREN_NEUTRAL-1)) | \ - (UI64LIT(1)<<(RACE_PANDAREN_ALLIANCE-1)) | \ - (UI64LIT(1)<<(RACE_PANDAREN_HORDE-1)) | \ - (UI64LIT(1)<<(RACE_NIGHTBORNE-1)) | \ - (UI64LIT(1)<<(RACE_HIGHMOUNTAIN_TAUREN-1)) | \ - (UI64LIT(1)<<(RACE_VOID_ELF-1)) | \ - (UI64LIT(1)<<(RACE_LIGHTFORGED_DRAENEI-1)) | \ - (UI64LIT(1)<<(RACE_DARK_IRON_DWARF-1)) | \ - (UI64LIT(1)<<(RACE_MAGHAR_ORC-1))) - -#define RACEMASK_NEUTRAL (UI64LIT(1)<<(RACE_PANDAREN_NEUTRAL-1)) - -#define RACEMASK_ALLIANCE \ - ((UI64LIT(1)<<(RACE_HUMAN-1)) | \ - (UI64LIT(1)<<(RACE_DWARF-1)) | \ - (UI64LIT(1)<<(RACE_NIGHTELF-1)) | \ - (UI64LIT(1)<<(RACE_GNOME-1)) | \ - (UI64LIT(1)<<(RACE_DRAENEI-1)) | \ - (UI64LIT(1)<<(RACE_WORGEN-1)) | \ - (UI64LIT(1)<<(RACE_PANDAREN_ALLIANCE-1)) | \ - (UI64LIT(1)<<(RACE_VOID_ELF-1)) | \ - (UI64LIT(1)<<(RACE_LIGHTFORGED_DRAENEI-1)) | \ - (UI64LIT(1)<<(RACE_DARK_IRON_DWARF-1))) - -#define RACEMASK_HORDE (RACEMASK_ALL_PLAYABLE & ~RACEMASK_ALLIANCE) - // Class value is index in ChrClasses.dbc enum Classes : uint8 { diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index b3cf053f8e2..5719c541406 100644 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -123,7 +123,7 @@ Quest::Quest(Field* questRecord) SoundTurnIn = questRecord[105].GetUInt32(); AreaGroupID = questRecord[106].GetUInt32(); LimitTime = questRecord[107].GetUInt32(); - AllowableRaces = questRecord[108].GetUInt64(); + AllowableRaces.RawValue = questRecord[108].GetUInt64(); TreasurePickerID = questRecord[109].GetInt32(); Expansion = questRecord[110].GetInt32(); ManagedWorldStateID = questRecord[111].GetInt32(); diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index ca0e5db9784..aefd9509f6b 100644 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -21,6 +21,7 @@ #include "Common.h" #include "DBCEnums.h" #include "DatabaseEnvFwd.h" +#include "RaceMask.h" #include "SharedDefines.h" #include "WorldPacket.h" #include <vector> @@ -375,7 +376,7 @@ class TC_GAME_API Quest int32 GetQuestMaxScalingLevel() const { return MaxScalingLevel; } uint32 GetQuestInfoID() const { return QuestInfoID; } uint32 GetAllowableClasses() const { return AllowableClasses; } - uint64 GetAllowableRaces() const { return AllowableRaces; } + Trinity::RaceMask<uint64> GetAllowableRaces() const { return AllowableRaces; } uint32 GetRequiredSkill() const { return RequiredSkillId; } uint32 GetRequiredSkillValue() const { return RequiredSkillPoints; } uint32 GetRequiredMinRepFaction() const { return RequiredMinRepFaction; } @@ -541,7 +542,7 @@ class TC_GAME_API Quest uint32 SoundTurnIn; uint32 AreaGroupID; uint32 LimitTime; - uint64 AllowableRaces; + Trinity::RaceMask<uint64> AllowableRaces; int32 TreasurePickerID; int32 Expansion; int32 ManagedWorldStateID; diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp index aa5738f56a9..1c362984ecc 100644 --- a/src/server/game/Reputation/ReputationMgr.cpp +++ b/src/server/game/Reputation/ReputationMgr.cpp @@ -92,12 +92,12 @@ int32 ReputationMgr::GetBaseReputation(FactionEntry const* factionEntry) const if (!factionEntry) return 0; - uint64 raceMask = _player->getRaceMask(); + uint8 race = _player->getRace(); uint32 classMask = _player->getClassMask(); for (int i=0; i < 4; i++) { - if ((factionEntry->ReputationRaceMask[i] & raceMask || - (factionEntry->ReputationRaceMask[i] == 0 && + if ((factionEntry->ReputationRaceMask[i].HasRace(race) || + (!factionEntry->ReputationRaceMask[i] && factionEntry->ReputationClassMask[i] != 0)) && (factionEntry->ReputationClassMask[i] & classMask || factionEntry->ReputationClassMask[i] == 0)) @@ -151,12 +151,12 @@ uint32 ReputationMgr::GetDefaultStateFlags(FactionEntry const* factionEntry) con if (!factionEntry) return 0; - uint64 raceMask = _player->getRaceMask(); + uint8 race = _player->getRace(); uint32 classMask = _player->getClassMask(); for (int i=0; i < 4; i++) { - if ((factionEntry->ReputationRaceMask[i] & raceMask || - (factionEntry->ReputationRaceMask[i] == 0 && + if ((factionEntry->ReputationRaceMask[i].HasRace(race) || + (!factionEntry->ReputationRaceMask[i] && factionEntry->ReputationClassMask[i] != 0)) && (factionEntry->ReputationClassMask[i] & classMask || factionEntry->ReputationClassMask[i] == 0)) @@ -396,7 +396,7 @@ void ReputationMgr::SetVisible(FactionTemplateEntry const* factionTemplateEntry) if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionTemplateEntry->Faction)) // Never show factions of the opposing team - if (!(factionEntry->ReputationRaceMask[1] & _player->getRaceMask() && factionEntry->ReputationBase[1] == Reputation_Bottom)) + if (!(factionEntry->ReputationRaceMask[1].HasRace(_player->getRace()) && factionEntry->ReputationBase[1] == Reputation_Bottom)) SetVisible(factionEntry); } diff --git a/src/server/game/Server/Packets/CharacterPackets.h b/src/server/game/Server/Packets/CharacterPackets.h index f8e5d245aab..c28e6e728e0 100644 --- a/src/server/game/Server/Packets/CharacterPackets.h +++ b/src/server/game/Server/Packets/CharacterPackets.h @@ -23,6 +23,7 @@ #include "Optional.h" #include "PacketUtilities.h" #include "Position.h" +#include "RaceMask.h" #include "SharedDefines.h" #include "UnitDefines.h" #include <array> diff --git a/src/server/game/Server/Packets/GuildPackets.cpp b/src/server/game/Server/Packets/GuildPackets.cpp index a64deeaec42..aae54fca389 100644 --- a/src/server/game/Server/Packets/GuildPackets.cpp +++ b/src/server/game/Server/Packets/GuildPackets.cpp @@ -523,7 +523,7 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Guild::GuildRewardItem co data << uint32(rewardItem.ItemID); data << uint32(rewardItem.Unk4); data << uint32(rewardItem.AchievementsRequired.size()); - data << uint64(rewardItem.RaceMask); + data << uint64(rewardItem.RaceMask.RawValue); data << int32(rewardItem.MinGuildLevel); data << int32(rewardItem.MinGuildRep); data << uint64(rewardItem.Cost); diff --git a/src/server/game/Server/Packets/GuildPackets.h b/src/server/game/Server/Packets/GuildPackets.h index 1175e1f9785..8d5e28a2b18 100644 --- a/src/server/game/Server/Packets/GuildPackets.h +++ b/src/server/game/Server/Packets/GuildPackets.h @@ -686,7 +686,7 @@ namespace WorldPackets uint32 ItemID = 0; uint32 Unk4 = 0; std::vector<uint32> AchievementsRequired; - uint64 RaceMask = 0; + Trinity::RaceMask<uint64> RaceMask = { 0 }; int32 MinGuildLevel = 0; int32 MinGuildRep = 0; uint64 Cost = 0; diff --git a/src/server/game/Server/Packets/InspectPackets.h b/src/server/game/Server/Packets/InspectPackets.h index c24be5f6faa..eb62955cfb7 100644 --- a/src/server/game/Server/Packets/InspectPackets.h +++ b/src/server/game/Server/Packets/InspectPackets.h @@ -21,6 +21,7 @@ #include "DBCEnums.h" #include "ItemPacketsCommon.h" #include "ObjectGuid.h" +#include "RaceMask.h" #include "SharedDefines.h" class Item; diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp index c7e3939ceb3..e6881ac5cbe 100644 --- a/src/server/game/Server/Packets/QuestPackets.cpp +++ b/src/server/game/Server/Packets/QuestPackets.cpp @@ -143,7 +143,7 @@ WorldPacket const* WorldPackets::Quest::QueryQuestInfoResponse::Write() _worldPacket << int32(Info.TimeAllowed); _worldPacket << uint32(Info.Objectives.size()); - _worldPacket << uint64(Info.AllowableRaces); + _worldPacket << uint64(Info.AllowableRaces.RawValue); _worldPacket << int32(Info.TreasurePickerID); _worldPacket << int32(Info.Expansion); _worldPacket << int32(Info.ManagedWorldStateID); diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h index a0184abed4e..01c0cbc227c 100644 --- a/src/server/game/Server/Packets/QuestPackets.h +++ b/src/server/game/Server/Packets/QuestPackets.h @@ -138,7 +138,7 @@ namespace WorldPackets float POIx = 0.0f; float POIy = 0.0f; int32 POIPriority = 0; - uint64 AllowableRaces = UI64LIT(0xFFFFFFFFFFFFFFFF); + Trinity::RaceMask<uint64> AllowableRaces = { UI64LIT(0xFFFFFFFFFFFFFFFF) }; std::string LogTitle; std::string LogDescription; std::string QuestDescription; diff --git a/src/server/game/Server/Packets/WhoPackets.cpp b/src/server/game/Server/Packets/WhoPackets.cpp index 1cac68cf088..8de2b9a935b 100644 --- a/src/server/game/Server/Packets/WhoPackets.cpp +++ b/src/server/game/Server/Packets/WhoPackets.cpp @@ -55,7 +55,7 @@ ByteBuffer& operator>>(ByteBuffer& data, WorldPackets::Who::WhoRequest& request) { data >> request.MinLevel; data >> request.MaxLevel; - data >> request.RaceFilter; + data >> request.RaceFilter.RawValue; data >> request.ClassFilter; uint32 nameLength = data.ReadBits(6); diff --git a/src/server/game/Server/Packets/WhoPackets.h b/src/server/game/Server/Packets/WhoPackets.h index cc6f07f0b54..7c3fc3bae48 100644 --- a/src/server/game/Server/Packets/WhoPackets.h +++ b/src/server/game/Server/Packets/WhoPackets.h @@ -21,6 +21,7 @@ #include "Packet.h" #include "ObjectGuid.h" #include "QueryPackets.h" +#include "RaceMask.h" namespace WorldPackets { @@ -66,7 +67,7 @@ namespace WorldPackets std::string VirtualRealmName; std::string Guild; std::string GuildVirtualRealmName; - int64 RaceFilter = SI64LIT(0); + Trinity::RaceMask<int64> RaceFilter = { SI64LIT(0) }; int32 ClassFilter = -1; std::vector<WhoWord> Words; bool ShowEnemies = false; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index cbb035a4b3c..ab73f8338a2 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -621,7 +621,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 return false; if (raceMask) // is not expected race - if (!player || !(raceMask & player->getRaceMask())) + if (!player || !raceMask.HasRace(player->getRace())) return false; if (areaId) // is not in expected zone @@ -2070,7 +2070,7 @@ void SpellMgr::LoadSpellAreas() spellArea.questEndStatus = fields[4].GetUInt32(); spellArea.questEnd = fields[5].GetUInt32(); spellArea.auraSpell = fields[6].GetInt32(); - spellArea.raceMask = fields[7].GetUInt64(); + spellArea.raceMask.RawValue = fields[7].GetUInt64(); spellArea.gender = Gender(fields[8].GetUInt8()); spellArea.flags = fields[9].GetUInt8(); @@ -2189,9 +2189,9 @@ void SpellMgr::LoadSpellAreas() } } - if (spellArea.raceMask && (spellArea.raceMask & RACEMASK_ALL_PLAYABLE) == 0) + if (spellArea.raceMask && (spellArea.raceMask.RawValue & RACEMASK_ALL_PLAYABLE) == 0) { - TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_area` has wrong race mask (" UI64FMTD ") requirement.", spell, spellArea.raceMask); + TC_LOG_ERROR("sql.sql", "The spell %u listed in `spell_area` has wrong race mask (" UI64FMTD ") requirement.", spell, spellArea.raceMask.RawValue); continue; } diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index ed79b12eef8..710d4aadf08 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -23,6 +23,7 @@ #include "Define.h" #include "Duration.h" #include "IteratorPair.h" +#include "RaceMask.h" #include "SharedDefines.h" #include "Util.h" @@ -474,7 +475,7 @@ struct TC_GAME_API SpellArea uint32 questStart; // quest start (quest must be active or rewarded for spell apply) uint32 questEnd; // quest end (quest must not be rewarded for spell apply) int32 auraSpell; // spell aura must be applied for spell apply)if possitive) and it must not be applied in other case - uint64 raceMask; // can be applied only to races + Trinity::RaceMask<uint64> raceMask; // can be applied only to races Gender gender; // can be applied only to gender uint32 questStartStatus; // QuestStatus that quest_start must have in order to keep the spell uint32 questEndStatus; // QuestStatus that the quest_end must have in order to keep the spell (if the quest_end's status is different than this, the spell will be dropped) diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp index fde54f3a1cf..f0c6981f0f0 100644 --- a/src/server/scripts/Commands/cs_learn.cpp +++ b/src/server/scripts/Commands/cs_learn.cpp @@ -432,7 +432,7 @@ public: continue; // skip racial skills - if (skillLine->RaceMask != 0) + if (skillLine->RaceMask) continue; // skip wrong class skills |