From 2b3b124e0910c53daeaceacb280d51a298055b84 Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Sun, 2 Dec 2012 16:32:44 +0100 Subject: Core/Reputation: Implemented new `reputation_reward_rate` fields for dayily/weekly quests --- src/server/game/Entities/Player/Player.cpp | 101 ++++++++++++++++++++++------- src/server/game/Entities/Player/Player.h | 12 +++- src/server/game/Globals/ObjectMgr.cpp | 40 ++++++++---- src/server/game/Globals/ObjectMgr.h | 8 ++- src/server/game/Spells/SpellEffects.cpp | 18 ++--- 5 files changed, 123 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index b4fd4a6846a..a0e732bb9f8 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -6923,37 +6923,76 @@ ReputationRank Player::GetReputationRank(uint32 faction) const return GetReputationMgr().GetRank(factionEntry); } -//Calculate total reputation percent player gain with quest/creature level -int32 Player::CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest, bool noQuestBonus) +// Calculate total reputation percent player gain with quest/creature level +int32 Player::CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool noQuestBonus) { float percent = 100.0f; - // Get the generic rate first - if (RepRewardRate const* repData = sObjectMgr->GetRepRewardRate(faction)) + 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) + repMod += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, faction); + + percent += rep > 0 ? repMod : -repMod; + + float rate; + switch (source) { - float repRate = for_quest ? repData->quest_rate : repData->creature_rate; - percent *= repRate; + case REPUTATION_SOURCE_KILL: + rate = sWorld->getRate(RATE_REPUTATION_LOWLEVEL_KILL); + break; + case REPUTATION_SOURCE_QUEST: + case REPUTATION_SOURCE_DAYLIY_QUEST: + case REPUTATION_SOURCE_WEEKLY_QUEST: + rate = sWorld->getRate(RATE_REPUTATION_LOWLEVEL_QUEST); + break; + case REPUTATION_SOURCE_SPELL: + default: + rate = 1.0f; + break; } - float rate = for_quest ? sWorld->getRate(RATE_REPUTATION_LOWLEVEL_QUEST) : sWorld->getRate(RATE_REPUTATION_LOWLEVEL_KILL); - if (rate != 1.0f && creatureOrQuestLevel <= Trinity::XP::GetGrayLevel(getLevel())) percent *= rate; - float repMod = noQuestBonus ? 0.0f : (float)GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN); + if (percent <= 0.0f) + return 0; - if (!for_quest) - repMod += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_FACTION_REPUTATION_GAIN, faction); + // Multiply result with the faction specific rate + if (RepRewardRate const* repData = sObjectMgr->GetRepRewardRate(faction)) + { + float repRate = 0.0f; + switch (source) + { + case REPUTATION_SOURCE_KILL: + repRate = repData->creatureRate; + break; + case REPUTATION_SOURCE_QUEST: + repRate = repData->questRate; + break; + case REPUTATION_SOURCE_DAYLIY_QUEST: + repRate = repData->questDailyRate; + break; + case REPUTATION_SOURCE_WEEKLY_QUEST: + repRate = repData->questWeeklyRate; + break; + case REPUTATION_SOURCE_SPELL: + repRate = repData->spellRate; + break; + } - percent += rep > 0 ? repMod : -repMod; + // for custom, a rate of 0.0 will totally disable reputation gain for this faction/type + if (repRate <= 0.0f) + return 0; - if (percent <= 0.0f) - return 0; + percent *= repRate; + } - return int32(rep*percent/100); + return int32(rep * percent / 100.0f); } -//Calculates how many reputation points player gains in victim's enemy factions +// Calculates how many reputation points player gains in victim's enemy factions void Player::RewardReputation(Unit* victim, float rate) { if (!victim || victim->GetTypeId() == TYPEID_PLAYER) @@ -6963,7 +7002,6 @@ void Player::RewardReputation(Unit* victim, float rate) return; ReputationOnKillEntry const* Rep = sObjectMgr->GetReputationOnKilEntry(victim->ToCreature()->GetCreatureTemplate()->Entry); - if (!Rep) return; @@ -6994,8 +7032,10 @@ void Player::RewardReputation(Unit* victim, float rate) uint32 team = GetTeam(); float favored_rep_mult = 0; - if ((HasAura(32096) || HasAura(32098)) && (zone == 3483 || zone == 3562 || zone == 3836 || zone == 3713 || zone == 3714)) favored_rep_mult = 0.25; // Thrallmar's Favor and Honor Hold's Favor - else if (HasAura(30754) && (Rep->RepFaction1 == 609 || Rep->RepFaction2 == 609) && !ChampioningFaction) favored_rep_mult = 0.25; // Cenarion Favor + if ((HasAura(32096) || HasAura(32098)) && (zone == 3483 || zone == 3562 || zone == 3836 || zone == 3713 || zone == 3714)) + favored_rep_mult = 0.25; // Thrallmar's Favor and Honor Hold's Favor + else if (HasAura(30754) && (Rep->RepFaction1 == 609 || Rep->RepFaction2 == 609) && !ChampioningFaction) + favored_rep_mult = 0.25; // Cenarion Favor if (favored_rep_mult > 0) favored_rep_mult *= 2; // Multiplied by 2 because the reputation is divided by 2 for some reason (See "donerep1 / 2" and "donerep2 / 2") -- if you know why this is done, please update/explain :) // Favored reputation increase END @@ -7004,7 +7044,7 @@ void Player::RewardReputation(Unit* victim, float rate) if (Rep->RepFaction1 && (!Rep->TeamDependent || team == ALLIANCE)) { - int32 donerep1 = CalculateReputationGain(victim->getLevel(), Rep->RepValue1, ChampioningFaction ? ChampioningFaction : Rep->RepFaction1, false); + int32 donerep1 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue1, ChampioningFaction ? ChampioningFaction : Rep->RepFaction1, false); donerep1 = int32(donerep1*(rate + favored_rep_mult)); if (recruitAFriend) @@ -7018,7 +7058,7 @@ void Player::RewardReputation(Unit* victim, float rate) if (Rep->RepFaction2 && (!Rep->TeamDependent || team == HORDE)) { - int32 donerep2 = CalculateReputationGain(victim->getLevel(), Rep->RepValue2, ChampioningFaction ? ChampioningFaction : Rep->RepFaction2, false); + int32 donerep2 = CalculateReputationGain(REPUTATION_SOURCE_KILL, victim->getLevel(), Rep->RepValue2, ChampioningFaction ? ChampioningFaction : Rep->RepFaction2, false); donerep2 = int32(donerep2*(rate + favored_rep_mult)); if (recruitAFriend) @@ -7031,7 +7071,7 @@ void Player::RewardReputation(Unit* victim, float rate) } } -//Calculate how many reputation points player gain with the quest +// Calculate how many reputation points player gain with the quest void Player::RewardReputation(Quest const* quest) { bool recruitAFriend = GetsRecruitAFriendBonus(false); @@ -7043,7 +7083,14 @@ void Player::RewardReputation(Quest const* quest) continue; if (quest->RewardFactionValueIdOverride[i]) { - int32 rep = CalculateReputationGain(GetQuestLevel(quest), quest->RewardFactionValueIdOverride[i]/100, quest->RewardFactionId[i], true, true); + int32 rep = 0; + + if (quest->IsDaily()) + rep = CalculateReputationGain(REPUTATION_SOURCE_DAYLIY_QUEST, GetQuestLevel(quest), quest->RewardFactionValueIdOverride[i]/100, quest->RewardFactionId[i], true); + else if (quest->IsWeekly()) + rep = CalculateReputationGain(REPUTATION_SOURCE_WEEKLY_QUEST, GetQuestLevel(quest), quest->RewardFactionValueIdOverride[i]/100, quest->RewardFactionId[i], true); + else + rep = CalculateReputationGain(REPUTATION_SOURCE_QUEST, GetQuestLevel(quest), quest->RewardFactionValueIdOverride[i]/100, quest->RewardFactionId[i], true); if (recruitAFriend) rep = int32(rep * (1 + sWorld->getRate(RATE_REPUTATION_RECRUIT_A_FRIEND_BONUS))); @@ -7059,11 +7106,15 @@ void Player::RewardReputation(Quest const* quest) if (const QuestFactionRewEntry* pRow = sQuestFactionRewardStore.LookupEntry(row)) { int32 repPoints = pRow->QuestRewFactionValue[field]; - if (!repPoints) continue; - repPoints = CalculateReputationGain(GetQuestLevel(quest), repPoints, quest->RewardFactionId[i], true); + if (quest->IsDaily()) + repPoints = CalculateReputationGain(REPUTATION_SOURCE_DAYLIY_QUEST, GetQuestLevel(quest), repPoints, quest->RewardFactionId[i], true); + else if (quest->IsDaily()) + repPoints = CalculateReputationGain(REPUTATION_SOURCE_WEEKLY_QUEST, GetQuestLevel(quest), repPoints, quest->RewardFactionId[i], true); + else + repPoints = CalculateReputationGain(REPUTATION_SOURCE_QUEST, GetQuestLevel(quest), repPoints, quest->RewardFactionId[i], true); if (recruitAFriend) repPoints = int32(repPoints * (1 + sWorld->getRate(RATE_REPUTATION_RECRUIT_A_FRIEND_BONUS))); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index c4b7deca4dd..108846e46dc 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -162,6 +162,15 @@ enum ActionButtonType ACTION_BUTTON_ITEM = 0x80 }; +enum ReputationSource +{ + REPUTATION_SOURCE_KILL, + REPUTATION_SOURCE_QUEST, + REPUTATION_SOURCE_DAYLIY_QUEST, + REPUTATION_SOURCE_WEEKLY_QUEST, + REPUTATION_SOURCE_SPELL +}; + #define ACTION_BUTTON_ACTION(X) (uint32(X) & 0x00FFFFFF) #define ACTION_BUTTON_TYPE(X) ((uint32(X) & 0xFF000000) >> 24) #define MAX_ACTION_BUTTON_ACTION_VALUE (0x00FFFFFF+1) @@ -2025,6 +2034,8 @@ class Player : public Unit, public GridObject void RewardReputation(Unit* victim, float rate); void RewardReputation(Quest const* quest); + int32 CalculateReputationGain(ReputationSource source, uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool noQuestBonus = false); + void UpdateSkillsForLevel(); void UpdateSkillsToMaxSkillsForLevel(); // for .levelup void ModifySkillBonus(uint32 skillid, int32 val, bool talent); @@ -2799,7 +2810,6 @@ class Player : public Unit, public GridObject // know currencies are not removed at any point (0 displayed) void AddKnownCurrency(uint32 itemId); - int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest, bool noQuestBonus = false); void AdjustQuestReqItemCount(Quest const* quest, QuestStatusData& questStatusData); bool IsCanDelayTeleport() const { return m_bCanDelayTeleport; } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 47294e7f9ad..7bf9d1c8fe2 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -6644,13 +6644,11 @@ void ObjectMgr::LoadReputationRewardRate() _repRewardRateStore.clear(); // for reload case - uint32 count = 0; // 0 1 2 3 - QueryResult result = WorldDatabase.Query("SELECT faction, quest_rate, creature_rate, spell_rate FROM reputation_reward_rate"); - + uint32 count = 0; // 0 1 2 3 4 5 + QueryResult result = WorldDatabase.Query("SELECT faction, quest_rate, quest_daily_rate, quest_weekly_rate, creature_rate, spell_rate FROM reputation_reward_rate"); if (!result) { sLog->outError(LOG_FILTER_SQL, ">> Loaded `reputation_reward_rate`, table is empty!"); - return; } @@ -6658,13 +6656,15 @@ void ObjectMgr::LoadReputationRewardRate() { Field* fields = result->Fetch(); - uint32 factionId = fields[0].GetUInt32(); + uint32 factionId = fields[0].GetUInt32(); RepRewardRate repRate; - repRate.quest_rate = fields[1].GetFloat(); - repRate.creature_rate = fields[2].GetFloat(); - repRate.spell_rate = fields[3].GetFloat(); + repRate.questRate = fields[1].GetFloat(); + repRate.questDailyRate = fields[2].GetFloat(); + repRate.questWeeklyRate = fields[3].GetFloat(); + repRate.creatureRate = fields[4].GetFloat(); + repRate.spellRate = fields[5].GetFloat(); FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId); if (!factionEntry) @@ -6673,21 +6673,33 @@ void ObjectMgr::LoadReputationRewardRate() continue; } - if (repRate.quest_rate < 0.0f) + if (repRate.questRate < 0.0f) + { + sLog->outError(LOG_FILTER_SQL, "Table reputation_reward_rate has quest_rate with invalid rate %f, skipping data for faction %u", repRate.questRate, factionId); + continue; + } + + if (repRate.questDailyRate < 0.0f) + { + sLog->outError(LOG_FILTER_SQL, "Table reputation_reward_rate has quest_daily_rate with invalid rate %f, skipping data for faction %u", repRate.questRate, factionId); + continue; + } + + if (repRate.questWeeklyRate < 0.0f) { - sLog->outError(LOG_FILTER_SQL, "Table reputation_reward_rate has quest_rate with invalid rate %f, skipping data for faction %u", repRate.quest_rate, factionId); + sLog->outError(LOG_FILTER_SQL, "Table reputation_reward_rate has quest_weekly_rate with invalid rate %f, skipping data for faction %u", repRate.questRate, factionId); continue; } - if (repRate.creature_rate < 0.0f) + if (repRate.creatureRate < 0.0f) { - sLog->outError(LOG_FILTER_SQL, "Table reputation_reward_rate has creature_rate with invalid rate %f, skipping data for faction %u", repRate.creature_rate, factionId); + sLog->outError(LOG_FILTER_SQL, "Table reputation_reward_rate has creature_rate with invalid rate %f, skipping data for faction %u", repRate.creatureRate, factionId); continue; } - if (repRate.spell_rate < 0.0f) + if (repRate.spellRate < 0.0f) { - sLog->outError(LOG_FILTER_SQL, "Table reputation_reward_rate has spell_rate with invalid rate %f, skipping data for faction %u", repRate.spell_rate, factionId); + sLog->outError(LOG_FILTER_SQL, "Table reputation_reward_rate has spell_rate with invalid rate %f, skipping data for faction %u", repRate.spellRate, factionId); continue; } diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 2adf45084c7..7f009bbd41d 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -463,9 +463,11 @@ typedef UNORDERED_MAP MailLevelRewardContainer; // We assume the rate is in general the same for all three types below, but chose to keep three for scalability and customization struct RepRewardRate { - float quest_rate; // We allow rate = 0.0 in database. For this case, it means that - float creature_rate; // no reputation are given at all for this faction/rate type. - float spell_rate; + float questRate; // We allow rate = 0.0 in database. For this case, it means that + float questDailyRate; + float questWeeklyRate; + float creatureRate; // no reputation are given at all for this faction/rate type. + float spellRate; }; struct ReputationOnKillEntry diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index c049605f27a..72ef429bed0 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -4982,25 +4982,17 @@ void Spell::EffectReputation(SpellEffIndex effIndex) Player* player = unitTarget->ToPlayer(); - int32 rep_change = damage; + int32 repChange = damage; - uint32 faction_id = m_spellInfo->Effects[effIndex].MiscValue; - - FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction_id); + uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue; + FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId); if (!factionEntry) return; - if (RepRewardRate const* repData = sObjectMgr->GetRepRewardRate(faction_id)) - { - rep_change = int32((float)rep_change * repData->spell_rate); - } - - // Bonus from spells that increase reputation gain - float bonus = rep_change * player->GetTotalAuraModifier(SPELL_AURA_MOD_REPUTATION_GAIN) / 100.0f; // 10% - rep_change += (int32)bonus; + repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId); - player->GetReputationMgr().ModifyReputation(factionEntry, rep_change); + player->GetReputationMgr().ModifyReputation(factionEntry, repChange); } void Spell::EffectQuestComplete(SpellEffIndex effIndex) -- cgit v1.2.3