feat(Core/Scripting): Add Player skill based hook (#21273)

Co-authored-by: IntelligentQuantum <IntelligentQuantum@ProtonMail.Com>
Co-authored-by: Ludwig <sudlud@users.noreply.github.com>
This commit is contained in:
iThorgrim 2025-02-15 23:10:38 +01:00 committed by GitHub
parent c96ff8a6dc
commit 971ebcae31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 37 additions and 4 deletions

View File

@ -708,7 +708,7 @@ void Player::UpdateAllRatings()
// skill+step, checking for max value
bool Player::UpdateSkill(uint32 skill_id, uint32 step)
{
if (!skill_id)
if (!skill_id || !sScriptMgr->CanPlayerUpdateSkill(this, skill_id))
return false;
SkillStatusMap::iterator itr = mSkillStatus.find(skill_id);
@ -720,6 +720,8 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step)
uint32 value = SKILL_VALUE(data);
uint32 max = SKILL_MAX(data);
sScriptMgr->OnBeforePlayerUpdateSkill(this, skill_id, value, max, step);
if ((!max) || (!value) || (value >= max))
return false;
@ -736,6 +738,8 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step)
UpdateSkillEnchantments(skill_id, value, new_value);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL,
skill_id);
sScriptMgr->OnPlayerUpdateSkill(this, skill_id, value, max, step, new_value);
return true;
}
@ -911,7 +915,7 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
LOG_DEBUG("entities.player.skills",
"UpdateSkillPro(SkillId {}, Chance {:3.1f}%)", SkillId,
Chance / 10.0f);
if (!SkillId)
if (!SkillId || !sScriptMgr->CanPlayerUpdateSkill(this, SkillId))
return false;
if (Chance <= 0) // speedup in 0 chance case
@ -929,8 +933,10 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
uint32 valueIndex = PLAYER_SKILL_VALUE_INDEX(itr->second.pos);
uint32 data = GetUInt32Value(valueIndex);
uint16 SkillValue = SKILL_VALUE(data);
uint16 MaxValue = SKILL_MAX(data);
uint32 SkillValue = SKILL_VALUE(data);
uint32 MaxValue = SKILL_MAX(data);
sScriptMgr->OnBeforePlayerUpdateSkill(this, SkillId, SkillValue, MaxValue, step);
if (!MaxValue || !SkillValue || SkillValue >= MaxValue)
return false;
@ -962,6 +968,8 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
LOG_DEBUG("entities.player.skills",
"Player::UpdateSkillPro Chance={:3.1f}% taken",
Chance / 10.0f);
sScriptMgr->OnPlayerUpdateSkill(this, SkillId, SkillValue, MaxValue, step, new_value);
return true;
}

View File

@ -895,6 +895,21 @@ bool ScriptMgr::AnticheatCheckMovementInfo(Player* player, MovementInfo const& m
CALL_ENABLED_BOOLEAN_HOOKS(PlayerScript, PLAYERHOOK_ANTICHEAT_CHECK_MOVEMENT_INFO, !script->AnticheatCheckMovementInfo(player, movementInfo, mover, jump));
}
bool ScriptMgr::CanPlayerUpdateSkill(Player* player, uint32 skillId)
{
CALL_ENABLED_BOOLEAN_HOOKS(PlayerScript, PLAYERHOOK_ON_CAN_UPDATE_SKILL, !script->CanPlayerUpdateSkill(player, skillId));
}
void ScriptMgr::OnBeforePlayerUpdateSkill(Player* player, uint32 skillId, uint32& value, uint32 max, uint32 step)
{
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_BEFORE_UPDATE_SKILL, script->OnBeforePlayerUpdateSkill(player, skillId, value, max, step));
}
void ScriptMgr::OnPlayerUpdateSkill(Player* player, uint32 skillId, uint32 value, uint32 max, uint32 step, uint32 newValue)
{
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_UPDATE_SKILL, script->OnPlayerUpdateSkill(player, skillId, value, max, step, newValue));
}
bool ScriptMgr::CanPlayerResurrect(Player* player)
{
CALL_ENABLED_BOOLEAN_HOOKS(PlayerScript, PLAYERHOOK_CAN_RESURRECT, !script->CanPlayerResurrect(player));

View File

@ -204,6 +204,9 @@ enum PlayerHook
PLAYERHOOK_CAN_SEND_ERROR_ALREADY_LOOTED,
PLAYERHOOK_ON_AFTER_CREATURE_LOOT,
PLAYERHOOK_ON_AFTER_CREATURE_LOOT_MONEY,
PLAYERHOOK_ON_CAN_UPDATE_SKILL,
PLAYERHOOK_ON_BEFORE_UPDATE_SKILL,
PLAYERHOOK_ON_UPDATE_SKILL,
PLAYERHOOK_CAN_RESURRECT,
PLAYERHOOK_END
};
@ -767,6 +770,10 @@ public:
*/
virtual void OnAfterCreatureLootMoney(Player* /*player*/) { }
virtual bool CanPlayerUpdateSkill(Player* /*player*/, uint32 /*skillId*/) { return true; }
virtual void OnBeforePlayerUpdateSkill(Player* /*player*/, uint32 /*skillId*/, uint32& /*value*/, uint32 /*max*/, uint32 /*step*/) { }
virtual void OnPlayerUpdateSkill(Player* /*player*/, uint32 /*skillId*/, uint32 /*value*/, uint32 /*max*/, uint32 /*step*/, uint32 /*newValue*/) { }
/**
* @brief This hook is called, to avoid player resurrect
*

View File

@ -459,6 +459,9 @@ public: /* PlayerScript */
void OnAfterCreatureLoot(Player* player);
void OnAfterCreatureLootMoney(Player* player);
bool OnCanPlayerFlyInZone(Player* player, uint32 mapId, uint32 zoneId, SpellInfo const* bySpell);
bool CanPlayerUpdateSkill(Player* player, uint32 skillId);
void OnBeforePlayerUpdateSkill(Player* player, uint32 skill_id, uint32& value, uint32 max, uint32 step);
void OnPlayerUpdateSkill(Player* player, uint32 skillId, uint32 value, uint32 max, uint32 step, uint32 newValue);
bool CanPlayerResurrect(Player* player);
// Anti cheat