*Fix some bugs about pet spells: such as cannot cast/cannot autocast.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-05-19 01:23:52 -05:00
parent 833ceee7c5
commit 2a2eff190c
4 changed files with 46 additions and 57 deletions
+13 -27
View File
@@ -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
View File
@@ -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
+9 -13
View File
@@ -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())
return SPELL_FAILED_CASTER_DEAD; if(!owner->isAlive())
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);
} }
@@ -4816,8 +4812,8 @@ bool Spell::CanAutoCast(Unit* target)
} }
else if ( IsAreaAuraEffect( m_spellInfo->Effect[j] )) else if ( IsAreaAuraEffect( m_spellInfo->Effect[j] ))
{ {
if( target->HasAuraEffect(m_spellInfo->Id, j) ) if( target->HasAuraEffect(m_spellInfo->Id, j) )
return false; return false;
} }
} }
+21 -13
View File
@@ -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; 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;
}
} }
if(onlyselfcast || !IsPositiveSpell(spellId)) //only self cast and spells versus enemies are autocastable
newstate = ACT_DISABLED;
else
newstate = ACT_PASSIVE;
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;