[7077] Implement support castable trainer spells for profession ranks.

This commit is contained in:
VladimirMangos 2009-01-13 21:05:34 +03:00
parent fa9daa3fb7
commit 5b50e2f9e8
8 changed files with 262 additions and 23 deletions

View file

@ -364,6 +364,10 @@ struct TrainerSpell
uint32 reqskill;
uint32 reqskillvalue;
uint32 reqlevel;
uint32 learned_spell;
// helpers
bool IsCastable() const { return learned_spell != spell; }
};
typedef std::vector<TrainerSpell*> TrainerSpellList;

View file

@ -164,16 +164,16 @@ void WorldSession::SendTrainerList( uint64 guid, const std::string& strTitle )
{
TrainerSpell const* tSpell = *itr;
if(!_player->IsSpellFitByClassAndRace(tSpell->spell))
if(!_player->IsSpellFitByClassAndRace(tSpell->learned_spell))
continue;
++count;
bool primary_prof_first_rank = spellmgr.IsPrimaryProfessionFirstRankSpell(tSpell->spell);
bool primary_prof_first_rank = spellmgr.IsPrimaryProfessionFirstRankSpell(tSpell->learned_spell);
SpellChainNode const* chain_node = spellmgr.GetSpellChainNode(tSpell->spell);
SpellChainNode const* chain_node = spellmgr.GetSpellChainNode(tSpell->learned_spell);
data << uint32(tSpell->spell);
data << uint32(tSpell->spell); // learned spell (or cast-spell in profession case)
data << uint8(_player->GetTrainerSpellState(tSpell));
data << uint32(floor(tSpell->spellcost * fDiscountMod));
@ -238,21 +238,27 @@ void WorldSession::HandleTrainerBuySpellOpcode( WorldPacket & recv_data )
if(_player->GetMoney() < nSpellCost )
return;
WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); // visual effect on trainer
data << uint64(guid) << uint32(0xB3);
SendPacket(&data);
data.Initialize(SMSG_PLAY_SPELL_IMPACT, 12); // visual effect on player
data << uint64(_player->GetGUID()) << uint32(0x016A);
SendPacket(&data);
_player->ModifyMoney( -int32(nSpellCost) );
// learn explicitly to prevent lost money at lags, learning spell will be only show spell animation
_player->learnSpell(trainer_spell->spell);
// learn explicitly or cast explicitly
if(trainer_spell->IsCastable ())
//FIXME: prof. spell entry in trainer list not marked gray until list re-open.
unit->CastSpell(_player,trainer_spell->spell,true);
else
{
WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 12); // visual effect on trainer
data << uint64(guid) << uint32(0xB3);
SendPacket(&data);
data.Initialize(SMSG_TRAINER_BUY_SUCCEEDED, 12);
data << uint64(guid) << uint32(spellId);
data.Initialize(SMSG_PLAY_SPELL_IMPACT, 12); // visual effect on player
data << uint64(_player->GetGUID()) << uint32(0x016A);
SendPacket(&data);
_player->learnSpell(spellId);
}
WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12);
data << uint64(guid) << uint32(trainer_spell->spell);
SendPacket(&data);
}

View file

@ -7040,6 +7040,19 @@ void ObjectMgr::LoadTrainerSpell()
if(!pTrainerSpell->reqlevel)
pTrainerSpell->reqlevel = spellinfo->spellLevel;
// calculate learned spell for profession case when stored cast-spell
pTrainerSpell->learned_spell = spell;
for(int i = 0; i <3; ++i)
{
if(spellinfo->Effect[i]!=SPELL_EFFECT_LEARN_SPELL)
continue;
if(SpellMgr::IsProfessionSpell(spellinfo->EffectTriggerSpell[i]))
{
pTrainerSpell->learned_spell = spellinfo->EffectTriggerSpell[i];
break;
}
}
TrainerSpellData& data = m_mCacheTrainerSpellMap[entry];

View file

@ -3451,22 +3451,22 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell
if (!trainer_spell)
return TRAINER_SPELL_RED;
if (!trainer_spell->spell)
if (!trainer_spell->learned_spell)
return TRAINER_SPELL_RED;
// known spell
if(HasSpell(trainer_spell->spell))
if(HasSpell(trainer_spell->learned_spell))
return TRAINER_SPELL_GRAY;
// check race/class requirement
if(!IsSpellFitByClassAndRace(trainer_spell->spell))
if(!IsSpellFitByClassAndRace(trainer_spell->learned_spell))
return TRAINER_SPELL_RED;
// check level requirement
if(getLevel() < trainer_spell->reqlevel)
return TRAINER_SPELL_RED;
if(SpellChainNode const* spell_chain = spellmgr.GetSpellChainNode(trainer_spell->spell))
if(SpellChainNode const* spell_chain = spellmgr.GetSpellChainNode(trainer_spell->learned_spell))
{
// check prev.rank requirement
if(spell_chain->prev && !HasSpell(spell_chain->prev))
@ -3482,7 +3482,7 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell
return TRAINER_SPELL_RED;
// exist, already checked at loading
SpellEntry const* spell = sSpellStore.LookupEntry(trainer_spell->spell);
SpellEntry const* spell = sSpellStore.LookupEntry(trainer_spell->learned_spell);
// secondary prof. or not prof. spell
uint32 skill = spell->EffectMiscValue[1];

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "7076"
#define REVISION_NR "7077"
#endif // __REVISION_NR_H__