*Fix some bugs about pet spells: such as cannot cast/cannot autocast.
--HG-- branch : trunk
This commit is contained in:
+13
-27
@@ -272,12 +272,6 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_LoadSpells();
|
|
||||||
_LoadSpellCooldowns();
|
|
||||||
LearnPetPassives();
|
|
||||||
InitLevelupSpellsForLevel();
|
|
||||||
CastPetAuras(current);
|
|
||||||
|
|
||||||
// Load action bar data
|
// Load action bar data
|
||||||
if (!is_temporary_summoned)
|
if (!is_temporary_summoned)
|
||||||
{
|
{
|
||||||
@@ -297,17 +291,8 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||||||
m_charmInfo->GetActionBarEntry(index)->Type = atol((*iter).c_str());
|
m_charmInfo->GetActionBarEntry(index)->Type = atol((*iter).c_str());
|
||||||
++iter;
|
++iter;
|
||||||
m_charmInfo->GetActionBarEntry(index)->SpellOrAction = atol((*iter).c_str());
|
m_charmInfo->GetActionBarEntry(index)->SpellOrAction = atol((*iter).c_str());
|
||||||
|
if(m_charmInfo->GetActionBarEntry(index)->Type == ACT_ENABLED && !IsAutocastableSpell(m_charmInfo->GetActionBarEntry(index)->SpellOrAction))
|
||||||
// patch for old data where some spells have ACT_DECIDE but should have ACT_CAST
|
m_charmInfo->GetActionBarEntry(index)->Type = ACT_PASSIVE;
|
||||||
// so overwrite old state
|
|
||||||
if(SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_charmInfo->GetActionBarEntry(index)->SpellOrAction))
|
|
||||||
{
|
|
||||||
if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET)
|
|
||||||
m_charmInfo->GetActionBarEntry(index)->Type = ACT_DISABLED;
|
|
||||||
|
|
||||||
if(m_charmInfo->GetActionBarEntry(index)->Type == ACT_ENABLED)
|
|
||||||
ToggleAutocast(spellInfo->Id, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//init teach spells
|
//init teach spells
|
||||||
@@ -323,6 +308,12 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_LoadSpells();
|
||||||
|
_LoadSpellCooldowns();
|
||||||
|
LearnPetPassives();
|
||||||
|
InitLevelupSpellsForLevel();
|
||||||
|
CastPetAuras(current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1249,10 +1240,6 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// same spells don't have autocast option
|
|
||||||
if (spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET)
|
|
||||||
active = ACT_DISABLED;
|
|
||||||
|
|
||||||
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())
|
||||||
{
|
{
|
||||||
@@ -1285,10 +1272,10 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel
|
|||||||
|
|
||||||
if(active == ACT_DECIDE) //active was not used before, so we save it's autocast/passive state here
|
if(active == ACT_DECIDE) //active was not used before, so we save it's autocast/passive state here
|
||||||
{
|
{
|
||||||
if(IsPassiveSpell(spell_id))
|
if(IsAutocastableSpell(spell_id))
|
||||||
newspell.active = ACT_PASSIVE;
|
|
||||||
else
|
|
||||||
newspell.active = ACT_DISABLED;
|
newspell.active = ACT_DISABLED;
|
||||||
|
else
|
||||||
|
newspell.active = ACT_PASSIVE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
newspell.active = active;
|
newspell.active = active;
|
||||||
@@ -1344,8 +1331,7 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel
|
|||||||
if (IsPassiveSpell(spell_id))
|
if (IsPassiveSpell(spell_id))
|
||||||
CastSpell(this, spell_id, true);
|
CastSpell(this, spell_id, true);
|
||||||
else
|
else
|
||||||
//m_charmInfo->AddSpellToAB(oldspell_id, spell_id);
|
m_charmInfo->AddSpellToAB(oldspell_id, spell_id);
|
||||||
m_charmInfo->AddSpellToAB(oldspell_id, spell_id, (ActiveStates)active);
|
|
||||||
|
|
||||||
if(newspell.active == ACT_ENABLED)
|
if(newspell.active == ACT_ENABLED)
|
||||||
ToggleAutocast(spell_id, true);
|
ToggleAutocast(spell_id, true);
|
||||||
@@ -1668,7 +1654,7 @@ uint8 Pet::GetMaxTalentPointsForLevel(uint32 level)
|
|||||||
|
|
||||||
void Pet::ToggleAutocast(uint32 spellid, bool apply)
|
void Pet::ToggleAutocast(uint32 spellid, bool apply)
|
||||||
{
|
{
|
||||||
if(IsPassiveSpell(spellid))
|
if(!IsAutocastableSpell(spellid))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PetSpellMap::iterator itr = m_spells.find(spellid);
|
PetSpellMap::iterator itr = m_spells.find(spellid);
|
||||||
|
|||||||
+3
-4
@@ -70,10 +70,9 @@ enum PetSpellType
|
|||||||
|
|
||||||
struct PetSpell
|
struct PetSpell
|
||||||
{
|
{
|
||||||
ActiveStates active : 16;
|
ActiveStates active;
|
||||||
|
PetSpellState state;
|
||||||
PetSpellState state : 8;
|
PetSpellType type;
|
||||||
PetSpellType type : 8;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ActionFeedback
|
enum ActionFeedback
|
||||||
|
|||||||
+6
-10
@@ -4649,28 +4649,25 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
|
|||||||
if(m_caster->isInCombat() && IsNonCombatSpell(m_spellInfo))
|
if(m_caster->isInCombat() && IsNonCombatSpell(m_spellInfo))
|
||||||
return SPELL_FAILED_AFFECTING_COMBAT;
|
return SPELL_FAILED_AFFECTING_COMBAT;
|
||||||
|
|
||||||
if(m_caster->GetTypeId()==TYPEID_UNIT && (((Creature*)m_caster)->isPet() || m_caster->isCharmed()))
|
|
||||||
{
|
|
||||||
//dead owner (pets still alive when owners ressed?)
|
//dead owner (pets still alive when owners ressed?)
|
||||||
if(m_caster->GetCharmerOrOwner() && !m_caster->GetCharmerOrOwner()->isAlive())
|
if(Unit *owner = m_caster->GetCharmerOrOwner())
|
||||||
|
if(!owner->isAlive())
|
||||||
return SPELL_FAILED_CASTER_DEAD;
|
return SPELL_FAILED_CASTER_DEAD;
|
||||||
|
|
||||||
if(!target && m_targets.getUnitTarget())
|
if(!target && m_targets.getUnitTarget())
|
||||||
target = m_targets.getUnitTarget();
|
target = m_targets.getUnitTarget();
|
||||||
|
|
||||||
bool need = false;
|
for(uint32 i = 0; i < 3; ++i)
|
||||||
for(uint32 i = 0;i<3;i++)
|
|
||||||
{
|
{
|
||||||
if(m_spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_TARGET_ENEMY || m_spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_TARGET_ALLY || m_spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_TARGET_ANY || m_spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_TARGET_PARTY || m_spellInfo->EffectImplicitTargetA[i] == TARGET_DST_TARGET_ENEMY)
|
if(spellmgr.SpellTargetType[m_spellInfo->EffectImplicitTargetA[i]] == TARGET_TYPE_UNIT_TARGET
|
||||||
|
|| spellmgr.SpellTargetType[m_spellInfo->EffectImplicitTargetA[i]] == TARGET_TYPE_DEST_TARGET)
|
||||||
{
|
{
|
||||||
need = true;
|
|
||||||
if(!target)
|
if(!target)
|
||||||
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
|
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
|
||||||
|
m_targets.setUnitTarget(target);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(need)
|
|
||||||
m_targets.setUnitTarget(target);
|
|
||||||
|
|
||||||
Unit* _target = m_targets.getUnitTarget();
|
Unit* _target = m_targets.getUnitTarget();
|
||||||
|
|
||||||
@@ -4685,7 +4682,6 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
|
|||||||
//cooldown
|
//cooldown
|
||||||
if(((Creature*)m_caster)->HasSpellCooldown(m_spellInfo->Id))
|
if(((Creature*)m_caster)->HasSpellCooldown(m_spellInfo->Id))
|
||||||
return SPELL_FAILED_NOT_READY;
|
return SPELL_FAILED_NOT_READY;
|
||||||
}
|
|
||||||
|
|
||||||
return CheckCast(true);
|
return CheckCast(true);
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-12
@@ -11762,20 +11762,26 @@ void CharmInfo::InitCharmCreateSpells()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ActiveStates newstate;
|
ActiveStates newstate;
|
||||||
bool onlyselfcast = true;
|
if(spellInfo)
|
||||||
|
|
||||||
if(!spellInfo) onlyselfcast = false;
|
|
||||||
for(uint32 i = 0;i<3 && onlyselfcast;++i) //non existent spell will not make any problems as onlyselfcast would be false -> break right away
|
|
||||||
{
|
{
|
||||||
if(spellInfo->EffectImplicitTargetA[i] != TARGET_UNIT_CASTER && spellInfo->EffectImplicitTargetA[i] != 0)
|
if(!IsAutocastableSpell(spellId))
|
||||||
onlyselfcast = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(onlyselfcast || !IsPositiveSpell(spellId)) //only self cast and spells versus enemies are autocastable
|
|
||||||
newstate = ACT_DISABLED;
|
|
||||||
else
|
|
||||||
newstate = ACT_PASSIVE;
|
newstate = ACT_PASSIVE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool autocast = false;
|
||||||
|
for(uint32 i = 0; i < 3 && !autocast; ++i)
|
||||||
|
if(spellmgr.SpellTargetType[spellInfo->EffectImplicitTargetA[i]] == TARGET_TYPE_UNIT_TARGET)
|
||||||
|
autocast = true;
|
||||||
|
|
||||||
|
if(autocast)
|
||||||
|
{
|
||||||
|
newstate = ACT_ENABLED;
|
||||||
|
ToggleCreatureAutocast(spellId, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
newstate = ACT_DISABLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
AddSpellToAB(0, spellId, newstate);
|
AddSpellToAB(0, spellId, newstate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11799,7 +11805,9 @@ bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate)
|
|||||||
PetActionBar[i].SpellOrAction = newid;
|
PetActionBar[i].SpellOrAction = newid;
|
||||||
if (!oldid)
|
if (!oldid)
|
||||||
{
|
{
|
||||||
if (newstate == ACT_DECIDE)
|
if(!IsAutocastableSpell(newid))
|
||||||
|
PetActionBar[i].Type = ACT_PASSIVE;
|
||||||
|
else if (newstate == ACT_DECIDE)
|
||||||
PetActionBar[i].Type = ACT_DISABLED;
|
PetActionBar[i].Type = ACT_DISABLED;
|
||||||
else
|
else
|
||||||
PetActionBar[i].Type = newstate;
|
PetActionBar[i].Type = newstate;
|
||||||
|
|||||||
Reference in New Issue
Block a user