revert(Core): ChrRace.dbc full implementation (#16114)

* revert (core): ChrRace.dbc full implementation

we revert this due to several issues arrising. Although the dbc reading is done in full and correctly. Azerothcore relied on the original handling (althought not propper) for so long that  there is

* revert

* Update remove_charrace_dbc.sql

* Update remove_charrace_dbc.sql

* Update remove_charrace_dbc.sql
This commit is contained in:
M'Dic
2023-04-29 07:23:11 -04:00
committed by GitHub
parent 43103b6145
commit 7e58650cf5
26 changed files with 225 additions and 165 deletions

View File

@@ -517,10 +517,9 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
return false;
}
setRace(createInfo->Race);
setClass(createInfo->Class);
setGender(Gender(createInfo->Gender));
setPowerType(Powers(powertype), false);
uint32 RaceClassGender = (createInfo->Race) | (createInfo->Class << 8) | (createInfo->Gender << 16);
SetUInt32Value(UNIT_FIELD_BYTES_0, (RaceClassGender | (powertype << 24)));
InitDisplayIds();
if (sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP)
{
@@ -725,7 +724,7 @@ bool Player::StoreNewItemInBestSlots(uint32 titem_id, uint32 titem_amount)
}
// item can't be added
LOG_ERROR("entities.player", "STORAGE: Can't equip or store initial item {} for race {} class {}, error msg = {}", titem_id, getRace(), getClass(), msg);
LOG_ERROR("entities.player", "STORAGE: Can't equip or store initial item {} for race {} class {}, error msg = {}", titem_id, getRace(true), getClass(), msg);
return false;
}
@@ -2225,7 +2224,7 @@ void Player::SetGameMaster(bool on)
SetPhaseMask(newPhase, false);
m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON;
SetFactionForRace(getRace());
SetFactionForRace(getRace(true));
RemovePlayerFlag(PLAYER_FLAGS_GM);
RemoveUnitFlag2(UNIT_FLAG2_ALLOW_CHEAT_SPELLS);
@@ -2436,7 +2435,7 @@ void Player::GiveLevel(uint8 level)
guild->UpdateMemberData(this, GUILD_MEMBER_DATA_LEVEL, level);
PlayerLevelInfo info;
sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), level, &info);
sObjectMgr->GetPlayerLevelInfo(getRace(true), getClass(), level, &info);
PlayerClassLevelInfo classInfo;
sObjectMgr->GetPlayerClassLevelInfo(getClass(), level, &classInfo);
@@ -2552,7 +2551,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
sObjectMgr->GetPlayerClassLevelInfo(getClass(), GetLevel(), &classInfo);
PlayerLevelInfo info;
sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), GetLevel(), &info);
sObjectMgr->GetPlayerLevelInfo(getRace(true), getClass(), GetLevel(), &info);
uint32 maxPlayerLevel = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
sScriptMgr->OnSetMaxLevel(this, maxPlayerLevel);
@@ -4339,7 +4338,7 @@ void Player::BuildPlayerRepop()
WorldPacket data(SMSG_PRE_RESURRECT, GetPackGUID().size());
data << GetPackGUID();
GetSession()->SendPacket(&data);
if (getRace() == RACE_NIGHTELF)
if (getRace(true) == RACE_NIGHTELF)
{
CastSpell(this, 20584, true);
}
@@ -5743,19 +5742,19 @@ TeamId Player::TeamIdForRace(uint8 race)
{
if (ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race))
{
switch (rEntry->BaseLanguage)
switch (rEntry->TeamID)
{
case 1:
return HORDE_FACTION;
return TEAM_HORDE;
case 7:
return ALLIANCE_FACTION;
return TEAM_ALLIANCE;
}
LOG_ERROR("entities.player", "Race ({}) has wrong teamid ({}) in DBC: wrong DBC files?", uint32(race), rEntry->BaseLanguage);
LOG_ERROR("entities.player", "Race ({}) has wrong teamid ({}) in DBC: wrong DBC files?", uint32(race), rEntry->TeamID);
}
else
LOG_ERROR("entities.player", "Race ({}) not found in DBC: wrong DBC files?", uint32(race));
return ALLIANCE_FACTION;
return TEAM_ALLIANCE;
}
void Player::SetFactionForRace(uint8 race)
@@ -5764,7 +5763,7 @@ void Player::SetFactionForRace(uint8 race)
sScriptMgr->OnPlayerUpdateFaction(this);
if (GetTeamId() != GetTeamId())
if (GetTeamId(true) != GetTeamId())
return;
ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(race);
@@ -5882,7 +5881,7 @@ void Player::RewardReputation(Unit* victim, float rate)
ChampioningFaction = GetChampioningFaction();
}
TeamId teamId = GetTeamId(); // Always check player original reputation when rewarding
TeamId teamId = GetTeamId(true); // Always check player original reputation when rewarding
if (Rep->RepFaction1 && (!Rep->TeamDependent || teamId == TEAM_ALLIANCE))
{
@@ -6066,7 +6065,7 @@ bool Player::RewardHonor(Unit* uVictim, uint32 groupsize, int32 honor, bool awar
ApplyModUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 1, true);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, victim->getClass());
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, victim->getRace());
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, victim->getRace(true));
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, GetAreaId());
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, victim);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, victim);
@@ -10271,7 +10270,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
// only one mount ID for both sides. Probably not good to use 315 in case DBC nodes
// change but I couldn't find a suitable alternative. OK to use class because only DK
// can use this taxi.
uint32 mount_display_id = sObjectMgr->GetTaxiMountDisplayId(sourcenode, GetTeamId(), npc == nullptr || (sourcenode == 315 && getClass() == CLASS_DEATH_KNIGHT));
uint32 mount_display_id = sObjectMgr->GetTaxiMountDisplayId(sourcenode, GetTeamId(true), npc == nullptr || (sourcenode == 315 && getClass() == CLASS_DEATH_KNIGHT));
// in spell case allow 0 model
if ((mount_display_id == 0 && spellid == 0) || sourcepath == 0)
@@ -10366,7 +10365,7 @@ void Player::ContinueTaxiFlight()
LOG_DEBUG("entities.unit", "WORLD: Restart character {} taxi flight", GetGUID().ToString());
uint32 mountDisplayId = sObjectMgr->GetTaxiMountDisplayId(sourceNode, GetTeamId(), true);
uint32 mountDisplayId = sObjectMgr->GetTaxiMountDisplayId(sourceNode, GetTeamId(true), true);
if (!mountDisplayId)
return;
@@ -10535,7 +10534,7 @@ void Player::InitDataForForm(bool reapplyMods)
void Player::InitDisplayIds()
{
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(true), getClass());
if (!info)
{
LOG_ERROR("entities.player", "Player {} has incorrect race/class pair. Can't init display ids.", GetGUID().ToString());
@@ -10656,7 +10655,7 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
return false;
}
if (!IsGameMaster() && ((pProto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && GetTeamId() == TEAM_ALLIANCE) || (pProto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && GetTeamId() == TEAM_HORDE)))
if (!IsGameMaster() && ((pProto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && GetTeamId(true) == TEAM_ALLIANCE) || (pProto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && GetTeamId(true) == TEAM_HORDE)))
{
return false;
}
@@ -11318,7 +11317,7 @@ void Player::ReportedAfkBy(Player* reporter)
WorldLocation Player::GetStartPosition() const
{
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(true), getClass());
uint32 mapId = info->mapId;
if (getClass() == CLASS_DEATH_KNIGHT && HasSpell(50977))
return WorldLocation(0, 2352.0f, -5709.0f, 154.5f, 0.0f);
@@ -14600,7 +14599,7 @@ void Player::_SaveCharacter(bool create, CharacterDatabaseTransaction trans)
stmt->SetData(index++, GetGUID().GetCounter());
stmt->SetData(index++, GetSession()->GetAccountId());
stmt->SetData(index++, GetName());
stmt->SetData(index++, getRace());
stmt->SetData(index++, getRace(true));
stmt->SetData(index++, getClass());
stmt->SetData(index++, GetByteValue(PLAYER_BYTES_3, 0)); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
stmt->SetData(index++, GetLevel());
@@ -14718,7 +14717,7 @@ void Player::_SaveCharacter(bool create, CharacterDatabaseTransaction trans)
// Update query
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER);
stmt->SetData(index++, GetName());
stmt->SetData(index++, getRace());
stmt->SetData(index++, getRace(true));
stmt->SetData(index++, getClass());
stmt->SetData(index++, GetByteValue(PLAYER_BYTES_3, 0)); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
stmt->SetData(index++, GetLevel());

