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:
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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user