Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2024-02-11 23:45:22 +08:00
54 changed files with 1943 additions and 1547 deletions

View File

@@ -553,7 +553,7 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
// set starting level
uint32 start_level = getClass() != CLASS_DEATH_KNIGHT
uint32 start_level = !IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_INIT)
? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL)
: sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
@@ -568,7 +568,7 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
InitRunes();
SetUInt32Value(PLAYER_FIELD_COINAGE, getClass() != CLASS_DEATH_KNIGHT
SetUInt32Value(PLAYER_FIELD_COINAGE, !IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_INIT)
? sWorld->getIntConfig(CONFIG_START_PLAYER_MONEY)
: sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_MONEY));
SetHonorPoints(sWorld->getIntConfig(CONFIG_START_HONOR_POINTS));
@@ -587,13 +587,13 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
InitPrimaryProfessions(); // to max set before any spell added
// apply original stats mods before spell loading or item equipment that call before equip _RemoveStatsMods()
if (getPowerType() == POWER_MANA)
if (HasActivePowerType(POWER_MANA))
{
UpdateMaxPower(POWER_MANA); // Update max Mana (for add bonus from intellect)
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
}
if (getPowerType() == POWER_RUNIC_POWER)
if (HasActivePowerType(POWER_RUNIC_POWER))
{
SetPower(POWER_RUNE, 8);
SetMaxPower(POWER_RUNE, 8);
@@ -633,7 +633,7 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
switch (iProto->Spells[0].SpellCategory)
{
case SPELL_CATEGORY_FOOD: // food
count = getClass() == CLASS_DEATH_KNIGHT ? 10 : 4;
count = IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_INIT) ? 10 : 4;
break;
case SPELL_CATEGORY_DRINK: // drink
count = 2;
@@ -1269,6 +1269,15 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
return true;
}
bool Player::IsClass(Classes unitClass, ClassContext context) const
{
Optional<bool> scriptResult = sScriptMgr->OnPlayerIsClass(this, unitClass, context);
if (scriptResult != std::nullopt)
return *scriptResult;
else
return (getClass() == unitClass);
}
void Player::ToggleAFK()
{
ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK);
@@ -1460,7 +1469,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
}
else
{
if (getClass() == CLASS_DEATH_KNIGHT && GetMapId() == 609 && !IsGameMaster() && !HasSpell(50977))
if (IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_TELEPORT) && GetMapId() == 609 && !IsGameMaster() && !HasSpell(50977))
{
SendTransferAborted(mapid, TRANSFER_ABORT_UNIQUE_MESSAGE, 1);
return false;
@@ -1745,7 +1754,7 @@ void Player::RegenerateAll()
Regenerate(POWER_MANA);
// Runes act as cooldowns, and they don't need to send any data
if (getClass() == CLASS_DEATH_KNIGHT)
if (IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_ABILITY))
for (uint8 i = 0; i < MAX_RUNES; ++i)
{
// xinef: implement grace
@@ -1775,7 +1784,7 @@ void Player::RegenerateAll()
}
Regenerate(POWER_RAGE);
if (getClass() == CLASS_DEATH_KNIGHT)
if (IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_ABILITY))
Regenerate(POWER_RUNIC_POWER);
m_regenTimerCount -= 2000;
@@ -2019,22 +2028,21 @@ void Player::RegenerateHealth()
void Player::ResetAllPowers()
{
SetHealth(GetMaxHealth());
switch (getPowerType())
if (HasActivePowerType(POWER_MANA))
{
case POWER_MANA:
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
break;
case POWER_RAGE:
SetPower(POWER_RAGE, 0);
break;
case POWER_ENERGY:
SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY));
break;
case POWER_RUNIC_POWER:
SetPower(POWER_RUNIC_POWER, 0);
break;
default:
break;
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
}
if (HasActivePowerType(POWER_RAGE))
{
SetPower(POWER_RAGE, 0);
}
if (HasActivePowerType(POWER_ENERGY))
{
SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY));
}
if (HasActivePowerType(POWER_RUNIC_POWER))
{
SetPower(POWER_RUNIC_POWER, 0);
}
}
@@ -2107,7 +2115,7 @@ Creature* Player::GetNPCIfCanInteractWith(ObjectGuid guid, uint32 npcflagmask)
// pussywizard: many npcs have missing conditions for class training and rogue trainer can for eg. train dual wield to a shaman :/ too many to change in sql and watch in the future
// pussywizard: this function is not used when talking, but when already taking action (buy spell, reset talents, show spell list)
if (npcflagmask & (UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_TRAINER_CLASS) && creature->GetCreatureTemplate()->trainer_type == TRAINER_TYPE_CLASS && getClass() != creature->GetCreatureTemplate()->trainer_class)
if (npcflagmask & (UNIT_NPC_FLAG_TRAINER | UNIT_NPC_FLAG_TRAINER_CLASS) && creature->GetCreatureTemplate()->trainer_type == TRAINER_TYPE_CLASS && !IsClass((Classes)creature->GetCreatureTemplate()->trainer_class, CLASS_CONTEXT_CLASS_TRAINER))
return nullptr;
return creature;
@@ -2714,6 +2722,14 @@ void Player::InitStatsForLevel(bool reapplyMods)
pet->SynchronizeLevelWithOwner();
}
bool Player::HasActivePowerType(Powers power)
{
if (sScriptMgr->OnPlayerHasActivePowerType(this, power))
return true;
else
return (getPowerType() == power);
}
void Player::SendInitialSpells()
{
uint32 curTime = GameTime::GetGameTimeMS().count();
@@ -6388,7 +6404,7 @@ void Player::DuelComplete(DuelCompleteType type)
opponent->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL, 1);
// Credit for quest Death's Challenge
if (getClass() == CLASS_DEATH_KNIGHT && opponent->GetQuestStatus(12733) == QUEST_STATUS_INCOMPLETE)
if (IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_QUEST) && opponent->GetQuestStatus(12733) == QUEST_STATUS_INCOMPLETE)
{
opponent->CastSpell(opponent, 52994, true);
}
@@ -6784,7 +6800,7 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
}
// Druids get feral AP bonus from weapon dps (also use DPS from ScalingStatValue)
if (getClass() == CLASS_DRUID)
if (IsClass(CLASS_DRUID, CLASS_CONTEXT_STATS))
{
int32 dpsMod = 0;
int32 feral_bonus = 0;
@@ -9841,7 +9857,7 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply)
if (apply)
{
m_spellMods[mod->op].push_back(mod);
if (getClass() == CLASS_MAGE)
if (IsClass(CLASS_MAGE, CLASS_CONTEXT_ABILITY))
m_spellMods[mod->op].sort(MageSpellModPred());
else
m_spellMods[mod->op].sort(SpellModPred());
@@ -10275,7 +10291,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(true), npc == nullptr || (sourcenode == 315 && getClass() == CLASS_DEATH_KNIGHT));
uint32 mount_display_id = sObjectMgr->GetTaxiMountDisplayId(sourcenode, GetTeamId(true), npc == nullptr || (sourcenode == 315 && IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_TAXI)));
// in spell case allow 0 model
if ((mount_display_id == 0 && spellid == 0) || sourcepath == 0)
@@ -11324,7 +11340,7 @@ WorldLocation Player::GetStartPosition() const
{
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(true), getClass());
uint32 mapId = info->mapId;
if (getClass() == CLASS_DEATH_KNIGHT && HasSpell(50977))
if (IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_INIT) && HasSpell(50977))
return WorldLocation(0, 2352.0f, -5709.0f, 154.5f, 0.0f);
return WorldLocation(mapId, info->positionX, info->positionY, info->positionZ, 0);
}
@@ -11818,7 +11834,7 @@ void Player::LearnDefaultSkill(uint32 skillId, uint16 rank)
{
skillValue = maxValue;
}
else if (getClass() == CLASS_DEATH_KNIGHT)
else if (IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_SKILL))
{
skillValue = std::min(std::max<uint16>({ 1, uint16((GetLevel() - 1) * 5) }), maxValue);
}
@@ -11851,7 +11867,7 @@ void Player::LearnDefaultSkill(uint32 skillId, uint16 rank)
{
skillValue = maxValue;
}
else if (getClass() == CLASS_DEATH_KNIGHT)
else if (IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_SKILL))
{
skillValue = std::min(std::max<uint16>({ uint16(1), uint16((GetLevel() - 1) * 5) }), maxValue);
}
@@ -13376,7 +13392,7 @@ static RuneType runeSlotTypes[MAX_RUNES] =
void Player::InitRunes()
{
if (getClass() != CLASS_DEATH_KNIGHT)
if (!IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_ABILITY))
return;
m_runes = new Runes;
@@ -13542,7 +13558,7 @@ uint32 Player::CalculateTalentsPoints() const
uint32 base_talent = GetLevel() < 10 ? 0 : GetLevel() - 9;
uint32 talentPointsForLevel = 0;
if (getClass() != CLASS_DEATH_KNIGHT || GetMapId() != 609)
if (!IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_TALENT_POINT_CALC) || GetMapId() != 609)
{
talentPointsForLevel = base_talent;
}
@@ -14174,19 +14190,21 @@ void Player::ResummonPetTemporaryUnSummonedIfAny()
bool Player::CanResummonPet(uint32 spellid)
{
if (getClass() == CLASS_DEATH_KNIGHT)
if (IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_PET))
{
if (CanSeeDKPet())
return true;
else if (spellid == 52150) // Raise Dead
return false;
}
else if (getClass() == CLASS_MAGE)
if (IsClass(CLASS_MAGE, CLASS_CONTEXT_PET))
{
if (HasSpell(31687) && HasAura(70937)) //Has [Summon Water Elemental] spell and [Glyph of Eternal Water].
return true;
}
else if (getClass() == CLASS_HUNTER)
if (IsClass(CLASS_HUNTER, CLASS_CONTEXT_PET))
{
return true;
}
@@ -15171,7 +15189,7 @@ void Player::ActivateSpec(uint8 spec)
AutoUnequipOffhandIfNeed();
// Xinef: Patch 3.2.0: Switching spec removes paladins spell Righteous Fury (25780)
if (getClass() == CLASS_PALADIN)
if (IsClass(CLASS_PALADIN, CLASS_CONTEXT_ABILITY))
RemoveAurasDueToSpell(25780);
// Xinef: Remove talented single target auras at other targets