mirror of
https://github.com/mangosfour/server.git
synced 2025-12-30 01:37:03 +00:00
[7077] Implement support castable trainer spells for profession ranks.
This commit is contained in:
parent
fa9daa3fb7
commit
5b50e2f9e8
8 changed files with 262 additions and 23 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "7076"
|
||||
#define REVISION_NR "7077"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue