mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 07:37:01 +00:00
[7838] More fixes in pet's levelup spells.
* Fixed not updating levelup spells at warlock pet summon firsy time (overwriting by default original ranks in fact) * Correctly upgrade/doungrade spell ranks in action bar. * Fixed spell learning spam at warlock pet re-summon in some cases. TODO: currently (before this commit and in it) PetSpellInitialize() called too oftern. Maybe possible cache update flag and do it one time somewhere in Pet::Update....
This commit is contained in:
parent
8cf9dc035b
commit
122c9c5785
6 changed files with 97 additions and 48 deletions
|
|
@ -4792,13 +4792,10 @@ bool ChatHandler::HandleResetLevelCommand(const char * args)
|
||||||
player->InitTalentForLevel();
|
player->InitTalentForLevel();
|
||||||
player->SetUInt32Value(PLAYER_XP,0);
|
player->SetUInt32Value(PLAYER_XP,0);
|
||||||
|
|
||||||
// reset level to summoned pet
|
// reset level for pet
|
||||||
Pet* pet = player->GetPet();
|
if(Pet* pet = player->GetPet())
|
||||||
if(pet && pet->getPetType()==SUMMON_PET)
|
pet->SynchronizeLevelWithOwner();
|
||||||
{
|
|
||||||
pet->InitStatsForLevel(1);
|
|
||||||
pet->InitTalentForLevel();
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -340,6 +340,8 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InitLevelupSpellsForLevel();
|
||||||
|
|
||||||
m_loading = false;
|
m_loading = false;
|
||||||
|
|
||||||
SynchronizeLevelWithOwner();
|
SynchronizeLevelWithOwner();
|
||||||
|
|
@ -653,6 +655,9 @@ bool Pet::CanTakeMoreActiveSpells(uint32 spellid)
|
||||||
|
|
||||||
for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
|
for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
|
||||||
{
|
{
|
||||||
|
if(itr->second.state == PETSPELL_REMOVED)
|
||||||
|
continue;
|
||||||
|
|
||||||
if(IsPassiveSpell(itr->first))
|
if(IsPassiveSpell(itr->first))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -746,6 +751,7 @@ void Pet::GivePetLevel(uint32 level)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
InitStatsForLevel(level);
|
InitStatsForLevel(level);
|
||||||
|
InitLevelupSpellsForLevel();
|
||||||
InitTalentForLevel();
|
InitTalentForLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -994,9 +1000,6 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
|
||||||
for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
|
for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
|
||||||
SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(createResistance[i]));
|
SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(createResistance[i]));
|
||||||
|
|
||||||
if(cinfo->family)
|
|
||||||
learnLevelupSpells();
|
|
||||||
|
|
||||||
UpdateAllStats();
|
UpdateAllStats();
|
||||||
|
|
||||||
SetHealth(GetMaxHealth());
|
SetHealth(GetMaxHealth());
|
||||||
|
|
@ -1118,7 +1121,7 @@ void Pet::_LoadSpells()
|
||||||
{
|
{
|
||||||
Field *fields = result->Fetch();
|
Field *fields = result->Fetch();
|
||||||
|
|
||||||
addSpell(fields[0].GetUInt32(), fields[1].GetUInt16(), PETSPELL_UNCHANGED);
|
addSpell(fields[0].GetUInt32(), ActiveStates(fields[1].GetUInt16()), PETSPELL_UNCHANGED);
|
||||||
}
|
}
|
||||||
while( result->NextRow() );
|
while( result->NextRow() );
|
||||||
|
|
||||||
|
|
@ -1284,7 +1287,7 @@ void Pet::_SaveAuras()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pet::addSpell(uint32 spell_id,uint16 active /*= ACT_DECIDE*/, PetSpellState state /*= PETSPELL_NEW*/, PetSpellType type /*= PETSPELL_NORMAL*/)
|
bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpellState state /*= PETSPELL_NEW*/, PetSpellType type /*= PETSPELL_NORMAL*/)
|
||||||
{
|
{
|
||||||
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
|
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
|
||||||
if (!spellInfo)
|
if (!spellInfo)
|
||||||
|
|
@ -1356,26 +1359,33 @@ bool Pet::addSpell(uint32 spell_id,uint16 active /*= ACT_DECIDE*/, PetSpellState
|
||||||
// skip unknown ranks
|
// skip unknown ranks
|
||||||
if(!HasSpell(rankSpellId))
|
if(!HasSpell(rankSpellId))
|
||||||
continue;
|
continue;
|
||||||
removeSpell(rankSpellId);
|
removeSpell(rankSpellId,false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id))
|
else if(spellmgr.GetSpellRank(spell_id)!=0)
|
||||||
{
|
{
|
||||||
for (PetSpellMap::const_iterator itr2 = m_spells.begin(); itr2 != m_spells.end(); ++itr2)
|
for (PetSpellMap::const_iterator itr2 = m_spells.begin(); itr2 != m_spells.end(); ++itr2)
|
||||||
{
|
{
|
||||||
if(itr2->second.state == PETSPELL_REMOVED) continue;
|
if(itr2->second.state == PETSPELL_REMOVED) continue;
|
||||||
|
|
||||||
if(spellmgr.GetFirstSpellInChain(itr2->first) == chainstart)
|
if( spellmgr.IsRankSpellDueToSpell(spellInfo,itr2->first) )
|
||||||
{
|
{
|
||||||
newspell.active = itr2->second.active;
|
// replace by new high rank
|
||||||
|
if(spellmgr.IsHighRankOfSpell(spell_id,itr2->first))
|
||||||
|
{
|
||||||
|
newspell.active = itr2->second.active;
|
||||||
|
|
||||||
if(newspell.active == ACT_ENABLED)
|
if(newspell.active == ACT_ENABLED)
|
||||||
ToggleAutocast(itr2->first, false);
|
ToggleAutocast(itr2->first, false);
|
||||||
|
|
||||||
oldspell_id = itr2->first;
|
oldspell_id = itr2->first;
|
||||||
unlearnSpell(itr2->first);
|
unlearnSpell(itr2->first,false);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
// ignore new lesser rank
|
||||||
|
else if(spellmgr.IsHighRankOfSpell(itr2->first,spell_id))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1384,7 +1394,7 @@ bool Pet::addSpell(uint32 spell_id,uint16 active /*= ACT_DECIDE*/, PetSpellState
|
||||||
|
|
||||||
if (IsPassiveSpell(spell_id))
|
if (IsPassiveSpell(spell_id))
|
||||||
CastSpell(this, spell_id, true);
|
CastSpell(this, spell_id, true);
|
||||||
else if(state == PETSPELL_NEW)
|
else
|
||||||
m_charmInfo->AddSpellToAB(oldspell_id, spell_id);
|
m_charmInfo->AddSpellToAB(oldspell_id, spell_id);
|
||||||
|
|
||||||
if(newspell.active == ACT_ENABLED)
|
if(newspell.active == ACT_ENABLED)
|
||||||
|
|
@ -1422,26 +1432,33 @@ bool Pet::learnSpell(uint32 spell_id)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pet::learnLevelupSpells()
|
void Pet::InitLevelupSpellsForLevel()
|
||||||
{
|
{
|
||||||
PetLevelupSpellSet const *levelupSpells = spellmgr.GetPetLevelupSpellList(GetCreatureInfo()->family);
|
uint32 family = GetCreatureInfo()->family;
|
||||||
|
if(!family)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PetLevelupSpellSet const *levelupSpells = spellmgr.GetPetLevelupSpellList(family);
|
||||||
if(!levelupSpells)
|
if(!levelupSpells)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32 level = getLevel();
|
uint32 level = getLevel();
|
||||||
|
|
||||||
for(PetLevelupSpellSet::const_iterator itr = levelupSpells->begin(); itr != levelupSpells->end(); ++itr)
|
// PetLevelupSpellSet ordered by levels, process in reversed order
|
||||||
|
for(PetLevelupSpellSet::const_reverse_iterator itr = levelupSpells->rbegin(); itr != levelupSpells->rend(); ++itr)
|
||||||
{
|
{
|
||||||
if(itr->first <= level)
|
// will called first if level down
|
||||||
learnSpell(itr->second);
|
if(itr->first > level)
|
||||||
|
unlearnSpell(itr->second,true); // will learn prev rank if any
|
||||||
|
// will called if level up
|
||||||
else
|
else
|
||||||
unlearnSpell(itr->second);
|
learnSpell(itr->second); // will unlearn prev rank if any
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pet::unlearnSpell(uint32 spell_id)
|
bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev)
|
||||||
{
|
{
|
||||||
if(removeSpell(spell_id))
|
if(removeSpell(spell_id,learn_prev))
|
||||||
{
|
{
|
||||||
if(GetOwner()->GetTypeId() == TYPEID_PLAYER)
|
if(GetOwner()->GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
|
|
@ -1457,7 +1474,7 @@ bool Pet::unlearnSpell(uint32 spell_id)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pet::removeSpell(uint32 spell_id)
|
bool Pet::removeSpell(uint32 spell_id, bool learn_prev)
|
||||||
{
|
{
|
||||||
PetSpellMap::iterator itr = m_spells.find(spell_id);
|
PetSpellMap::iterator itr = m_spells.find(spell_id);
|
||||||
if (itr == m_spells.end())
|
if (itr == m_spells.end())
|
||||||
|
|
@ -1485,6 +1502,27 @@ bool Pet::removeSpell(uint32 spell_id)
|
||||||
SetFreeTalentPoints(free_points > 0 ? free_points : 0);
|
SetFreeTalentPoints(free_points > 0 ? free_points : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (learn_prev)
|
||||||
|
{
|
||||||
|
if (uint32 prev_id = spellmgr.GetPrevSpellInChain (spell_id))
|
||||||
|
{
|
||||||
|
// replace to next spell
|
||||||
|
if(!talentCost && !IsPassiveSpell(prev_id))
|
||||||
|
m_charmInfo->AddSpellToAB(spell_id, prev_id);
|
||||||
|
|
||||||
|
learnSpell(prev_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_charmInfo->AddSpellToAB(spell_id, 0);
|
||||||
|
|
||||||
|
// need update action bar for last removed rank
|
||||||
|
if (Unit* owner = GetOwner())
|
||||||
|
if (owner->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
((Player*)owner)->PetSpellInitialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1620,7 +1658,7 @@ bool Pet::resetTalents(bool no_cost)
|
||||||
// unlearn if first rank is talent or learned by talent
|
// unlearn if first rank is talent or learned by talent
|
||||||
if (itrFirstId == talentInfo->RankID[j] || spellmgr.IsSpellLearnToSpell(talentInfo->RankID[j],itrFirstId))
|
if (itrFirstId == talentInfo->RankID[j] || spellmgr.IsSpellLearnToSpell(talentInfo->RankID[j],itrFirstId))
|
||||||
{
|
{
|
||||||
removeSpell(itr->first);
|
removeSpell(itr->first,false);
|
||||||
itr = m_spells.begin();
|
itr = m_spells.begin();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ enum PetSpellType
|
||||||
|
|
||||||
struct PetSpell
|
struct PetSpell
|
||||||
{
|
{
|
||||||
uint16 active;
|
ActiveStates active : 16;
|
||||||
|
|
||||||
PetSpellState state : 8;
|
PetSpellState state : 8;
|
||||||
PetSpellType type : 8;
|
PetSpellType type : 8;
|
||||||
|
|
@ -196,12 +196,12 @@ class Pet : public Creature
|
||||||
void _LoadSpells();
|
void _LoadSpells();
|
||||||
void _SaveSpells();
|
void _SaveSpells();
|
||||||
|
|
||||||
bool addSpell(uint32 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
|
bool addSpell(uint32 spell_id,ActiveStates active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
|
||||||
bool learnSpell(uint32 spell_id);
|
bool learnSpell(uint32 spell_id);
|
||||||
void learnSpellHighRank(uint32 spellid);
|
void learnSpellHighRank(uint32 spellid);
|
||||||
void learnLevelupSpells();
|
void InitLevelupSpellsForLevel();
|
||||||
bool unlearnSpell(uint32 spell_id);
|
bool unlearnSpell(uint32 spell_id, bool learn_prev);
|
||||||
bool removeSpell(uint32 spell_id);
|
bool removeSpell(uint32 spell_id, bool learn_prev);
|
||||||
|
|
||||||
PetSpellMap m_spells;
|
PetSpellMap m_spells;
|
||||||
TeachSpellMap m_teachspells;
|
TeachSpellMap m_teachspells;
|
||||||
|
|
|
||||||
|
|
@ -3259,6 +3259,7 @@ void Spell::EffectSummon(uint32 i)
|
||||||
|
|
||||||
spawnCreature->AIM_Initialize();
|
spawnCreature->AIM_Initialize();
|
||||||
spawnCreature->InitPetCreateSpells();
|
spawnCreature->InitPetCreateSpells();
|
||||||
|
spawnCreature->InitLevelupSpellsForLevel();
|
||||||
spawnCreature->SetHealth(spawnCreature->GetMaxHealth());
|
spawnCreature->SetHealth(spawnCreature->GetMaxHealth());
|
||||||
spawnCreature->SetPower(POWER_MANA, spawnCreature->GetMaxPower(POWER_MANA));
|
spawnCreature->SetPower(POWER_MANA, spawnCreature->GetMaxPower(POWER_MANA));
|
||||||
|
|
||||||
|
|
@ -4171,6 +4172,7 @@ void Spell::EffectSummonPet(uint32 i)
|
||||||
|
|
||||||
NewSummon->InitStatsForLevel(petlevel);
|
NewSummon->InitStatsForLevel(petlevel);
|
||||||
NewSummon->InitPetCreateSpells();
|
NewSummon->InitPetCreateSpells();
|
||||||
|
NewSummon->InitLevelupSpellsForLevel();
|
||||||
NewSummon->InitTalentForLevel();
|
NewSummon->InitTalentForLevel();
|
||||||
|
|
||||||
if(NewSummon->getPetType()==SUMMON_PET)
|
if(NewSummon->getPetType()==SUMMON_PET)
|
||||||
|
|
@ -5967,6 +5969,7 @@ void Spell::EffectSummonCritter(uint32 i)
|
||||||
|
|
||||||
critter->AIM_Initialize();
|
critter->AIM_Initialize();
|
||||||
critter->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as critter...
|
critter->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as critter...
|
||||||
|
//critter->InitLevelupSpellsForLevel(); // none?
|
||||||
critter->SelectLevel(critter->GetCreatureInfo()); // some summoned creaters have different from 1 DB data for level/hp
|
critter->SelectLevel(critter->GetCreatureInfo()); // some summoned creaters have different from 1 DB data for level/hp
|
||||||
critter->SetUInt32Value(UNIT_NPC_FLAGS, critter->GetCreatureInfo()->npcflag);
|
critter->SetUInt32Value(UNIT_NPC_FLAGS, critter->GetCreatureInfo()->npcflag);
|
||||||
// some mini-pets have quests
|
// some mini-pets have quests
|
||||||
|
|
|
||||||
|
|
@ -10396,20 +10396,30 @@ void CharmInfo::InitCharmCreateSpells()
|
||||||
|
|
||||||
bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate)
|
bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate)
|
||||||
{
|
{
|
||||||
|
// new spell already listed for example in case prepered switch to lesser rank in Pet::removeSpell
|
||||||
|
for(uint8 i = 0; i < 10; ++i)
|
||||||
|
if (PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE)
|
||||||
|
if (newid && PetActionBar[i].SpellOrAction == newid)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// old spell can be leasted for example in case learn high rank
|
||||||
for(uint8 i = 0; i < 10; ++i)
|
for(uint8 i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE) && PetActionBar[i].SpellOrAction == oldid)
|
if (PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE)
|
||||||
{
|
{
|
||||||
PetActionBar[i].SpellOrAction = newid;
|
if (PetActionBar[i].SpellOrAction == oldid)
|
||||||
if(!oldid)
|
|
||||||
{
|
{
|
||||||
if(newstate == ACT_DECIDE)
|
PetActionBar[i].SpellOrAction = newid;
|
||||||
PetActionBar[i].Type = ACT_DISABLED;
|
if (!oldid)
|
||||||
else
|
{
|
||||||
PetActionBar[i].Type = newstate;
|
if (newstate == ACT_DECIDE)
|
||||||
}
|
PetActionBar[i].Type = ACT_DISABLED;
|
||||||
|
else
|
||||||
|
PetActionBar[i].Type = newstate;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -11399,6 +11409,7 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)
|
||||||
// this enables pet details window (Shift+P)
|
// this enables pet details window (Shift+P)
|
||||||
pet->AIM_Initialize();
|
pet->AIM_Initialize();
|
||||||
pet->InitPetCreateSpells();
|
pet->InitPetCreateSpells();
|
||||||
|
pet->InitLevelupSpellsForLevel();
|
||||||
pet->InitTalentForLevel();
|
pet->InitTalentForLevel();
|
||||||
pet->SetHealth(pet->GetMaxHealth());
|
pet->SetHealth(pet->GetMaxHealth());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7837"
|
#define REVISION_NR "7838"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue