Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new hooks for repuation gaining to the player #21306

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/server/game/Battlegrounds/Battleground.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,10 @@ void Battleground::RewardReputationToTeam(uint32 factionId, uint32 reputation, T
AddPct(repGain, itr->second->GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN));
AddPct(repGain, itr->second->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, realFactionId));
if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(realFactionId))
{
ScriptMgr::instance()->OnBeforePlayerReputationChange(itr->second, factionId, repGain, ReputationSource::PvP);
itr->second->GetReputationMgr().ModifyReputation(factionEntry, repGain);
}
}
}

Expand Down
56 changes: 33 additions & 23 deletions src/server/game/Entities/Player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5904,25 +5904,25 @@ float Player::CalculateReputationGain(ReputationSource source, uint32 creatureOr
float repMod = noQuestBonus ? 0.0f : float(GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN));

// faction specific auras only seem to apply to kills
if (source == REPUTATION_SOURCE_KILL)
if (source == ReputationSource::Kill)
repMod += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, faction);

percent += rep > 0.f ? repMod : -repMod;

float rate;
switch (source)
{
case REPUTATION_SOURCE_KILL:
case ReputationSource::Kill:
rate = sWorld->getRate(RATE_REPUTATION_LOWLEVEL_KILL);
break;
case REPUTATION_SOURCE_QUEST:
case REPUTATION_SOURCE_DAILY_QUEST:
case REPUTATION_SOURCE_WEEKLY_QUEST:
case REPUTATION_SOURCE_MONTHLY_QUEST:
case REPUTATION_SOURCE_REPEATABLE_QUEST:
case ReputationSource::Quest:
case ReputationSource::DailyQuest:
case ReputationSource::WeeklyQuest:
case ReputationSource::MonthlyQuest:
case ReputationSource::RepeatableQuest:
rate = sWorld->getRate(RATE_REPUTATION_LOWLEVEL_QUEST);
break;
case REPUTATION_SOURCE_SPELL:
case ReputationSource::Spell:
default:
rate = 1.0f;
break;
Expand All @@ -5940,25 +5940,25 @@ float Player::CalculateReputationGain(ReputationSource source, uint32 creatureOr
float repRate = 0.0f;
switch (source)
{
case REPUTATION_SOURCE_KILL:
case ReputationSource::Kill:
repRate = repData->creatureRate;
break;
case REPUTATION_SOURCE_QUEST:
case ReputationSource::Quest:
repRate = repData->questRate;
break;
case REPUTATION_SOURCE_DAILY_QUEST:
case ReputationSource::DailyQuest:
repRate = repData->questDailyRate;
break;
case REPUTATION_SOURCE_WEEKLY_QUEST:
case ReputationSource::WeeklyQuest:
repRate = repData->questWeeklyRate;
break;
case REPUTATION_SOURCE_MONTHLY_QUEST:
case ReputationSource::MonthlyQuest:
repRate = repData->questMonthlyRate;
break;
case REPUTATION_SOURCE_REPEATABLE_QUEST:
case ReputationSource::RepeatableQuest:
repRate = repData->questRepeatableRate;
break;
case REPUTATION_SOURCE_SPELL:
case ReputationSource::Spell:
repRate = repData->spellRate;
break;
}
Expand All @@ -5970,7 +5970,7 @@ float Player::CalculateReputationGain(ReputationSource source, uint32 creatureOr
percent *= repRate;
}

if (source != REPUTATION_SOURCE_SPELL && GetsRecruitAFriendBonus(false))
if (source != ReputationSource::Spell && GetsRecruitAFriendBonus(false))
percent *= 1.0f + sWorld->getRate(RATE_REPUTATION_RECRUIT_A_FRIEND_BONUS);

return CalculatePct(rep, percent);
Expand Down Expand Up @@ -6005,7 +6005,9 @@ void Player::RewardReputation(Unit* victim)

if (Rep->RepFaction1 && (!Rep->TeamDependent || teamId == TEAM_ALLIANCE))
{
float donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), static_cast<float>(Rep->RepValue1), ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
float donerep1 = CalculateReputationGain(ReputationSource::Kill, victim->GetLevel(), static_cast<float>(Rep->RepValue1), ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
ScriptMgr::instance()->OnBeforePlayerReputationChange(this, static_cast<float>(Rep->RepValue1), donerep1, ReputationSource::Kill);
ScriptMgr::instance()->OnBeforePlayerReputationChange(this, static_cast<float>(Rep->RepValue1), donerep1, victim);

FactionEntry const* factionEntry1 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction1);
if (factionEntry1)
Expand All @@ -6016,7 +6018,9 @@ void Player::RewardReputation(Unit* victim)

if (Rep->RepFaction2 && (!Rep->TeamDependent || teamId == TEAM_HORDE))
{
float donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->GetLevel(), static_cast<float>(Rep->RepValue2), ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
float donerep2 = CalculateReputationGain(ReputationSource::Kill, victim->GetLevel(), static_cast<float>(Rep->RepValue2), ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
ScriptMgr::instance()->OnBeforePlayerReputationChange(this, static_cast<float>(Rep->RepValue1), donerep2, ReputationSource::Kill);
ScriptMgr::instance()->OnBeforePlayerReputationChange(this, static_cast<float>(Rep->RepValue1), donerep2, victim);

FactionEntry const* factionEntry2 = sFactionStore.LookupEntry(ChampioningFaction ? ChampioningFaction : Rep->RepFaction2);
if (factionEntry2)
Expand Down Expand Up @@ -6055,25 +6059,31 @@ void Player::RewardReputation(Quest const* quest)

if (quest->IsDaily())
{
rep = CalculateReputationGain(REPUTATION_SOURCE_DAILY_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
rep = CalculateReputationGain(ReputationSource::DailyQuest, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
ScriptMgr::instance()->OnBeforePlayerReputationChange(this, quest->RewardFactionId[i], rep, ReputationSource::DailyQuest);
}
else if (quest->IsWeekly())
{
rep = CalculateReputationGain(REPUTATION_SOURCE_WEEKLY_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
rep = CalculateReputationGain(ReputationSource::WeeklyQuest, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
ScriptMgr::instance()->OnBeforePlayerReputationChange(this, quest->RewardFactionId[i], rep, ReputationSource::WeeklyQuest);
}
else if (quest->IsMonthly())
{
rep = CalculateReputationGain(REPUTATION_SOURCE_MONTHLY_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
rep = CalculateReputationGain(ReputationSource::MonthlyQuest, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
ScriptMgr::instance()->OnBeforePlayerReputationChange(this, quest->RewardFactionId[i], rep, ReputationSource::MonthlyQuest);
}
else if (quest->IsRepeatable())
{
rep = CalculateReputationGain(REPUTATION_SOURCE_REPEATABLE_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
rep = CalculateReputationGain(ReputationSource::RepeatableQuest, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
ScriptMgr::instance()->OnBeforePlayerReputationChange(this, quest->RewardFactionId[i], rep, ReputationSource::RepeatableQuest);
}
else
{
rep = CalculateReputationGain(REPUTATION_SOURCE_QUEST, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
rep = CalculateReputationGain(ReputationSource::Quest, GetQuestLevel(quest), rep, quest->RewardFactionId[i], false);
ScriptMgr::instance()->OnBeforePlayerReputationChange(this, quest->RewardFactionId[i], rep, ReputationSource::Quest);
}

ScriptMgr::instance()->OnBeforePlayerReputationChange(this, quest->RewardFactionId[i], rep, quest);
if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(quest->RewardFactionId[i]))
{
GetReputationMgr().ModifyReputation(factionEntry, rep, quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_NO_REP_SPILLOVER));
Expand Down
33 changes: 24 additions & 9 deletions src/server/game/Entities/Player/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,15 +234,30 @@ enum ActionButtonType
ACTION_BUTTON_ITEM = 0x80
};

enum ReputationSource
{
REPUTATION_SOURCE_KILL,
REPUTATION_SOURCE_QUEST,
REPUTATION_SOURCE_DAILY_QUEST,
REPUTATION_SOURCE_WEEKLY_QUEST,
REPUTATION_SOURCE_MONTHLY_QUEST,
REPUTATION_SOURCE_REPEATABLE_QUEST,
REPUTATION_SOURCE_SPELL
/**
* @brief This enum represent all known sources a character can get reputation
*/
enum class ReputationSource : uint8 {
/// The player killed an enemy
Kill,
/// The player turned in a quest
Quest,
/// The player turned in a daily quest
DailyQuest,
/// The player turned in a weekly quest
WeeklyQuest,
/// The player turned in a montly quest
MonthlyQuest,
/// The player turned in a repeatable quest
RepeatableQuest,
/// The player used a spell
Spell,
// The player get reputation by doing PvP related tasks
PvP,
/// The player get reputation by a console command
Console,
/// The player get some reputation by server configuration
Config
};

enum QuestSound
Expand Down
7 changes: 5 additions & 2 deletions src/server/game/Handlers/CharacterHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1017,11 +1017,14 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder)
{
ReputationMgr& repMgr = pCurrChar->GetReputationMgr();

auto SendFullReputation = [&repMgr](std::initializer_list<uint32> factionsList)
auto SendFullReputation = [&repMgr, pCurrChar](std::initializer_list<uint32> factionsList)
{
for (auto const& itr : factionsList)
{
repMgr.SetOneFactionReputation(sFactionStore.LookupEntry(itr), 42999.f, false);
auto faction = sFactionStore.LookupEntry(itr);
float reputation = 42999.f;
ScriptMgr::instance()->OnBeforePlayerReputationChange(pCurrChar, faction->ID, reputation, ReputationSource::Config);
repMgr.SetOneFactionReputation(sFactionStore.LookupEntry(itr), reputation, false);
}
};

Expand Down
20 changes: 20 additions & 0 deletions src/server/game/Scripting/ScriptDefines/PlayerScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,26 @@ void ScriptMgr::OnGivePlayerXP(Player* player, uint32& amount, Unit* victim, uin
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_GIVE_EXP, script->OnGiveXP(player, amount, victim, xpSource));
}

void ScriptMgr::OnBeforePlayerReputationChange(Player* player, uint32 factionId, float& amount, Unit* victim)
{
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_BEFORE_REPUTATION_CHANGE_UNIT, script->OnBeforeReputationChange(player, factionId, amount, victim));
}

void ScriptMgr::OnBeforePlayerReputationChange(Player* player, uint32 factionId, float& amount, Quest const* quest)
{
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_BEFORE_REPUTATION_CHANGE_QUEST, script->OnBeforeReputationChange(player, factionId, amount, quest));
}

void ScriptMgr::OnBeforePlayerReputationChange(Player* player, uint32 factionId, float& amount, Spell* spell)
{
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_BEFORE_REPUTATION_CHANGE_SPELL, script->OnBeforeReputationChange(player, factionId, amount, spell));
}

void ScriptMgr::OnBeforePlayerReputationChange(Player* player, uint32 factionId, float& amount, ReputationSource reputationSource)
{
CALL_ENABLED_HOOKS(PlayerScript, PLAYERHOOK_ON_BEFORE_REPUTATION_CHANGE_SOURCE, script->OnBeforeReputationChange(player, factionId, amount, reputationSource));
}

bool ScriptMgr::OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental)
{
CALL_ENABLED_BOOLEAN_HOOKS(PlayerScript, PLAYERHOOK_ON_REPUTATION_CHANGE, !script->OnReputationChange(player, factionID, standing, incremental));
Expand Down
53 changes: 53 additions & 0 deletions src/server/game/Scripting/ScriptDefines/PlayerScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef SCRIPT_OBJECT_PLAYER_SCRIPT_H_
#define SCRIPT_OBJECT_PLAYER_SCRIPT_H_

#include "Player.h"
#include "ScriptObject.h"
#include "SharedDefines.h"
#include <vector>
Expand Down Expand Up @@ -48,6 +49,10 @@ enum PlayerHook
PLAYERHOOK_ON_MONEY_CHANGED,
PLAYERHOOK_ON_BEFORE_LOOT_MONEY,
PLAYERHOOK_ON_GIVE_EXP,
PLAYERHOOK_ON_BEFORE_REPUTATION_CHANGE_UNIT,
PLAYERHOOK_ON_BEFORE_REPUTATION_CHANGE_QUEST,
PLAYERHOOK_ON_BEFORE_REPUTATION_CHANGE_SPELL,
PLAYERHOOK_ON_BEFORE_REPUTATION_CHANGE_SOURCE,
PLAYERHOOK_ON_REPUTATION_CHANGE,
PLAYERHOOK_ON_REPUTATION_RANK_CHANGE,
PLAYERHOOK_ON_LEARN_SPELL,
Expand Down Expand Up @@ -271,6 +276,54 @@ class PlayerScript : public ScriptObject
// Called when a player gains XP (before anything is given)
virtual void OnGiveXP(Player* /*player*/, uint32& /*amount*/, Unit* /*victim*/, uint8 /*xpSource*/) { }

/**
* @brief Called before a player gains or looses Reputation
*
* @param [in] player instance of the current player
* @param [in] factionId id of the faction which reputation changes
* @param[in,out] amount the amount of reputation the player gets or loses
* @param[in] victim the unit which was killed to gain reputation
* @remark avoid hooking both versions of this event ReputationSource is a more generic one.<br />
* ReputationSource is called first.
*/
virtual void OnBeforeReputationChange(Player* /*player*/, uint32 /*factionId*/, float& /*amount*/, Unit* /*victim*/ ) {}

/**
* @brief Called before a player gains or looses Reputation
*
* @param [in] player instance of the current player
* @param [in] factionId id of the faction which reputation changes
* @param[in,out] amount the amount of reputation the player gets or loses
* @param[in] quest the quest which was turn in to gain reputation
* @remark avoid hooking both versions of this event ReputationSource is a more generic one.<br />
* ReputationSource is called first.
*/
virtual void OnBeforeReputationChange(Player* /*player*/, uint32 /*factionId*/ , float& /*amount*/, Quest const* /*quest*/) {}

/**
* @brief Called before a player gains or looses Reputation
*
* @param [in] player instance of the current player
* @param [in] factionId id of the faction which reputation changes
* @param[in,out] amount the amount of reputation the player gets or loses
* @param[in] spell the spell which was used to gain reputation
* @remark avoid hooking both versions of this event ReputationSource is a more generic one.<br />
* ReputationSource is called first.
*/
virtual void OnBeforeReputationChange(Player* /*player*/, uint32 /*factionId*/, float& /*amount*/ , Spell* /*spell*/) {}

/**
* @brief Called before a player gains or looses Reputation
*
* @param [in] player instance of the current player
* @param [in] factionId id of the faction which reputation changes
* @param[in,out] amount the amount of reputation the player gets or loses
* @param[in] reputationSource an enum which determinate the source used to gain or loose reputation
* @remark avoid hooking both versions of this event ReputationSource is a more generic one.<br />
* ReputationSource is called first.
*/
virtual void OnBeforeReputationChange(Player* /*player*/, uint32 /*factionId*/, float& /*amount*/, ReputationSource /*reputationSource*/) {}

// Called when a player's reputation changes (before it is actually changed)
virtual bool OnReputationChange(Player* /*player*/, uint32 /*factionID*/, int32& /*standing*/, bool /*incremental*/) { return true; }

Expand Down
51 changes: 51 additions & 0 deletions src/server/game/Scripting/ScriptMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "LFGMgr.h"
#include "ObjectMgr.h"
#include "PetDefines.h"
#include "Player.h"
#include "SharedDefines.h"
#include "Tuples.h"
#include "Weather.h"
Expand Down Expand Up @@ -311,6 +312,56 @@ class ScriptMgr
void OnPlayerMoneyChanged(Player* player, int32& amount);
void OnBeforeLootMoney(Player* player, Loot* loot);
void OnGivePlayerXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource);

/**
* @brief Called before a player gains or looses Reputation
*
* @param [in] player instance of the current player
* @param [in] factionId id of the faction which reputation changes
* @param[in,out] amount the amount of reputation the player gets or loses
* @param[in] victim the unit which was killed to gain reputation
*
* @remark avoid hooking both versions of this event ReputationSource is a more generic one.<br />
* ReputationSource is called first.
*/
void OnBeforePlayerReputationChange(Player* player, uint32 factionId, float& amount, Unit* victim);

/**
* @brief Called before a player gains or looses Reputation
*
* @param [in] player instance of the current player
* @param [in] factionId id of the faction which reputation changes
* @param[in,out] amount the amount of reputation the player gets or loses
* @param[in] quest the quest which was turn in to gain reputation
* @remark avoid hooking both versions of this event ReputationSource is a more generic one.<br />
* ReputationSource is called first.
*/
void OnBeforePlayerReputationChange(Player* player, uint32 factionId, float& amount, Quest const* quest);

/**
* @brief Called before a player gains or looses Reputation
*
* @param [in] player instance of the current player
* @param [in] factionId id of the faction which reputation changes
* @param[in,out] amount the amount of reputation the player gets or loses
* @param[in] spell the spell which was used to gain reputation
* @remark avoid hooking both versions of this event ReputationSource is a more generic one.<br />
* ReputationSource is called first.
*/
void OnBeforePlayerReputationChange(Player* player, uint32 factionId, float& amount, Spell* spell);

/**
* @brief Called before a player gains or looses Reputation
*
* @param [in] player instance of the current player
* @param [in] factionId id of the faction which reputation changes
* @param[in,out] amount the amount of reputation the player gets or loses
* @param[in] reputationSource an enum which determinate the source used to gain or loose reputation
*
* @remark avoid hooking both versions of this event ReputationSource is a more generic one.<br />
* ReputationSource is called first.
*/
void OnBeforePlayerReputationChange(Player* player, uint32 factionId, float& amount, ReputationSource reputationSource);
bool OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental);
void OnPlayerReputationRankChange(Player* player, uint32 factionID, ReputationRank newRank, ReputationRank oldRank, bool increased);
void OnPlayerLearnSpell(Player* player, uint32 spellID);
Expand Down
4 changes: 3 additions & 1 deletion src/server/game/Spells/SpellEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4747,7 +4747,9 @@ void Spell::EffectReputation(SpellEffIndex effIndex)
if (!factionEntry)
return;

repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
repChange = player->CalculateReputationGain(ReputationSource::Spell, 0, repChange, factionId);
ScriptMgr::instance()->OnBeforePlayerReputationChange(player, factionId, repChange, ReputationSource::Spell);
ScriptMgr::instance()->OnBeforePlayerReputationChange(player, factionId, repChange, this);
player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
}

Expand Down
Loading
Loading