diff --git a/sql/mangos.sql b/sql/mangos.sql index 18939c78f..207e227d4 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -22,7 +22,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) default NULL, - `required_7150_01_mangos_playercreateinfo_spell` bit(1) default NULL + `required_7156_01_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -16862,6 +16862,7 @@ INSERT INTO `spell_proc_event` VALUES (44394, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), (44395, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), (44396, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000400, 0.000000, 0.000000, 0), +(44401, 0x00000000, 3, 0x00200000, 0x00000000, 0x00000000, 0x00000000, 0x00000FFF, 0.000000, 0.000000, 0), (44404, 0x00000000, 3, 0x20000021, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (44445, 0x00000000, 3, 0x00000013, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (44446, 0x00000000, 3, 0x00000013, 0x00001000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), diff --git a/sql/updates/7156_01_mangos_spell_proc_event.sql b/sql/updates/7156_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..82e9d2649 --- /dev/null +++ b/sql/updates/7156_01_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_7150_01_mangos_playercreateinfo_spell required_7156_01_mangos_spell_proc_event bit; + +-- (44401) Missile Barrage () +DELETE FROM `spell_proc_event` WHERE `entry` IN (44401); +INSERT INTO `spell_proc_event` VALUES (44401, 0x00, 3, 0x00200000, 0x00000000, 0x00000000, 0x00000000, 0x00000FFF, 0.000000, 0.000000, 0); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index ccc4d8f5d..28315cb65 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -149,6 +149,7 @@ pkgdata_DATA = \ 7147_01_mangos_creature_template.sql \ 7149_01_mangos_spell_proc_event.sql \ 7150_01_mangos_playercreateinfo_spell.sql \ + 7156_01_mangos_spell_proc_event.sql \ README ## Additional files to include when running 'make dist' @@ -278,4 +279,5 @@ EXTRA_DIST = \ 7147_01_mangos_creature_template.sql \ 7149_01_mangos_spell_proc_event.sql \ 7150_01_mangos_playercreateinfo_spell.sql \ + 7156_01_mangos_spell_proc_event.sql \ README diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index a1ccd0ace..a12723cdc 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -383,7 +383,7 @@ enum ItemQualities #define SPELL_ATTR_EX5_UNK6 0x00000040 // 6 #define SPELL_ATTR_EX5_UNK7 0x00000080 // 7 #define SPELL_ATTR_EX5_UNK8 0x00000100 // 8 -#define SPELL_ATTR_EX5_UNK9 0x00000200 // 9 +#define SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY 0x00000200 // 9 begin periodic tick at aura apply #define SPELL_ATTR_EX5_UNK10 0x00000400 // 10 #define SPELL_ATTR_EX5_UNK11 0x00000800 // 11 #define SPELL_ATTR_EX5_UNK12 0x00001000 // 12 diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index c726405d9..0ec2bcb01 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2263,6 +2263,9 @@ void Spell::handle_immediate() int32 duration = GetSpellDuration(m_spellInfo); if (duration) { + // Apply duration mod + if(Player* modOwner = m_caster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); m_spellState = SPELL_STATE_CASTING; SendChannelStart(duration); } diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 5ae889278..dc0cecd49 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -112,7 +112,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus &Aura::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE &Aura::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE - &Aura::HandleNULL, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL + &Aura::HandlePeriodicHealthFunnel, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL &Aura::HandleUnused, // 63 SPELL_AURA_PERIODIC_MANA_FUNNEL obsolete? &Aura::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH &Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED @@ -405,14 +405,19 @@ m_updated(false), m_isRemovedOnShapeLost(true), m_in_use(false) m_duration = m_maxduration; - if(modOwner) - modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_periodicTimer); - sLog.outDebug("Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d Damage : %d", m_spellProto->Id, m_spellProto->EffectApplyAuraName[eff], m_maxduration, m_spellProto->EffectImplicitTargetA[eff],damage); m_effIndex = eff; SetModifier(AuraType(m_spellProto->EffectApplyAuraName[eff]), damage, m_spellProto->EffectAmplitude[eff], m_spellProto->EffectMiscValue[eff]); + // Apply periodic time mod + if(modOwner && m_modifier.periodictime) + modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_modifier.periodictime); + + // Start periodic on next tick or at aura apply + if (!(m_spellProto->AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY)) + m_periodicTimer += m_modifier.periodictime; + m_isDeathPersist = IsDeathPersistentSpell(m_spellProto); m_procCharges = m_spellProto->procCharges; @@ -606,18 +611,8 @@ void Aura::Update(uint32 diff) if(m_isPeriodic && (m_duration >= 0 || m_isPassive || m_permanent)) { m_periodicTimer -= diff; - if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N + if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N { - if( m_modifier.m_auraname == SPELL_AURA_MOD_REGEN || - m_modifier.m_auraname == SPELL_AURA_MOD_POWER_REGEN || - // Cannibalize, eating items and other spells - m_modifier.m_auraname == SPELL_AURA_OBS_MOD_HEALTH || - // Eating items and other spells - m_modifier.m_auraname == SPELL_AURA_OBS_MOD_MANA ) - { - ApplyModifier(true); - return; - } // update before applying (aura can be removed in TriggerSpell or PeriodicTick calls) m_periodicTimer += m_modifier.periodictime; PeriodicTick(); @@ -923,19 +918,6 @@ void Aura::_AddAura() } } } - // not call total regen auras at adding - switch (m_modifier.m_auraname) - { - case SPELL_AURA_OBS_MOD_HEALTH: - case SPELL_AURA_OBS_MOD_MANA: - m_periodicTimer = m_modifier.periodictime; - break; - case SPELL_AURA_MOD_REGEN: - case SPELL_AURA_MOD_POWER_REGEN: - case SPELL_AURA_MOD_MANA_REGEN_FROM_STAT: - m_periodicTimer = 5000; - break; - } Unit* caster = GetCaster(); @@ -959,6 +941,10 @@ void Aura::_AddAura() //***************************************************** if (!secondaura) { + // Sitdown on apply aura req seated + if (m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !m_target->IsSitState()) + m_target->SetStandState(PLAYER_STATE_SIT); + // register aura diminishing on apply if (getDiminishGroup() != DIMINISHING_NONE ) m_target->ApplyDiminishingAura(getDiminishGroup(),true); @@ -2365,54 +2351,6 @@ void Aura::HandleAuraDummy(bool apply, bool Real) } } -void Aura::HandleAuraPeriodicDummy(bool apply, bool Real) -{ - // spells required only Real aura add/remove - if(!Real) - return; - - Unit* caster = GetCaster(); - - SpellEntry const*spell = GetSpellProto(); - switch( spell->SpellFamilyName) - { - case SPELLFAMILY_ROGUE: - { - // Master of Subtlety - if (spell->Id==31666 && !apply && Real) - { - m_target->RemoveAurasDueToSpell(31665); - break; - } - break; - } - case SPELLFAMILY_HUNTER: - { - // Aspect of the Viper - if (spell->SpellFamilyFlags&0x0004000000000000LL) - { - // Update regen on remove - if (!apply && m_target->GetTypeId() == TYPEID_PLAYER) - ((Player*)m_target)->UpdateManaRegen(); - break; - } - // Explosive Shot - if (spell->SpellFamilyFlags & 0x8000000000000000LL) - { - if (apply && caster) - { - int32 damage = m_modifier.m_amount + caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100; - caster->CastCustomSpell(m_target, 53352, &damage, 0, 0, true, 0, this); - } - break; - } - break; - } - } - - m_isPeriodic = apply; -} - void Aura::HandleAuraMounted(bool apply, bool Real) { // only at real add/remove aura @@ -4066,33 +4004,71 @@ void Aura::HandleAuraModStalked(bool apply, bool Real) void Aura::HandlePeriodicTriggerSpell(bool apply, bool Real) { - if (m_periodicTimer <= 0) - m_periodicTimer += m_modifier.periodictime; - m_isPeriodic = apply; } void Aura::HandlePeriodicTriggerSpellWithValue(bool apply, bool Real) { - if (m_periodicTimer <= 0) - m_periodicTimer += m_modifier.periodictime; - m_isPeriodic = apply; } void Aura::HandlePeriodicEnergize(bool apply, bool Real) { - if (m_periodicTimer <= 0) - m_periodicTimer += m_modifier.periodictime; + if (!Real) + return; + + m_isPeriodic = apply; + + // Replenishment (0.25% from max) + // Infinite Replenishment + if (GetId() == 57669 || + GetId() == 61782) + m_modifier.m_amount = m_target->GetMaxPower(POWER_MANA) * 25 / 10000; +} + +void Aura::HandleAuraPowerBurn(bool apply, bool Real) +{ + m_isPeriodic = apply; +} + +void Aura::HandleAuraPeriodicDummy(bool apply, bool Real) +{ + // spells required only Real aura add/remove + if(!Real) + return; + + // For prevent double apply bonuses + bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading()); + + Unit* caster = GetCaster(); + + SpellEntry const*spell = GetSpellProto(); + switch( spell->SpellFamilyName) + { + case SPELLFAMILY_ROGUE: + { + // Master of Subtlety + if (spell->Id==31666 && !apply) + { + m_target->RemoveAurasDueToSpell(31665); + break; + } + break; + } + case SPELLFAMILY_HUNTER: + { + // Explosive Shot + if (apply && !loading && caster) + m_modifier.m_amount +=caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100; + break; + } + } m_isPeriodic = apply; } void Aura::HandlePeriodicHeal(bool apply, bool Real) { - if (m_periodicTimer <= 0) - m_periodicTimer += m_modifier.periodictime; - m_isPeriodic = apply; // For prevent double apply bonuses @@ -4136,18 +4112,17 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) if(!Real) return; - if (m_periodicTimer <= 0) - m_periodicTimer += m_modifier.periodictime; - m_isPeriodic = apply; // For prevent double apply bonuses bool loading = (m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading()); - Unit *caster = GetCaster(); - // Custom damage calculation after - if (!apply || loading || !caster) + if (!apply || loading) + return; + + Unit *caster = GetCaster(); + if (!caster) return; switch (m_spellProto->SpellFamilyName) @@ -4322,25 +4297,21 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real) void Aura::HandlePeriodicDamagePCT(bool apply, bool Real) { - if (m_periodicTimer <= 0) - m_periodicTimer += m_modifier.periodictime; - m_isPeriodic = apply; } void Aura::HandlePeriodicLeech(bool apply, bool Real) { - if (m_periodicTimer <= 0) - m_periodicTimer += m_modifier.periodictime; - m_isPeriodic = apply; } void Aura::HandlePeriodicManaLeech(bool apply, bool Real) { - if (m_periodicTimer <= 0) - m_periodicTimer += m_modifier.periodictime; + m_isPeriodic = apply; +} +void Aura::HandlePeriodicHealthFunnel(bool apply, bool Real) +{ m_isPeriodic = apply; } @@ -4585,117 +4556,47 @@ void Aura::HandleAuraModResistenceOfStatPercent(bool /*apply*/, bool Real) /********************************/ void Aura::HandleAuraModTotalHealthPercentRegen(bool apply, bool Real) { - /* - Need additional checking for auras who reduce or increase healing, magic effect like Dumpen Magic, - so this aura not fully working. - */ - if(apply) - { - if(!m_target->isAlive()) - return; - - if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState()) - m_target->SetStandState(PLAYER_STATE_SIT); - - if(m_periodicTimer <= 0) - { - m_periodicTimer += m_modifier.periodictime; - - if(m_target->GetHealth() < m_target->GetMaxHealth()) - { - // PeriodicTick can cast triggered spells with stats changes - PeriodicTick(); - } - } - } - m_isPeriodic = apply; } void Aura::HandleAuraModTotalManaPercentRegen(bool apply, bool Real) { - if((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState()) - m_target->SetStandState(PLAYER_STATE_SIT); - if(apply) - { - if(m_modifier.periodictime == 0) - m_modifier.periodictime = 1000; - if(m_periodicTimer <= 0 && m_target->getPowerType() == POWER_MANA) - { - m_periodicTimer += m_modifier.periodictime; - - if(m_target->GetPower(POWER_MANA) < m_target->GetMaxPower(POWER_MANA)) - { - // PeriodicTick can cast triggered spells with stats changes - PeriodicTick(); - } - } - } + if(m_modifier.periodictime == 0) + m_modifier.periodictime = 1000; + m_periodicTimer = m_modifier.periodictime; m_isPeriodic = apply; } void Aura::HandleModRegen(bool apply, bool Real) // eating { - if(apply) - { - if(!m_target->isAlive()) - return; - - if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && !m_target->IsSitState()) - m_target->SetStandState(PLAYER_STATE_SIT); - - if(m_periodicTimer <= 0) - { - m_periodicTimer += 5000; - int32 gain = m_target->ModifyHealth(m_modifier.m_amount); - Unit *caster = GetCaster(); - if (caster) - { - SpellEntry const *spellProto = GetSpellProto(); - if (spellProto) - m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, spellProto); - } - } - } + if(m_modifier.periodictime == 0) + m_modifier.periodictime = 5000; + m_periodicTimer = 5000; m_isPeriodic = apply; } void Aura::HandleModPowerRegen(bool apply, bool Real) // drinking { - if ((GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) && apply && !m_target->IsSitState()) - m_target->SetStandState(PLAYER_STATE_SIT); + if (!Real) + return; - if(apply && m_periodicTimer <= 0) + Powers pt = m_target->getPowerType(); + if(m_modifier.periodictime == 0) { - m_periodicTimer += 2000; - - Powers pt = m_target->getPowerType(); - if(int32(pt) != m_modifier.m_miscvalue) - return; - - if ( GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED ) - { - // eating anim - m_target->HandleEmoteCommand(EMOTE_ONESHOT_EAT); - } - else if( GetId() == 20577 ) - { - // cannibalize anim - m_target->HandleEmoteCommand(EMOTE_STATE_CANNIBALIZE); - } - - // Warrior talent, gain 1 rage every 3 seconds while in combat - if(pt == POWER_RAGE && m_target->isInCombat()) - { - m_target->ModifyPower(pt, m_modifier.m_amount*10/17); - m_periodicTimer += 1000; - } + if (pt == POWER_RAGE) + m_modifier.periodictime = 1000; + else + m_modifier.periodictime = 2000; } - m_isPeriodic = apply; - if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_modifier.m_miscvalue == POWER_MANA) + + m_periodicTimer = 5000; + + if (m_target->GetTypeId() == TYPEID_PLAYER && m_modifier.m_miscvalue == POWER_MANA) ((Player*)m_target)->UpdateManaRegen(); + + m_isPeriodic = apply; } void Aura::HandleModPowerRegenPCT(bool /*apply*/, bool Real) @@ -5610,14 +5511,6 @@ void Aura::CleanupTriggeredSpells() m_target->RemoveAurasDueToSpell(tSpellId); } -void Aura::HandleAuraPowerBurn(bool apply, bool Real) -{ - if (m_periodicTimer <= 0) - m_periodicTimer += m_modifier.periodictime; - - m_isPeriodic = apply; -} - void Aura::HandleSchoolAbsorb(bool apply, bool Real) { if(!Real) @@ -5799,6 +5692,7 @@ void Aura::PeriodicTick() break; } case SPELL_AURA_PERIODIC_LEECH: + case SPELL_AURA_PERIODIC_HEALTH_FUNNEL: { Unit *pCaster = GetCaster(); if(!pCaster) @@ -5811,7 +5705,7 @@ void Aura::PeriodicTick() pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE) return; - // Check for immune (not use charges) + // Check for immune if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto()))) return; @@ -6195,6 +6089,35 @@ void Aura::PeriodicTick() pCaster->DealSpellDamage(&damageInfo, true); break; } + case SPELL_AURA_MOD_REGEN: + { + int32 gain = m_target->ModifyHealth(m_modifier.m_amount); + if (Unit *caster = GetCaster()) + m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, GetSpellProto()); + break; + } + case SPELL_AURA_MOD_POWER_REGEN: + { + Powers pt = m_target->getPowerType(); + if(int32(pt) != m_modifier.m_miscvalue) + return; + + if ( GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED ) + { + // eating anim + m_target->HandleEmoteCommand(EMOTE_ONESHOT_EAT); + } + else if( GetId() == 20577 ) + { + // cannibalize anim + m_target->HandleEmoteCommand(EMOTE_STATE_CANNIBALIZE); + } + + // Warrior talent, gain 1 rage every 3 seconds while in combat + if(pt == POWER_RAGE && m_target->isInCombat()) + m_target->ModifyPower(pt, m_modifier.m_amount*10/17); + break; + } // Here tick dummy auras case SPELL_AURA_PERIODIC_DUMMY: { @@ -6321,29 +6244,6 @@ void Aura::PeriodicDummyTick() // case 33208: break; // // Gossip NPC Periodic - Despawn // case 33209: break; - - // TODO: now its not periodic dummy - need move out from here - // Aspect of the Viper - case 34074: - { - if (m_target->GetTypeId() != TYPEID_PLAYER) - return; - // Should be manauser - if (m_target->getPowerType()!=POWER_MANA) - return; - if (!caster) - return; - // Regen amount is max (100% from spell) on 21% or less mana and min on 92.5% or greater mana (20% from spell) - int mana = m_target->GetPower(POWER_MANA); - int max_mana = m_target->GetMaxPower(POWER_MANA); - int32 base_regen = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target); - float regen_pct = 1.20f - 1.1f * mana / max_mana; - if (regen_pct > 1.0f) regen_pct = 1.0f; - else if (regen_pct < 0.2f) regen_pct = 0.2f; - m_modifier.m_amount = int32 (base_regen * regen_pct); - ((Player*)m_target)->UpdateManaRegen(); - return; - } // // Steal Weapon // case 36207: break; // // Simon Game START timer, (DND) @@ -6569,11 +6469,13 @@ void Aura::PeriodicDummyTick() { if (!caster) return; - // Skip 0 tick + int32 damage = m_modifier.m_amount; + // Full damage to target at 0 tick if (m_duration > m_modifier.periodictime) + { + caster->CastCustomSpell(m_target, 53352, &damage, 0, 0, true, 0, this); return; - int32 damage = caster->CalculateSpellDamage(spell, GetEffIndex(), GetBasePoints(), m_target); - damage+=caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100; + } damage/=4; caster->CastCustomSpell(m_target, 56298, &damage, 0, 0, true, 0, this); return; diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 31a49ab4c..7b4ee52d3 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -148,6 +148,7 @@ class MANGOS_DLL_SPEC Aura void HandleModSpellHitChance(bool Apply, bool Real); void HandleAuraModScale(bool Apply, bool Real); void HandlePeriodicManaLeech(bool Apply, bool Real); + void HandlePeriodicHealthFunnel(bool apply, bool Real); void HandleModCastingSpeed(bool Apply, bool Real); void HandleAuraMounted(bool Apply, bool Real); void HandleWaterBreathing(bool Apply, bool Real); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9e5e45e5e..b2d5c9c85 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7155" + #define REVISION_NR "7156" #endif // __REVISION_NR_H__