View File

@@ -2056,9 +2056,9 @@ public:
void CheckAreaExploreAndOutdoor();
static TeamId TeamIdForRace(uint8 race);
[[nodiscard]] uint32 GetTeam() const { return m_team; }
[[nodiscard]] TeamId GetTeamId() const { return m_team == ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE; }
[[nodiscard]] TeamId GetTeamId(bool original = false) const { return original ? TeamIdForRace(getRace(true)) : m_team; };
void SetFactionForRace(uint8 race);
void setTeamId(TeamId teamid) { m_team = teamid; };
void InitDisplayIds();
@@ -2709,7 +2709,7 @@ public:
void outDebugValues() const;
ObjectGuid m_lootGuid;
uint32 m_team;
TeamId m_team;
uint32 m_nextSave; // pussywizard
uint16 m_additionalSaveTimer; // pussywizard
uint8 m_additionalSaveMask; // pussywizard

View File

@@ -2310,12 +2310,12 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const
return EQUIP_ERR_ITEM_NOT_FOUND;
}
if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetTeamId() != TEAM_HORDE)
if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetTeamId(true) != TEAM_HORDE)
{
return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
}
if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetTeamId() != TEAM_ALLIANCE)
if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetTeamId(true) != TEAM_ALLIANCE)
{
return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
}
@@ -5076,7 +5076,7 @@ bool Player::LoadFromDB(ObjectGuid playerGuid, CharacterDatabaseQueryHolder cons
//Need to call it to initialize m_team (m_team can be calculated from race)
//Other way is to saves m_team into characters table.
SetFactionForRace(getRace());
SetFactionForRace(getRace(true));
// pussywizard: create empty instance bind containers if necessary
sInstanceSaveMgr->PlayerCreateBoundInstancesMaps(playerGuid);
@@ -5249,7 +5249,7 @@ bool Player::LoadFromDB(ObjectGuid playerGuid, CharacterDatabaseQueryHolder cons
else if (!taxi_nodes.empty())
{
instanceId = 0;
if (!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes, GetTeamId()))
if (!m_taxi.LoadTaxiDestinationsFromString(taxi_nodes, GetTeamId(true)))
{
// xinef: could no load valid data for taxi, relocate to homebind and clear
m_taxi.ClearTaxiDestinations();
@@ -5311,7 +5311,7 @@ bool Player::LoadFromDB(ObjectGuid playerGuid, CharacterDatabaseQueryHolder cons
map = sMapMgr->CreateMap(mapId, this);
if (!map)
{
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(true), getClass());
mapId = info->mapId;
Relocate(info->positionX, info->positionY, info->positionZ, 0.0f);
LOG_ERROR("entities.player", "Player (guidlow {}) have invalid coordinates (X: {} Y: {} Z: {} O: {}). Teleport to default race/class locations.", guid, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation());
@@ -6780,7 +6780,7 @@ bool Player::Satisfy(DungeonProgressionRequirements const* ar, uint32 target_map
missingItems = &missingLeaderItems;
}
if (itemRequirement->faction == TEAM_NEUTRAL || itemRequirement->faction == checkPlayer->GetTeamId())
if (itemRequirement->faction == TEAM_NEUTRAL || itemRequirement->faction == checkPlayer->GetTeamId(true))
{
if (!checkPlayer->HasItemCount(itemRequirement->id, 1))
{
@@ -6802,7 +6802,7 @@ bool Player::Satisfy(DungeonProgressionRequirements const* ar, uint32 target_map
missingAchievements = &missingLeaderAchievements;
}
if (achievementRequirement->faction == TEAM_NEUTRAL || achievementRequirement->faction == GetTeamId())
if (achievementRequirement->faction == TEAM_NEUTRAL || achievementRequirement->faction == GetTeamId(true))
{
if (!checkPlayer || !checkPlayer->HasAchieved(achievementRequirement->id))
{
@@ -6824,7 +6824,7 @@ bool Player::Satisfy(DungeonProgressionRequirements const* ar, uint32 target_map
missingQuests = &missingLeaderQuests;
}
if (questRequirement->faction == TEAM_NEUTRAL || questRequirement->faction == checkPlayer->GetTeamId())
if (questRequirement->faction == TEAM_NEUTRAL || questRequirement->faction == checkPlayer->GetTeamId(true))
{
if (!checkPlayer->GetQuestRewardStatus(questRequirement->id))
{
@@ -7005,7 +7005,7 @@ bool Player::CheckInstanceCount(uint32 instanceId) const
bool Player::_LoadHomeBind(PreparedQueryResult result)
{
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(true), getClass());
if (!info)
{
LOG_ERROR("entities.player", "Player (Name {}) has incorrect race/class pair. Can't be loaded.", GetName());

View File

@@ -1195,7 +1195,7 @@ void Player::UpdateArea(uint32 newArea)
else
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
uint32 const areaRestFlag = (GetTeamId() == TEAM_ALLIANCE)
uint32 const areaRestFlag = (GetTeamId(true) == TEAM_ALLIANCE)
? AREA_FLAG_REST_ZONE_ALLIANCE
: AREA_FLAG_REST_ZONE_HORDE;
if (area && area->flags & areaRestFlag)
@@ -1255,12 +1255,12 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
{
case AREATEAM_ALLY:
pvpInfo.IsInHostileArea =
GetTeamId() != TEAM_ALLIANCE &&
GetTeamId(true) != TEAM_ALLIANCE &&
(sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL);
break;
case AREATEAM_HORDE:
pvpInfo.IsInHostileArea =
GetTeamId() != TEAM_HORDE &&
GetTeamId(true) != TEAM_HORDE &&
(sWorld->IsPvPRealm() || zone->flags & AREA_FLAG_CAPITAL);
break;
case AREATEAM_NONE:

View File

@@ -9974,15 +9974,9 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit* victim, uint32 /*damage*/, Au
return true;
}
void Unit::setPowerType(Powers new_powertype, bool sendUpdate/* = true*/)
void Unit::setPowerType(Powers new_powertype)
{
if (getPowerType() == new_powertype)
return;
SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_POWER_TYPE, new_powertype);
if (!sendUpdate)
return;
SetByteValue(UNIT_FIELD_BYTES_0, 3, new_powertype);
if (GetTypeId() == TYPEID_PLAYER)
{
@@ -15185,10 +15179,7 @@ uint32 Unit::GetCreatureType() const
if (ssEntry && ssEntry->creatureType > 0)
return ssEntry->creatureType;
else
{
ChrRacesEntry const* raceEntry = sChrRacesStore.AssertEntry(getRace());
return raceEntry->CreatureType;
}
return CREATURE_TYPE_HUMANOID;
}
else
return ToCreature()->GetCreatureTemplate()->type;
@@ -21292,6 +21283,25 @@ void Unit::BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCooldowns c
}
}
uint8 Unit::getRace(bool original) const
{
if (GetTypeId() == TYPEID_PLAYER)
{
if (original)
return m_realRace;
else
return m_race;
}
return GetByteValue(UNIT_FIELD_BYTES_0, 0);
}
void Unit::setRace(uint8 race)
{
if (GetTypeId() == TYPEID_PLAYER)
m_race = race;
}
// Check if unit in combat with specific unit
bool Unit::IsInCombatWith(Unit const* who) const
{

View File

@@ -39,14 +39,6 @@
#define BASE_MAXDAMAGE 2.0f
#define BASE_ATTACK_TIME 2000
enum UnitBytes0Offsets : uint8
{
UNIT_BYTES_0_OFFSET_RACE = 0,
UNIT_BYTES_0_OFFSET_CLASS = 1,
UNIT_BYTES_0_OFFSET_GENDER = 2,
UNIT_BYTES_0_OFFSET_POWER_TYPE = 3
};
enum UnitBytes1Offsets : uint8
{
UNIT_BYTES_1_OFFSET_STAND_STATE = 0,
@@ -1452,21 +1444,12 @@ public:
[[nodiscard]] uint8 GetLevel() const { return getLevel(); }
uint8 getLevelForTarget(WorldObject const* /*target*/) const override { return GetLevel(); }
void SetLevel(uint8 lvl, bool showLevelChange = true);
[[nodiscard]] uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE); }
void setRace(uint8 race) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE, race); }
[[nodiscard]] uint32 getRaceMask() const { return 1 << (getRace() - 1); }
[[nodiscard]] uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS); }
void setClass(uint8 classId) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, classId); }
[[nodiscard]] uint8 GetRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE); }
void SetRace(uint8 race) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE, race); }
[[nodiscard]] uint32 GetRaceMask() const { return 1 << (getRace() - 1); }
[[nodiscard]] uint8 GetClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS); }
void SetClass(uint8 classId) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, classId); }
[[nodiscard]] uint8 getRace(bool original = false) const;
void setRace(uint8 race);
[[nodiscard]] uint32 getRaceMask() const { return 1 << (getRace(true) - 1); }
[[nodiscard]] uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); }
[[nodiscard]] uint32 getClassMask() const { return 1 << (getClass() - 1); }
Gender getGender() const { return Gender(GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER)); }
void setGender(Gender gender) { SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, gender); }
virtual Gender GetNativeGender() const { return getGender(); }
virtual void SetNativeGender(Gender gender) { setGender(gender); }
[[nodiscard]] uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); }
[[nodiscard]] float GetStat(Stats stat) const { return float(GetUInt32Value(static_cast<uint16>(UNIT_FIELD_STAT0) + stat)); }
void SetStat(Stats stat, int32 val) { SetStatInt32Value(static_cast<uint16>(UNIT_FIELD_STAT0) + stat, val); }
@@ -1497,8 +1480,8 @@ public:
int32 ModifyHealth(int32 val);
int32 GetHealthGain(int32 dVal);
[[nodiscard]] Powers getPowerType() const { return Powers(GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_POWER_TYPE)); }
void setPowerType(Powers power, bool sendUpdate = true);
[[nodiscard]] Powers getPowerType() const { return Powers(GetByteValue(UNIT_FIELD_BYTES_0, 3)); }
void setPowerType(Powers power);
[[nodiscard]] uint32 GetPower(Powers power) const { return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_POWER1) + power); }
[[nodiscard]] uint32 GetMaxPower(Powers power) const { return GetUInt32Value(static_cast<uint16>(UNIT_FIELD_MAXPOWER1) + power); }
void SetPower(Powers power, uint32 val, bool withPowerUpdate = true, bool fromRegenerate = false);