[10762] Implement SPELL_AURA_IGNORE_UNIT_STATE (252).

Original patch provided by Wojta

Note: From patch excluded talent 44543 and ranks stacking code.
      It look like need another implemention different from suggested,
      or at least more research.

Signed-off-by: VladimirMangos <vladimir@getmangos.com>

In patch added enum IgnoreUnitState and related checks now more cheating protected.
This commit is contained in:
insider42 2010-11-21 01:36:18 +03:00 committed by VladimirMangos
parent 16cd545df8
commit f7b4b88e02
11 changed files with 70 additions and 20 deletions

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0',
`required_10749_01_mangos_mangos_string` bit(1) default NULL
`required_10762_01_mangos_spell_proc_event` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@ -17249,6 +17249,7 @@ INSERT INTO `spell_proc_event` VALUES
(52127, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3),
(52420, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 30),
(52423, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0),
(52437, 0x00, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0.000000, 0.000000, 0),
(53527, 0x00, 10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(52795, 0x00, 6, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(52898, 0x7F, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),

View file

@ -0,0 +1,9 @@
ALTER TABLE db_version CHANGE COLUMN required_10749_01_mangos_mangos_string required_10762_01_mangos_spell_proc_event bit;
DELETE FROM `spell_proc_event` WHERE `entry` IN (52437);
INSERT INTO spell_proc_event VALUES
(52437, 0x00, 4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00000000, 0.000000, 0.000000, 0);

View file

@ -123,6 +123,7 @@ pkgdata_DATA = \
10743_02_mangos_spell_bonus_data.sql \
10746_01_mangos_mangos_string.sql \
10749_01_mangos_mangos_string.sql \
10762_01_mangos_spell_proc_event.sql \
README
## Additional files to include when running 'make dist'
@ -226,4 +227,5 @@ EXTRA_DIST = \
10743_02_mangos_spell_bonus_data.sql \
10746_01_mangos_mangos_string.sql \
10749_01_mangos_mangos_string.sql \
10762_01_mangos_spell_proc_event.sql \
README

View file

@ -4236,7 +4236,8 @@ SpellCastResult Spell::CheckCast(bool strict)
if(bg->GetStatus() == STATUS_WAIT_LEAVE)
return SPELL_FAILED_DONT_REPORT;
if (m_caster->isInCombat() && IsNonCombatSpell(m_spellInfo) && !m_IsTriggeredSpell)
if (!m_IsTriggeredSpell && IsNonCombatSpell(m_spellInfo) &&
m_caster->isInCombat() && !m_caster->IsIgnoreUnitState(m_spellInfo, IGNORE_UNIT_COMBAT_STATE))
return SPELL_FAILED_AFFECTING_COMBAT;
if (m_caster->GetTypeId() == TYPEID_PLAYER && !((Player*)m_caster)->isGameMaster() &&
@ -4310,7 +4311,7 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_MOVING;
}
if (!m_IsTriggeredSpell && NeedsComboPoints(m_spellInfo) &&
if (!m_IsTriggeredSpell && NeedsComboPoints(m_spellInfo) && !m_caster->IsIgnoreUnitState(m_spellInfo, IGNORE_UNIT_TARGET_STATE) &&
(!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetObjectGuid() != ((Player*)m_caster)->GetComboTargetGuid()))
// warrior not have real combo-points at client side but use this way for mark allow Overpower use
return m_caster->getClass() == CLASS_WARRIOR ? SPELL_FAILED_CASTER_AURASTATE : SPELL_FAILED_NO_COMBO_POINTS;
@ -4347,7 +4348,8 @@ SpellCastResult Spell::CheckCast(bool strict)
if(non_caster_target)
{
// target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds
if(m_spellInfo->TargetAuraState && !target->HasAuraStateForCaster(AuraState(m_spellInfo->TargetAuraState),m_caster->GetGUID()))
if (m_spellInfo->TargetAuraState && !target->HasAuraStateForCaster(AuraState(m_spellInfo->TargetAuraState), m_caster->GetGUID()) &&
!m_caster->IsIgnoreUnitState(m_spellInfo, IGNORE_UNIT_TARGET_STATE))
return SPELL_FAILED_TARGET_AURASTATE;
// Not allow casting on flying player
@ -4782,12 +4784,7 @@ SpellCastResult Spell::CheckCast(bool strict)
break;
case SPELL_EFFECT_DUMMY:
{
if(m_spellInfo->SpellIconID == 1648) // Execute
{
if(!m_targets.getUnitTarget() || m_targets.getUnitTarget()->GetHealth() > m_targets.getUnitTarget()->GetMaxHealth()*0.2)
return SPELL_FAILED_BAD_TARGETS;
}
else if (m_spellInfo->Id == 51582) // Rocket Boots Engaged
if (m_spellInfo->Id == 51582) // Rocket Boots Engaged
{
if(m_caster->IsInWater())
return SPELL_FAILED_ONLY_ABOVEWATER;

View file

@ -297,7 +297,7 @@ enum AuraType
SPELL_AURA_259 = 259,
SPELL_AURA_SCREEN_EFFECT = 260,
SPELL_AURA_PHASE = 261,
SPELL_AURA_262 = 262,
SPELL_AURA_IGNORE_UNIT_STATE = 262,
SPELL_AURA_ALLOW_ONLY_ABILITY = 263,
SPELL_AURA_264 = 264,
SPELL_AURA_265 = 265,

View file

@ -312,8 +312,8 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
&Aura::HandleNULL, //259 corrupt healing over time spell
&Aura::HandleNoImmediateEffect, //260 SPELL_AURA_SCREEN_EFFECT (miscvalue = id in ScreenEffect.dbc) not required any code
&Aura::HandlePhase, //261 SPELL_AURA_PHASE undetectable invisibility? implemented in Unit::isVisibleForOrDetect
&Aura::HandleNULL, //262 ignore combat/aura state?
&Aura::HandleNoImmediateEffect, //263 SPELL_AURA_ALLOW_ONLY_ABILITY implemented in Spell::CheckCasterAuras
&Aura::HandleNoImmediateEffect, //262 SPELL_AURA_IGNORE_UNIT_STATE implemented in Unit::isIgnoreUnitState & Spell::CheckCast
&Aura::HandleNoImmediateEffect, //263 SPELL_AURA_ALLOW_ONLY_ABILITY implemented in Spell::CheckCasterAuras, lool enum IgnoreUnitState for known misc values
&Aura::HandleUnused, //264 unused (3.0.8a-3.2.2a)
&Aura::HandleUnused, //265 unused (3.0.8a-3.2.2a)
&Aura::HandleUnused, //266 unused (3.0.8a-3.2.2a)
@ -8195,7 +8195,7 @@ bool SpellAuraHolder::IsNeedVisibleSlot(Unit const* caster) const
return true;
else if (IsSpellHaveAura(m_spellProto, SPELL_AURA_MOD_IGNORE_SHAPESHIFT))
return true;
else if (IsSpellHaveAura(m_spellProto, SPELL_AURA_262))
else if (IsSpellHaveAura(m_spellProto, SPELL_AURA_IGNORE_UNIT_STATE))
return true;
// passive auras (except totem auras) do not get placed in the slots

View file

@ -1868,6 +1868,10 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons
((spellInfo_2->SpellFamilyFlags & UI64LIT(0x0000000000010000)) && (spellInfo_1->SpellVisual[0] == 72 && spellInfo_1->SpellIconID == 1499)))
return false;
// Fingers of Frost effects
if (spellInfo_1->SpellIconID == 2947 && spellInfo_2->SpellIconID == 2947)
return false;
// Living Bomb & Ignite (Dots)
if (((spellInfo_1->SpellFamilyFlags & UI64LIT(0x2000000000000)) && (spellInfo_2->SpellFamilyFlags & UI64LIT(0x8000000))) ||
((spellInfo_2->SpellFamilyFlags & UI64LIT(0x2000000000000)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x8000000))))

View file

@ -6329,7 +6329,7 @@ uint32 Unit::SpellDamageBonusDone(Unit *pVictim, SpellEntry const *spellProto, u
// Ice Lance
if (spellProto->SpellIconID == 186)
{
if (pVictim->isFrozen())
if (pVictim->isFrozen() || IsIgnoreUnitState(spellProto, IGNORE_UNIT_TARGET_NON_FROZEN))
{
float multiplier = 3.0f;
@ -6626,9 +6626,18 @@ bool Unit::IsSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
continue;
switch((*i)->GetModifier()->m_miscvalue)
{
case 849: if (pVictim->isFrozen()) crit_chance+= 17.0f; break; //Shatter Rank 1
case 910: if (pVictim->isFrozen()) crit_chance+= 34.0f; break; //Shatter Rank 2
case 911: if (pVictim->isFrozen()) crit_chance+= 50.0f; break; //Shatter Rank 3
case 849: //Shatter Rank 1
if (pVictim->isFrozen() || IsIgnoreUnitState(spellProto, IGNORE_UNIT_TARGET_NON_FROZEN))
crit_chance+= 17.0f;
break;
case 910: //Shatter Rank 2
if (pVictim->isFrozen() || IsIgnoreUnitState(spellProto, IGNORE_UNIT_TARGET_NON_FROZEN))
crit_chance+= 34.0f;
break;
case 911: //Shatter Rank 3
if (pVictim->isFrozen() || IsIgnoreUnitState(spellProto, IGNORE_UNIT_TARGET_NON_FROZEN))
crit_chance+= 50.0f;
break;
case 7917: // Glyph of Shadowburn
if (pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
crit_chance+=(*i)->GetModifier()->m_amount;
@ -10693,6 +10702,25 @@ void Unit::StopAttackFaction(uint32 faction_id)
CallForAllControlledUnits(StopAttackFactionHelper(faction_id), CONTROLLED_PET|CONTROLLED_GUARDIANS|CONTROLLED_CHARM);
}
bool Unit::IsIgnoreUnitState(SpellEntry const *spell, IgnoreUnitState ignoreState)
{
Unit::AuraList const& stateAuras = GetAurasByType(SPELL_AURA_IGNORE_UNIT_STATE);
for(Unit::AuraList::const_iterator itr = stateAuras.begin(); itr != stateAuras.end(); ++itr)
{
if ((*itr)->GetModifier()->m_miscvalue == ignoreState)
{
// frozen state absent ignored for all spells
if (ignoreState == IGNORE_UNIT_TARGET_NON_FROZEN)
return true;
if ((*itr)->isAffectedOnSpell(spell))
return true;
}
}
return false;
}
void Unit::CleanupDeletedAuras()
{
for (SpellAuraHolderList::const_iterator iter = m_deletedHolders.begin(); iter != m_deletedHolders.end(); ++iter)

View file

@ -1133,6 +1133,14 @@ enum ReactiveType
#define MAX_REACTIVE 3
// Used as MiscValue for SPELL_AURA_IGNORE_UNIT_STATE
enum IgnoreUnitState
{
IGNORE_UNIT_TARGET_STATE = 0, // target health, aura states, or combopoints
IGNORE_UNIT_COMBAT_STATE = 1, // ignore caster in combat state
IGNORE_UNIT_TARGET_NON_FROZEN = 126, // ignore absent of frozen state
};
typedef std::set<uint64> GuardianPetList;
// delay time next attack to prevent client attack animation problems
@ -1433,6 +1441,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
bool IsPolymorphed() const;
bool isFrozen() const;
bool IsIgnoreUnitState(SpellEntry const *spell, IgnoreUnitState ignoreState);
void RemoveSpellbyDamageTaken(AuraType auraType, uint32 damage);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "10761"
#define REVISION_NR "10762"
#endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_10664_01_characters_arena_team_stats"
#define REVISION_DB_MANGOS "required_10749_01_mangos_mangos_string"
#define REVISION_DB_MANGOS "required_10762_01_mangos_spell_proc_event"
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
#endif // __REVISION_SQL_H__