Core/GameObject: implement gaining experience from unlocking chests

* this handles gathering experience as well as getting some extra xp from opening hidden treasure chests
This commit is contained in:
Ovahlord committed 2023-01-17 22:05:16 +01:00
1 parent f18a592a7e
commit 6ecaebb19e
5 files changed
+52 -35

No files matched your search

@@ -895,7 +895,7 @@ void GameObject::Update(uint32 diff)
}
m_respawnTime = 0;
m_SkillupList.clear();
_tappingPlayers.clear();
m_usetimes = 0;
switch (GetGoType())
@@ -221,8 +221,8 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
void SetLootGenerationTime();
uint32 GetLootGenerationTime() const { return m_lootGenerationTime; }
void AddToSkillupList(ObjectGuid::LowType playerLowGUID) { m_SkillupList.push_back(playerLowGUID); }
bool IsInSkillupList(ObjectGuid::LowType playerLowGUID) const { return std::find(m_SkillupList.begin(), m_SkillupList.end(), playerLowGUID) != m_SkillupList.end(); }
bool IsTappedByPlayer(ObjectGuid playerGuid) const { return std::find(_tappingPlayers.begin(), _tappingPlayers.end(), playerGuid) != _tappingPlayers.end(); }
void AddPlayerToTapperList(ObjectGuid playerGuid) { _tappingPlayers.emplace_back(playerGuid); }
void AddUniqueUse(Player* player);
void AddUse() { ++m_usetimes; }
@@ -345,7 +345,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
// For traps this: spell casting cooldown, for doors/buttons: reset time.
GOState m_prevGoState; // What state to set whenever resetting
std::list<ObjectGuid::LowType> m_SkillupList;
std::vector<ObjectGuid> _tappingPlayers;
ObjectGuid m_ritualOwnerGUID; // used for GAMEOBJECT_TYPE_SUMMONING_RITUAL where GO is not summoned (no owner)
GuidSet m_unique_users;
+25 -22
View File
@@ -242,30 +242,33 @@ void Quest::LoadQuestMailSender(Field* fields)
uint32 Quest::GetXPReward(Player const* player) const
{
if (player)
if (!player)
return 0;
return Quest::CalcXPReward(player->getLevel(), _level, _rewardXPDifficulty);
}
/*static*/ uint32 Quest::CalcXPReward(uint8 playerLevel, int32 targetLevel, uint8 xpDifficulty)
{
int32 effectiveLevel = (targetLevel == -1 ? playerLevel : targetLevel);
const QuestXPEntry* xpentry = sQuestXPStore.LookupEntry(effectiveLevel);
if (!xpentry)
return 0;
int32 diffFactor = 2 * (effectiveLevel - playerLevel) + 20;
if (diffFactor < 1)
diffFactor = 1;
else if (diffFactor > 10)
diffFactor = 10;
uint32 xp = RoundXPValue(diffFactor * xpentry->Difficulty[xpDifficulty] / 10);
if (sWorld->getIntConfig(CONFIG_MIN_QUEST_SCALED_XP_RATIO))
{
int32 quest_level = (_level == -1 ? player->getLevel() : _level);
const QuestXPEntry* xpentry = sQuestXPStore.LookupEntry(quest_level);
if (!xpentry)
return 0;
int32 diffFactor = 2 * (quest_level - player->getLevel()) + 20;
if (diffFactor < 1)
diffFactor = 1;
else if (diffFactor > 10)
diffFactor = 10;
uint32 xp = RoundXPValue(diffFactor * xpentry->Difficulty[_rewardXPDifficulty] / 10);
if (sWorld->getIntConfig(CONFIG_MIN_QUEST_SCALED_XP_RATIO))
{
uint32 minScaledXP = RoundXPValue(xpentry->Difficulty[_rewardXPDifficulty]) * sWorld->getIntConfig(CONFIG_MIN_QUEST_SCALED_XP_RATIO) / 100;
xp = std::max(minScaledXP, xp);
}
return xp;
uint32 minScaledXP = RoundXPValue(xpentry->Difficulty[xpDifficulty]) * sWorld->getIntConfig(CONFIG_MIN_QUEST_SCALED_XP_RATIO) / 100;
xp = std::max(minScaledXP, xp);
}
return 0;
return xp;
}
/*static*/ bool Quest::IsTakingQuestEnabled(uint32 questId)
@@ -409,7 +412,7 @@ bool Quest::CanIncreaseRewardedQuestCounters() const
return (!IsDFQuest() && !IsDaily() && (!IsRepeatable() || IsWeekly() || IsMonthly() || IsSeasonal()));
}
uint32 Quest::RoundXPValue(uint32 xp)
/*static*/ uint32 Quest::RoundXPValue(uint32 xp)
{
if (xp <= 100)
return 5 * ((xp + 2) / 5);
+3 -3
View File
@@ -237,6 +237,7 @@ class TC_GAME_API Quest
void LoadQuestMailSender(Field* fields);
uint32 GetXPReward(Player const* player) const;
static uint32 CalcXPReward(uint8 playerLevel, int32 targetLevel, uint8 xpDifficulty);
bool HasFlag(uint32 flag) const { return (_flags & flag) != 0; }
void SetFlag(uint32 flag) { _flags |= flag; }
@@ -372,6 +373,8 @@ class TC_GAME_API Quest
void BuildQuestRewards(WorldPackets::Quest::QuestRewards& rewards, Player* player) const;
static uint32 RoundXPValue(uint32 xp);
static void AddQuestLevelToTitle(std::string& title, int32 level);
void InitializeQueryData();
WorldPacket BuildQueryData(LocaleConstant loc) const;
@@ -468,9 +471,6 @@ class TC_GAME_API Quest
uint32 _specialFlags = 0; // custom flags, not sniffed/WDB
uint32 _allowableRaces = 0;
uint32 _timeAllowed = 0;
// Helpers
static uint32 RoundXPValue(uint32 xp);
};
struct QuestStatusData
+20 -6
View File
@@ -53,6 +53,7 @@
#include "Pet.h"
#include "PhasingHandler.h"
#include "Player.h"
#include "QuestDef.h"
#include "ReputationMgr.h"
#include "ScriptMgr.h"
#include "SharedDefines.h"
@@ -1655,10 +1656,10 @@ void Spell::EffectOpenLock(SpellEffIndex effIndex)
ObjectGuid guid;
// Get lockId
GameObjectTemplate const* goInfo;
if (gameObjTarget)
{
GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
goInfo = gameObjTarget->GetGOInfo();
if (goInfo->CannotBeUsedUnderImmunity() && m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE))
return;
@@ -1711,7 +1712,7 @@ void Spell::EffectOpenLock(SpellEffIndex effIndex)
SkillType skillId = SKILL_NONE;
int32 reqSkillValue = 0;
int32 skillValue;
int32 skillValue = 0;
SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
if (res != SPELL_CAST_OK)
@@ -1741,9 +1742,22 @@ void Spell::EffectOpenLock(SpellEffIndex effIndex)
{
if (gameObjTarget)
{
// Allow one skill-up until respawned
if (!gameObjTarget->IsInSkillupList(player->GetGUID().GetCounter()) && player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue))
gameObjTarget->AddToSkillupList(player->GetGUID().GetCounter());
// Only allow unique uses for gathering and experience rewards
if (!gameObjTarget->IsTappedByPlayer(player->GetGUID()))
{
gameObjTarget->AddPlayerToTapperList(player->GetGUID());
player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
if (goInfo->type == GAMEOBJECT_TYPE_CHEST)
{
// Chests, such as gathering nodes and treasure chests calculate their XP rewards just like quests
if (uint8 xpDifficulty = goInfo->chest.xpDifficulty)
{
int32 xpLevel = goInfo->chest.xpMinLevel;
player->GiveXP(Quest::CalcXPReward(player->getLevel(), xpLevel, xpDifficulty), nullptr);
}
}
}
}
else if (itemTarget)
{