mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 10:37:02 +00:00
[7467] Use SpellCastResult and replace CanCast by CheckCast.
Note: proper way to check: if(spell->CheckCast(...)==SPELL_CAST_OK)
This commit is contained in:
parent
c1b0e7d57a
commit
0e987bf59e
6 changed files with 75 additions and 76 deletions
|
|
@ -294,7 +294,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||||
AIM_Initialize();
|
AIM_Initialize();
|
||||||
map->Add((Creature*)this);
|
map->Add((Creature*)this);
|
||||||
|
|
||||||
// Spells should be loaded after pet is added to map, because in CanCast is check on it
|
// Spells should be loaded after pet is added to map, because in CheckCast is check on it
|
||||||
_LoadSpells();
|
_LoadSpells();
|
||||||
_LoadSpellCooldowns();
|
_LoadSpellCooldowns();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -409,7 +409,7 @@ void Spell::FillTargetMap()
|
||||||
if(m_spellInfo->Effect[i]==0)
|
if(m_spellInfo->Effect[i]==0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// targets for TARGET_SCRIPT_COORDINATES (A) and TARGET_SCRIPT filled in Spell::canCast call
|
// targets for TARGET_SCRIPT_COORDINATES (A) and TARGET_SCRIPT filled in Spell::CheckCast call
|
||||||
if( m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT_COORDINATES ||
|
if( m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT_COORDINATES ||
|
||||||
m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT ||
|
m_spellInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT ||
|
||||||
m_spellInfo->EffectImplicitTargetB[i] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[i] != TARGET_SELF )
|
m_spellInfo->EffectImplicitTargetB[i] == TARGET_SCRIPT && m_spellInfo->EffectImplicitTargetA[i] != TARGET_SELF )
|
||||||
|
|
@ -466,7 +466,7 @@ void Spell::FillTargetMap()
|
||||||
case 0:
|
case 0:
|
||||||
SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap);
|
SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap);
|
||||||
break;
|
break;
|
||||||
case TARGET_SCRIPT_COORDINATES: // B case filled in canCast but we need fill unit list base at A case
|
case TARGET_SCRIPT_COORDINATES: // B case filled in CheckCast but we need fill unit list base at A case
|
||||||
SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap);
|
SetTargetMap(i,m_spellInfo->EffectImplicitTargetA[i],tmpUnitMap);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -2182,8 +2182,8 @@ void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura)
|
||||||
// Fill cost data
|
// Fill cost data
|
||||||
m_powerCost = CalculatePowerCost();
|
m_powerCost = CalculatePowerCost();
|
||||||
|
|
||||||
uint8 result = CanCast(true);
|
SpellCastResult result = CheckCast(true);
|
||||||
if(result != 0 && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
|
if(result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
|
||||||
{
|
{
|
||||||
if(triggeredByAura)
|
if(triggeredByAura)
|
||||||
{
|
{
|
||||||
|
|
@ -2198,7 +2198,7 @@ void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura)
|
||||||
// Prepare data for triggers
|
// Prepare data for triggers
|
||||||
prepareDataForTriggerSystem();
|
prepareDataForTriggerSystem();
|
||||||
|
|
||||||
// calculate cast time (calculated after first CanCast check to prevent charge counting for first CanCast fail)
|
// calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
|
||||||
m_casttime = GetSpellCastTime(m_spellInfo, this);
|
m_casttime = GetSpellCastTime(m_spellInfo, this);
|
||||||
|
|
||||||
// set timer base at cast time
|
// set timer base at cast time
|
||||||
|
|
@ -2283,7 +2283,7 @@ void Spell::cast(bool skipCheck)
|
||||||
if(m_caster->GetTypeId() != TYPEID_PLAYER && m_targets.getUnitTarget() && m_targets.getUnitTarget() != m_caster)
|
if(m_caster->GetTypeId() != TYPEID_PLAYER && m_targets.getUnitTarget() && m_targets.getUnitTarget() != m_caster)
|
||||||
m_caster->SetInFront(m_targets.getUnitTarget());
|
m_caster->SetInFront(m_targets.getUnitTarget());
|
||||||
|
|
||||||
uint8 castResult = CheckPower();
|
SpellCastResult castResult = CheckPower();
|
||||||
if(castResult != SPELL_CAST_OK)
|
if(castResult != SPELL_CAST_OK)
|
||||||
{
|
{
|
||||||
SendCastResult(castResult);
|
SendCastResult(castResult);
|
||||||
|
|
@ -2295,8 +2295,8 @@ void Spell::cast(bool skipCheck)
|
||||||
// triggered cast called from Spell::prepare where it was already checked
|
// triggered cast called from Spell::prepare where it was already checked
|
||||||
if(!skipCheck)
|
if(!skipCheck)
|
||||||
{
|
{
|
||||||
castResult = CanCast(false);
|
castResult = CheckCast(false);
|
||||||
if(castResult != 0)
|
if(castResult != SPELL_CAST_OK)
|
||||||
{
|
{
|
||||||
SendCastResult(castResult);
|
SendCastResult(castResult);
|
||||||
finish(false);
|
finish(false);
|
||||||
|
|
@ -2781,65 +2781,65 @@ void Spell::finish(bool ok)
|
||||||
m_caster->AttackStop();
|
m_caster->AttackStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::SendCastResult(uint8 result)
|
void Spell::SendCastResult(SpellCastResult result)
|
||||||
{
|
{
|
||||||
|
if(result == SPELL_CAST_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
if (m_caster->GetTypeId() != TYPEID_PLAYER)
|
if (m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(((Player*)m_caster)->GetSession()->PlayerLoading()) // don't send cast results at loading time
|
if(((Player*)m_caster)->GetSession()->PlayerLoading()) // don't send cast results at loading time
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(result != 0)
|
WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
|
||||||
|
data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
|
||||||
|
data << uint32(m_spellInfo->Id);
|
||||||
|
data << uint8(result); // problem
|
||||||
|
switch (result)
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_CAST_FAILED, (4+1+1));
|
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
|
||||||
data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
|
data << uint32(m_spellInfo->RequiresSpellFocus);
|
||||||
data << uint32(m_spellInfo->Id);
|
break;
|
||||||
data << uint8(result); // problem
|
case SPELL_FAILED_REQUIRES_AREA:
|
||||||
switch (result)
|
// hardcode areas limitation case
|
||||||
{
|
switch(m_spellInfo->Id)
|
||||||
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
|
{
|
||||||
data << uint32(m_spellInfo->RequiresSpellFocus);
|
case 41617: // Cenarion Mana Salve
|
||||||
break;
|
case 41619: // Cenarion Healing Salve
|
||||||
case SPELL_FAILED_REQUIRES_AREA:
|
data << uint32(3905);
|
||||||
// hardcode areas limitation case
|
break;
|
||||||
switch(m_spellInfo->Id)
|
case 41618: // Bottled Nethergon Energy
|
||||||
{
|
case 41620: // Bottled Nethergon Vapor
|
||||||
case 41617: // Cenarion Mana Salve
|
data << uint32(3842);
|
||||||
case 41619: // Cenarion Healing Salve
|
break;
|
||||||
data << uint32(3905);
|
case 45373: // Bloodberry Elixir
|
||||||
break;
|
data << uint32(4075);
|
||||||
case 41618: // Bottled Nethergon Energy
|
break;
|
||||||
case 41620: // Bottled Nethergon Vapor
|
default: // default case (don't must be)
|
||||||
data << uint32(3842);
|
data << uint32(0);
|
||||||
break;
|
break;
|
||||||
case 45373: // Bloodberry Elixir
|
}
|
||||||
data << uint32(4075);
|
break;
|
||||||
break;
|
case SPELL_FAILED_TOTEMS:
|
||||||
default: // default case (don't must be)
|
if(m_spellInfo->Totem[0])
|
||||||
data << uint32(0);
|
data << uint32(m_spellInfo->Totem[0]);
|
||||||
break;
|
if(m_spellInfo->Totem[1])
|
||||||
}
|
data << uint32(m_spellInfo->Totem[1]);
|
||||||
break;
|
break;
|
||||||
case SPELL_FAILED_TOTEMS:
|
case SPELL_FAILED_TOTEM_CATEGORY:
|
||||||
if(m_spellInfo->Totem[0])
|
if(m_spellInfo->TotemCategory[0])
|
||||||
data << uint32(m_spellInfo->Totem[0]);
|
data << uint32(m_spellInfo->TotemCategory[0]);
|
||||||
if(m_spellInfo->Totem[1])
|
if(m_spellInfo->TotemCategory[1])
|
||||||
data << uint32(m_spellInfo->Totem[1]);
|
data << uint32(m_spellInfo->TotemCategory[1]);
|
||||||
break;
|
break;
|
||||||
case SPELL_FAILED_TOTEM_CATEGORY:
|
case SPELL_FAILED_EQUIPPED_ITEM_CLASS:
|
||||||
if(m_spellInfo->TotemCategory[0])
|
data << uint32(m_spellInfo->EquippedItemClass);
|
||||||
data << uint32(m_spellInfo->TotemCategory[0]);
|
data << uint32(m_spellInfo->EquippedItemSubClassMask);
|
||||||
if(m_spellInfo->TotemCategory[1])
|
//data << uint32(m_spellInfo->EquippedItemInventoryTypeMask);
|
||||||
data << uint32(m_spellInfo->TotemCategory[1]);
|
break;
|
||||||
break;
|
|
||||||
case SPELL_FAILED_EQUIPPED_ITEM_CLASS:
|
|
||||||
data << uint32(m_spellInfo->EquippedItemClass);
|
|
||||||
data << uint32(m_spellInfo->EquippedItemSubClassMask);
|
|
||||||
//data << uint32(m_spellInfo->EquippedItemInventoryTypeMask);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
((Player*)m_caster)->GetSession()->SendPacket(&data);
|
|
||||||
}
|
}
|
||||||
|
((Player*)m_caster)->GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::SendSpellStart()
|
void Spell::SendSpellStart()
|
||||||
|
|
@ -3582,7 +3582,7 @@ void Spell::TriggerSpell()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 Spell::CanCast(bool strict)
|
SpellCastResult Spell::CheckCast(bool strict)
|
||||||
{
|
{
|
||||||
// check cooldowns to prevent cheating
|
// check cooldowns to prevent cheating
|
||||||
if(m_caster->GetTypeId()==TYPEID_PLAYER && ((Player*)m_caster)->HasSpellCooldown(m_spellInfo->Id))
|
if(m_caster->GetTypeId()==TYPEID_PLAYER && ((Player*)m_caster)->HasSpellCooldown(m_spellInfo->Id))
|
||||||
|
|
@ -3647,9 +3647,7 @@ uint8 Spell::CanCast(bool strict)
|
||||||
return SPELL_FAILED_MOVING;
|
return SPELL_FAILED_MOVING;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit *target = m_targets.getUnitTarget();
|
if(Unit *target = m_targets.getUnitTarget())
|
||||||
|
|
||||||
if(target)
|
|
||||||
{
|
{
|
||||||
// target state requirements (not allowed state), apply to self also
|
// target state requirements (not allowed state), apply to self also
|
||||||
if(m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot)))
|
if(m_spellInfo->TargetAuraStateNot && target->HasAuraState(AuraState(m_spellInfo->TargetAuraStateNot)))
|
||||||
|
|
@ -3813,7 +3811,7 @@ uint8 Spell::CanCast(bool strict)
|
||||||
}
|
}
|
||||||
|
|
||||||
//ImpliciteTargetA-B = 38, If fact there is 0 Spell with ImpliciteTargetB=38
|
//ImpliciteTargetA-B = 38, If fact there is 0 Spell with ImpliciteTargetB=38
|
||||||
if(m_UniqueTargetInfo.empty()) // skip second canCast apply (for delayed spells for example)
|
if(m_UniqueTargetInfo.empty()) // skip second CheckCast apply (for delayed spells for example)
|
||||||
{
|
{
|
||||||
for(uint8 j = 0; j < 3; j++)
|
for(uint8 j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
|
|
@ -3988,7 +3986,7 @@ uint8 Spell::CanCast(bool strict)
|
||||||
{
|
{
|
||||||
// spell different for friends and enemies
|
// spell different for friends and enemies
|
||||||
// hart version required facing
|
// hart version required facing
|
||||||
if(m_targets.getUnitTarget() && !m_caster->IsFriendlyTo(m_targets.getUnitTarget()) && !m_caster->HasInArc( M_PI, target ))
|
if(m_targets.getUnitTarget() && !m_caster->IsFriendlyTo(m_targets.getUnitTarget()) && !m_caster->HasInArc( M_PI, m_targets.getUnitTarget() ))
|
||||||
return SPELL_FAILED_UNIT_NOT_INFRONT;
|
return SPELL_FAILED_UNIT_NOT_INFRONT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -4393,7 +4391,7 @@ uint8 Spell::CanCast(bool strict)
|
||||||
}
|
}
|
||||||
|
|
||||||
// all ok
|
// all ok
|
||||||
return 0;
|
return SPELL_CAST_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 Spell::PetCanCast(Unit* target)
|
int16 Spell::PetCanCast(Unit* target)
|
||||||
|
|
@ -4460,8 +4458,8 @@ int16 Spell::PetCanCast(Unit* target)
|
||||||
return SPELL_FAILED_NOT_READY;
|
return SPELL_FAILED_NOT_READY;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 result = CanCast(true);
|
SpellCastResult result = CheckCast(true);
|
||||||
if(result != 0)
|
if(result != SPELL_CAST_OK)
|
||||||
return result;
|
return result;
|
||||||
else
|
else
|
||||||
return -1; //this allows to check spell fail 0, in combat
|
return -1; //this allows to check spell fail 0, in combat
|
||||||
|
|
|
||||||
|
|
@ -337,9 +337,9 @@ class Spell
|
||||||
void TakeReagents();
|
void TakeReagents();
|
||||||
void TakeCastItem();
|
void TakeCastItem();
|
||||||
void TriggerSpell();
|
void TriggerSpell();
|
||||||
uint8 CanCast(bool strict);
|
|
||||||
|
SpellCastResult CheckCast(bool strict);
|
||||||
int16 PetCanCast(Unit* target);
|
int16 PetCanCast(Unit* target);
|
||||||
bool CanAutoCast(Unit* target);
|
|
||||||
|
|
||||||
// handlers
|
// handlers
|
||||||
void handle_immediate();
|
void handle_immediate();
|
||||||
|
|
@ -372,8 +372,9 @@ class Spell
|
||||||
|
|
||||||
Unit* SelectMagnetTarget();
|
Unit* SelectMagnetTarget();
|
||||||
bool CheckTarget( Unit* target, uint32 eff );
|
bool CheckTarget( Unit* target, uint32 eff );
|
||||||
|
bool CanAutoCast(Unit* target);
|
||||||
|
|
||||||
void SendCastResult(uint8 result);
|
void SendCastResult(SpellCastResult result);
|
||||||
void SendSpellStart();
|
void SendSpellStart();
|
||||||
void SendSpellGo();
|
void SendSpellGo();
|
||||||
void SendSpellCooldown();
|
void SendSpellCooldown();
|
||||||
|
|
|
||||||
|
|
@ -2964,7 +2964,7 @@ void Spell::EffectOpenLock(uint32 effIndex)
|
||||||
if( goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune ||
|
if( goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune ||
|
||||||
goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK )
|
goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK )
|
||||||
{
|
{
|
||||||
//CanUseBattleGroundObject() already called in CanCast()
|
//CanUseBattleGroundObject() already called in CheckCast()
|
||||||
// in battleground check
|
// in battleground check
|
||||||
if(BattleGround *bg = player->GetBattleGround())
|
if(BattleGround *bg = player->GetBattleGround())
|
||||||
{
|
{
|
||||||
|
|
@ -2976,7 +2976,7 @@ void Spell::EffectOpenLock(uint32 effIndex)
|
||||||
}
|
}
|
||||||
else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
|
else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
|
||||||
{
|
{
|
||||||
//CanUseBattleGroundObject() already called in CanCast()
|
//CanUseBattleGroundObject() already called in CheckCast()
|
||||||
// in battleground check
|
// in battleground check
|
||||||
if(BattleGround *bg = player->GetBattleGround())
|
if(BattleGround *bg = player->GetBattleGround())
|
||||||
{
|
{
|
||||||
|
|
@ -3012,7 +3012,7 @@ void Spell::EffectOpenLock(uint32 effIndex)
|
||||||
|
|
||||||
SendLoot(guid, LOOT_SKINNING);
|
SendLoot(guid, LOOT_SKINNING);
|
||||||
|
|
||||||
// not allow use skill grou at item base open
|
// not allow use skill grow at item base open
|
||||||
if(!m_CastItem && skillId != SKILL_NONE)
|
if(!m_CastItem && skillId != SKILL_NONE)
|
||||||
{
|
{
|
||||||
// update skill if really known
|
// update skill if really known
|
||||||
|
|
|
||||||
|
|
@ -2968,7 +2968,7 @@ void Unit::_UpdateAutoRepeatSpell()
|
||||||
if (isAttackReady(RANGED_ATTACK))
|
if (isAttackReady(RANGED_ATTACK))
|
||||||
{
|
{
|
||||||
// Check if able to cast
|
// Check if able to cast
|
||||||
if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CanCast(true))
|
if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckCast(true) != SPELL_CAST_OK)
|
||||||
{
|
{
|
||||||
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
|
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7466"
|
#define REVISION_NR "7467"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue