From adfa88d23691a31df7348788158be1f7fa73ef24 Mon Sep 17 00:00:00 2001 From: Schmoozerd Date: Sun, 4 Dec 2011 19:17:00 +0100 Subject: [PATCH] [11857] Fix sent level in trainer spell list - this fixes problems especially with druid trainers * This allows to really overwrite required level for spells * Adds proper checks when buying * Fixes default level requirement Signed-off-by: Schmoozerd --- src/game/Creature.h | 7 ++++--- src/game/NPCHandler.cpp | 31 ++++++++++++++++++++----------- src/game/ObjectMgr.cpp | 4 +++- src/game/Player.cpp | 4 ++-- src/game/Player.h | 2 +- src/shared/revision_nr.h | 2 +- 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/game/Creature.h b/src/game/Creature.h index 6afba20b7..d4247b055 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -362,10 +362,10 @@ typedef std::list VendorItemCounts; struct TrainerSpell { - TrainerSpell() : spell(0), spellCost(0), reqSkill(0), reqSkillValue(0), reqLevel(0), learnedSpell(0) {} + TrainerSpell() : spell(0), spellCost(0), reqSkill(0), reqSkillValue(0), reqLevel(0), learnedSpell(0), isProvidedReqLevel(false) {} - TrainerSpell(uint32 _spell, uint32 _spellCost, uint32 _reqSkill, uint32 _reqSkillValue, uint32 _reqLevel, uint32 _learnedspell) - : spell(_spell), spellCost(_spellCost), reqSkill(_reqSkill), reqSkillValue(_reqSkillValue), reqLevel(_reqLevel), learnedSpell(_learnedspell) + TrainerSpell(uint32 _spell, uint32 _spellCost, uint32 _reqSkill, uint32 _reqSkillValue, uint32 _reqLevel, uint32 _learnedspell, bool _isProvidedReqLevel) + : spell(_spell), spellCost(_spellCost), reqSkill(_reqSkill), reqSkillValue(_reqSkillValue), reqLevel(_reqLevel), learnedSpell(_learnedspell), isProvidedReqLevel(_isProvidedReqLevel) {} uint32 spell; @@ -374,6 +374,7 @@ struct TrainerSpell uint32 reqSkillValue; uint32 reqLevel; uint32 learnedSpell; + bool isProvidedReqLevel; // helpers bool IsCastable() const { return learnedSpell != spell; } diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index db7b03504..438027006 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -119,7 +119,7 @@ void WorldSession::SendTrainerList(ObjectGuid guid) } -static void SendTrainerSpellHelper(WorldPacket& data, TrainerSpell const* tSpell, TrainerSpellState state, float fDiscountMod, bool can_learn_primary_prof, uint32 skillReqLevel) +static void SendTrainerSpellHelper(WorldPacket& data, TrainerSpell const* tSpell, TrainerSpellState state, float fDiscountMod, bool can_learn_primary_prof, uint32 reqLevel) { bool primary_prof_first_rank = sSpellMgr.IsPrimaryProfessionFirstRankSpell(tSpell->learnedSpell); SpellChainNode const* chain_node = sSpellMgr.GetSpellChainNode(tSpell->learnedSpell); @@ -131,7 +131,7 @@ static void SendTrainerSpellHelper(WorldPacket& data, TrainerSpell const* tSpell data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0); // primary prof. learn confirmation dialog data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state - data << uint8(skillReqLevel ? skillReqLevel : tSpell->reqLevel); + data << uint8(reqLevel); data << uint32(tSpell->reqSkill); data << uint32(tSpell->reqSkillValue); data << uint32(!tSpell->IsCastable() && chain_node ? (chain_node->prev ? chain_node->prev : chain_node->req) : 0); @@ -193,13 +193,15 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle) { TrainerSpell const* tSpell = &itr->second; - uint32 skillReqLevel = 0; - if(!_player->IsSpellFitByClassAndRace(tSpell->learnedSpell, &skillReqLevel)) + uint32 reqLevel = 0; + if(!_player->IsSpellFitByClassAndRace(tSpell->learnedSpell, &reqLevel)) continue; - TrainerSpellState state = _player->GetTrainerSpellState(tSpell); + reqLevel = tSpell->isProvidedReqLevel ? tSpell->reqLevel : std::max(reqLevel, tSpell->reqLevel); - SendTrainerSpellHelper(data, tSpell, state, fDiscountMod, can_learn_primary_prof, skillReqLevel); + TrainerSpellState state = _player->GetTrainerSpellState(tSpell, reqLevel); + + SendTrainerSpellHelper(data, tSpell, state, fDiscountMod, can_learn_primary_prof, reqLevel); ++count; } @@ -211,13 +213,15 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle) { TrainerSpell const* tSpell = &itr->second; - uint32 skillReqLevel = 0; - if(!_player->IsSpellFitByClassAndRace(tSpell->learnedSpell, &skillReqLevel)) + uint32 reqLevel = 0; + if(!_player->IsSpellFitByClassAndRace(tSpell->learnedSpell, &reqLevel)) continue; - TrainerSpellState state = _player->GetTrainerSpellState(tSpell); + reqLevel = tSpell->isProvidedReqLevel ? tSpell->reqLevel : std::max(reqLevel, tSpell->reqLevel); - SendTrainerSpellHelper(data, tSpell, state, fDiscountMod, can_learn_primary_prof, skillReqLevel); + TrainerSpellState state = _player->GetTrainerSpellState(tSpell, reqLevel); + + SendTrainerSpellHelper(data, tSpell, state, fDiscountMod, can_learn_primary_prof, reqLevel); ++count; } @@ -270,7 +274,12 @@ void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data ) return; // can't be learn, cheat? Or double learn with lags... - if (_player->GetTrainerSpellState(trainer_spell) != TRAINER_SPELL_GREEN) + uint32 reqLevel = 0; + if(!_player->IsSpellFitByClassAndRace(trainer_spell->learnedSpell, &reqLevel)) + return; + + reqLevel = trainer_spell->isProvidedReqLevel ? trainer_spell->reqLevel : std::max(reqLevel, trainer_spell->reqLevel); + if (_player->GetTrainerSpellState(trainer_spell, reqLevel) != TRAINER_SPELL_GREEN) return; // apply reputation discount diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index dc2e99ddf..d9318e381 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -8269,6 +8269,8 @@ void ObjectMgr::LoadTrainers(char const* tableName, bool isTemplates) trainerSpell.reqSkillValue = fields[4].GetUInt32(); trainerSpell.reqLevel = fields[5].GetUInt32(); + trainerSpell.isProvidedReqLevel = trainerSpell.reqLevel > 0; + // calculate learned spell for profession case when stored cast-spell trainerSpell.learnedSpell = spell; for(int i = 0; i < MAX_EFFECT_INDEX; ++i) @@ -8290,7 +8292,7 @@ void ObjectMgr::LoadTrainers(char const* tableName, bool isTemplates) } // already checked as valid spell so exist. - SpellEntry const *learnSpellinfo = sSpellStore.LookupEntry(trainerSpell.learnedSpell); + SpellEntry const* learnSpellinfo = sSpellStore.LookupEntry(trainerSpell.learnedSpell); if (SpellMgr::IsProfessionSpell(trainerSpell.learnedSpell)) { data.trainerType = 2; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 91f1fb038..73f1a5b0c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -4003,7 +4003,7 @@ bool Player::HasActiveSpell(uint32 spell) const itr->second.active && !itr->second.disabled); } -TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell) const +TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell, uint32 reqLevel) const { if (!trainer_spell) return TRAINER_SPELL_RED; @@ -4023,7 +4023,7 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell // check level requirement if (!prof || GetSession()->GetSecurity() < AccountTypes(sWorld.getConfig(CONFIG_UINT32_TRADE_SKILL_GMIGNORE_LEVEL))) - if (getLevel() < trainer_spell->reqLevel) + if (getLevel() < reqLevel) return TRAINER_SPELL_RED; if(SpellChainNode const* spell_chain = sSpellMgr.GetSpellChainNode(trainer_spell->learnedSpell)) diff --git a/src/game/Player.h b/src/game/Player.h index 688093d8f..836baf211 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1564,7 +1564,7 @@ class MANGOS_DLL_SPEC Player : public Unit bool HasSpell(uint32 spell) const; bool HasActiveSpell(uint32 spell) const; // show in spellbook - TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell) const; + TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell, uint32 reqLevel) const; bool IsSpellFitByClassAndRace(uint32 spell_id, uint32* pReqlevel = NULL) const; bool IsNeedCastPassiveLikeSpellAtLearn(SpellEntry const* spellInfo) const; bool IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index) const; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0a9852fe2..0bec18fd7 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11856" + #define REVISION_NR "11857" #endif // __REVISION_NR_H__