From 12d6c33d863178b1b6ee9e2f1a898d98f6d77514 Mon Sep 17 00:00:00 2001 From: Splinter Date: Fri, 4 Dec 2009 03:26:22 +0300 Subject: [PATCH 01/59] [8914] Implement full damage absorbing chance with telent 11189 Signed-off-by: VladimirMangos --- src/game/Unit.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/shared/revision_nr.h | 2 +- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index c8f30b104..a43c5201f 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1693,8 +1693,47 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe // Death Prevention Aura SpellEntry const* preventDeathSpell = NULL; int32 preventDeathAmount = 0; + + // full absorb cases (by chance) + AuraList const& vAbsorb = pVictim->GetAurasByType(SPELL_AURA_SCHOOL_ABSORB); + for(AuraList::const_iterator i = vAbsorb.begin(); i != vAbsorb.end() && RemainingDamage > 0; ++i) + { + // only work with proper school mask damage + Modifier* i_mod = (*i)->GetModifier(); + if (!(i_mod->m_miscvalue & schoolMask)) + continue; + + SpellEntry const* i_spellProto = (*i)->GetSpellProto(); + // Fire Ward or Frost Ward + if(i_spellProto->SpellFamilyName == SPELLFAMILY_MAGE && i_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000108)) + { + int chance = 0; + Unit::AuraList const& auras = pVictim->GetAurasByType(SPELL_AURA_ADD_PCT_MODIFIER); + for (Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + SpellEntry const* itr_spellProto = (*itr)->GetSpellProto(); + // Frost Warding (chance full absorb) + if (itr_spellProto->SpellFamilyName == SPELLFAMILY_MAGE && itr_spellProto->SpellIconID == 501) + { + // chance stored in next dummy effect + chance = itr_spellProto->CalculateSimpleValue(1); + break; + } + } + if(roll_chance_i(chance)) + { + int32 amount = RemainingDamage; + RemainingDamage = 0; + // Frost Warding (mana regen) + pVictim->CastCustomSpell(pVictim, 57776, &amount, NULL, NULL, true, NULL, *i); + break; + } + } + } + // Need remove expired auras after bool existExpired = false; + // absorb without mana cost AuraList const& vSchoolAbsorb = pVictim->GetAurasByType(SPELL_AURA_SCHOOL_ABSORB); for(AuraList::const_iterator i = vSchoolAbsorb.begin(); i != vSchoolAbsorb.end() && RemainingDamage > 0; ++i) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ec98f4c9c..b64fc8f3f 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 "8913" + #define REVISION_NR "8914" #endif // __REVISION_NR_H__ From f8d0496407c98ea30ead2cda3edb63333901e564 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 4 Dec 2009 04:45:36 +0300 Subject: [PATCH 02/59] [8915] Fixed rage calculation for spell 5308 and ranks. --- src/game/SpellEffects.cpp | 8 ++++---- src/shared/revision_nr.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 87dd27483..d78d9a4ca 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1441,14 +1441,14 @@ void Spell::EffectDummy(uint32 i) uint32 rage = m_caster->GetPower(POWER_RAGE); // up to max 30 rage cost - if(rage > 30) - rage = 30; + if(rage > 300) + rage = 300; // Glyph of Execution bonus uint32 rage_modified = rage; if (Aura *aura = m_caster->GetDummyAura(58367)) - rage_modified += aura->GetModifier()->m_amount; + rage_modified += aura->GetModifier()->m_amount*10; int32 basePoints0 = damage+int32(rage_modified * m_spellInfo->DmgMultiplier[i] + m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f); @@ -1465,7 +1465,7 @@ void Spell::EffectDummy(uint32 i) if ((*itr)->GetSpellProto()->SpellIconID == 1989) { // saved rage top stored in next affect - uint32 lastrage = (*itr)->GetSpellProto()->CalculateSimpleValue(1); + uint32 lastrage = (*itr)->GetSpellProto()->CalculateSimpleValue(1)*10; if(lastrage < rage) rage -= lastrage; break; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b64fc8f3f..e8d34af8a 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 "8914" + #define REVISION_NR "8915" #endif // __REVISION_NR_H__ From 92ec5ace709fb17531df45c8f31ac5c388d89310 Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Fri, 4 Dec 2009 05:07:18 +0300 Subject: [PATCH 03/59] [8916] Fixed spell stacking problem for somr sprlls with spell icon 240. Signed-off-by: VladimirMangos --- src/game/SpellMgr.cpp | 6 ++---- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index bdb1b663b..cba3c9635 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1329,10 +1329,8 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons spellInfo_2->SpellVisual[0] == 99 && spellInfo_1->SpellVisual[0] == 0 ) ) return false; - // Heart of the Wild and (Primal Instinct (Idol of Terror) triggering spell or Agility) - if( spellInfo_1->SpellIconID == 240 && spellInfo_2->SpellIconID == 240 && ( - spellInfo_1->SpellVisual[0] == 0 && spellInfo_2->SpellVisual[0] == 78 || - spellInfo_2->SpellVisual[0] == 0 && spellInfo_1->SpellVisual[0] == 78 ) ) + // Heart of the Wild, Agility and various Idol Triggers + if(spellInfo_1->SpellIconID == 240 && spellInfo_2->SpellIconID == 240) return false; // Personalized Weather (thunder effect should overwrite rainy aura) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e8d34af8a..c92098242 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 "8915" + #define REVISION_NR "8916" #endif // __REVISION_NR_H__ From 3b4241624a8e4cb0223089796ea479d4a392784a Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 4 Dec 2009 06:46:06 +0300 Subject: [PATCH 04/59] [8917] Fixed `spell_proc_event` data for spell 65661 --- sql/mangos.sql | 4 ++-- sql/updates/8917_01_mangos_spell_proc_event.sql | 5 +++++ sql/updates/Makefile.am | 2 ++ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 sql/updates/8917_01_mangos_spell_proc_event.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index d5546addb..6b17fd315 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_8912_01_mangos_spell_proc_event` bit(1) default NULL + `required_8917_01_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -18386,7 +18386,7 @@ INSERT INTO `spell_proc_event` VALUES (63730, 0x00000000, 6, 0x00000800, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (64928, 0x00000000, 11, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (64976, 0x00000000, 4, 0x00000001, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), -(65661, 0x00000000, 15, 0x00400010, 0x20020004, 0x00000000, 0x00000010, 0x00000000, 0.000000, 100.000000,0), +(65661, 0x00000000, 15, 0x00400011, 0x00020004, 0x00000000, 0x00000010, 0x00000001, 0.000000, 100.000000,0); (64127, 0x00000000, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (67353, 0x00000000, 7, 0x00008000, 0x00100500, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); diff --git a/sql/updates/8917_01_mangos_spell_proc_event.sql b/sql/updates/8917_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..57b5b7974 --- /dev/null +++ b/sql/updates/8917_01_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8912_01_mangos_spell_proc_event required_8917_01_mangos_spell_proc_event bit; + +DELETE FROM `spell_proc_event` WHERE `entry` IN (65661); +INSERT INTO `spell_proc_event` VALUES +(65661, 0x00000000, 15, 0x00400011, 0x00020004, 0x00000000, 0x00000010, 0x00000001, 0.000000, 100.000000,0); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 5424680f9..056287b36 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -188,6 +188,7 @@ pkgdata_DATA = \ 8908_01_mangos_spell_chain.sql \ 8909_01_mangos_spell_proc_event.sql \ 8912_01_mangos_spell_proc_event.sql \ + 8917_01_mangos_spell_proc_event.sql \ README ## Additional files to include when running 'make dist' @@ -356,4 +357,5 @@ EXTRA_DIST = \ 8908_01_mangos_spell_chain.sql \ 8909_01_mangos_spell_proc_event.sql \ 8912_01_mangos_spell_proc_event.sql \ + 8917_01_mangos_spell_proc_event.sql \ README diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c92098242..cd97c7e00 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 "8916" + #define REVISION_NR "8917" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index d6de31072..e341811f7 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills" - #define REVISION_DB_MANGOS "required_8912_01_mangos_spell_proc_event" + #define REVISION_DB_MANGOS "required_8917_01_mangos_spell_proc_event" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__ From 562e71ec3f89564b6b1c166aec98bed0c76692d5 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 4 Dec 2009 06:47:15 +0300 Subject: [PATCH 05/59] [8918] Fix mangos.sql --- sql/mangos.sql | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/mangos.sql b/sql/mangos.sql index 6b17fd315..f861b0df1 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -18386,7 +18386,7 @@ INSERT INTO `spell_proc_event` VALUES (63730, 0x00000000, 6, 0x00000800, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (64928, 0x00000000, 11, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (64976, 0x00000000, 4, 0x00000001, 0x00000000, 0x00000000, 0x00010000, 0x00000000, 0.000000, 0.000000, 0), -(65661, 0x00000000, 15, 0x00400011, 0x00020004, 0x00000000, 0x00000010, 0x00000001, 0.000000, 100.000000,0); +(65661, 0x00000000, 15, 0x00400011, 0x00020004, 0x00000000, 0x00000010, 0x00000001, 0.000000, 100.000000,0), (64127, 0x00000000, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (67353, 0x00000000, 7, 0x00008000, 0x00100500, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index cd97c7e00..73071a6db 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 "8917" + #define REVISION_NR "8918" #endif // __REVISION_NR_H__ From 6094d2368b4cf729778e5946112c4b2cc842c238 Mon Sep 17 00:00:00 2001 From: Splinter Date: Sat, 5 Dec 2009 23:14:13 +0300 Subject: [PATCH 06/59] [8919] Implement telant 44394 and ranks. Signed-off-by: VladimirMangos --- src/game/Unit.cpp | 31 +++++++++++++++++++++++++++++++ src/shared/revision_nr.h | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index a43c5201f..742ef27e9 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -2005,6 +2005,37 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe RemainingDamage -= currentAbsorb; } + // effects dependent from full absorb amount + if (int32 full_absorb = damage - RemainingDamage - *resist) + { + Unit::AuraList const& auras = pVictim->GetAurasByType(SPELL_AURA_DUMMY); + for (Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + { + SpellEntry const* itr_spellProto = (*itr)->GetSpellProto(); + + // Incanter's Absorption + if (itr_spellProto->SpellFamilyName == SPELLFAMILY_GENERIC && + itr_spellProto->SpellIconID == 2941) + { + + int32 amount = int32(full_absorb * (*itr)->GetModifier()->m_amount / 100); + + // apply normalized part of already accumulated amount in aura + if (Aura* spdAura = pVictim->GetAura(44413,0)) + amount += spdAura->GetModifier()->m_amount * spdAura->GetAuraDuration() / spdAura->GetAuraMaxDuration(); + + // limit 5 health percents + int32 health_5percent = pVictim->GetMaxHealth()*5/100; + if(amount > health_5percent) + amount = health_5percent; + + // Incanter's Absorption (triggered absorb based spell power, will replace existed if any) + pVictim->CastCustomSpell(pVictim, 44413, &amount, NULL, NULL, true); + break; + } + } + } + // only split damage if not damaging yourself if(pVictim != this) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 73071a6db..9a4ce57ef 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 "8918" + #define REVISION_NR "8919" #endif // __REVISION_NR_H__ From 155ea6f40a24e08786cb5d725190bb4a7421a2be Mon Sep 17 00:00:00 2001 From: Splinter Date: Sun, 6 Dec 2009 00:37:43 +0300 Subject: [PATCH 07/59] [8920] Fixed glyph 42408 by move code to more correct place. Signed-off-by: VladimirMangos --- src/game/SpellAuras.cpp | 20 -------------------- src/game/Unit.cpp | 12 +++++++++++- src/shared/revision_nr.h | 2 +- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index b0efd81e1..38d040707 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -6259,26 +6259,6 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real) DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto()); m_modifier.m_amount += (int32)DoneActualBenefit; - - // now that the correct amount is computed, apply caster aura, if any - switch(m_spellProto->SpellFamilyName) - { - case SPELLFAMILY_PRIEST: - // Power Word: Shield - if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000001)) - { - // Glyph of Power Word: Shield - if(Aura* glyph = caster->GetAura(55672,0)) - { - // instant heal glyph m_amount% of the absorbed amount - int32 heal = (glyph->GetModifier()->m_amount * m_modifier.m_amount)/100; - caster->CastCustomSpell(m_target, 56160, &heal, NULL, NULL, true, 0, this); - } - } - break; - default: - break; - } } } else diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 742ef27e9..ce7728f27 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1841,7 +1841,17 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe preventDeathAmount = (*i)->GetModifier()->m_amount; continue; } - + // Power Word: Shield + if (spellProto->SpellFamilyFlags & UI64LIT(00000001) && spellProto->Mechanic == MECHANIC_SHIELD) + { + // Glyph of Power Word: Shield + if (Aura *glyph = pVictim->GetAura(55672,0)) + { + int32 heal = int32(glyph->GetModifier()->m_amount * + (RemainingDamage >= currentAbsorb ? currentAbsorb : RemainingDamage) / 100); + pVictim->CastCustomSpell(pVictim, 56160, &heal, NULL, NULL, true, 0, *i); + } + } // Reflective Shield if (spellProto->SpellFamilyFlags == 0x1 && canReflect) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9a4ce57ef..848fde25d 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 "8919" + #define REVISION_NR "8920" #endif // __REVISION_NR_H__ From bfaeddbc4b79d822f4ad958b766fcb922c4b4656 Mon Sep 17 00:00:00 2001 From: nos4r2zod Date: Sun, 6 Dec 2009 01:13:12 +0300 Subject: [PATCH 08/59] [8921] Implemement talent 53583 and ranks refresh part for spell 54428 Signed-off-by: VladimirMangos --- src/game/SpellEffects.cpp | 8 ++++++++ src/shared/revision_nr.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index d78d9a4ca..e61fb7dff 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -5350,6 +5350,14 @@ void Spell::EffectScriptEffect(uint32 effIndex) } return; } + // Guarded by The Light (Paladin spell with SPELLFAMILY_WARLOCK) + case 63521: + { + // Divine Plea, refresh on target (3 aura slots) + if (Aura* aura = unitTarget->GetAura(54428,0)) + aura->RefreshAura(); + return; + } } break; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 848fde25d..fb4fe1e1d 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 "8920" + #define REVISION_NR "8921" #endif // __REVISION_NR_H__ From 8b0ce112baf05b64170f0ab2de3f0b8e0a62e23d Mon Sep 17 00:00:00 2001 From: QAston Date: Sun, 6 Dec 2009 02:49:42 +0300 Subject: [PATCH 09/59] [8922] Implement telant 46859 and ranks additional debuff apply. Thanks to xXxRRLxXx and KAPATEJIb for patch prepering. Signed-off-by: VladimirMangos --- src/game/SpellAuras.cpp | 54 ++++++++++++++++++++++++++++++++++----- src/game/SpellEffects.cpp | 1 + src/shared/revision_nr.h | 2 +- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 38d040707..155efcaac 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2254,14 +2254,54 @@ void Aura::HandleAuraDummy(bool apply, bool Real) return; } - // Earth Shield - if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x40000000000))) + switch(m_spellProto->SpellFamilyName) { - // prevent double apply bonuses - if(m_target->GetTypeId() != TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading()) - if (Unit* caster = GetCaster()) - m_modifier.m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE); - return; + case SPELLFAMILY_WARRIOR: + // Overpower + if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000004)) + { + // Must be casting target + if (!m_target->IsNonMeleeSpellCasted(false)) + return; + + Unit* caster = GetCaster(); + if (!caster) + return; + + Unit::AuraList const& modifierAuras = caster->GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER); + for(Unit::AuraList::const_iterator itr = modifierAuras.begin(); itr != modifierAuras.end(); ++itr) + { + // Unrelenting Assault + if((*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARRIOR && (*itr)->GetSpellProto()->SpellIconID == 2775) + { + switch ((*itr)->GetSpellProto()->Id) + { + case 46859: // Unrelenting Assault, rank 1 + m_target->CastSpell(m_target,64849,true,NULL,(*itr)); + break; + case 46860: // Unrelenting Assault, rank 2 + m_target->CastSpell(m_target,64850,true,NULL,(*itr)); + break; + default: + break; + } + break; + } + } + return; + } + break; + case SPELLFAMILY_SHAMAN: + // Earth Shield + if ((GetSpellProto()->SpellFamilyFlags & UI64LIT(0x40000000000))) + { + // prevent double apply bonuses + if(m_target->GetTypeId() != TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading()) + if (Unit* caster = GetCaster()) + m_modifier.m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_modifier.m_amount, SPELL_DIRECT_DAMAGE); + return; + } + break; } } // AT REMOVE diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index e61fb7dff..acdfc33b8 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1491,6 +1491,7 @@ void Spell::EffectDummy(uint32 i) m_damage+= uint32(damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100); return; } + switch(m_spellInfo->Id) { // Warrior's Wrath diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index fb4fe1e1d..e7f5055be 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 "8921" + #define REVISION_NR "8922" #endif // __REVISION_NR_H__ From 090c8b88544c87301fcba70dcefc5d313f933081 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Sun, 6 Dec 2009 02:26:29 +0100 Subject: [PATCH 10/59] [8923] Restructure gossip menus and make it possible to build selections by database As result, gossip for GO is now possible. Moved related data structures and remove useless from code. Please note that after some time, table npc_gossip will be fully removed (use menuId in _template in relation to gossip_menu as replacement). Special thanks to GriffonHeart for help with research, discussions and ideas of code and thanks to Vladimir for helpful input. Signed-off-by: NoFantasy --- sql/mangos.sql | 204 +++++++++------ sql/updates/8923_01_mangos_gossip.sql | 72 +++++ sql/updates/Makefile.am | 2 + src/game/Creature.cpp | 17 +- src/game/Creature.h | 106 +------- src/game/GameObject.cpp | 13 +- src/game/GossipDef.cpp | 29 +- src/game/GossipDef.h | 63 ++++- src/game/Level3.cpp | 3 +- src/game/NPCHandler.cpp | 16 +- src/game/ObjectMgr.cpp | 175 +++++++++++-- src/game/ObjectMgr.h | 55 +++- src/game/Player.cpp | 364 +++++++++++++------------- src/game/Player.h | 8 +- src/game/QuestHandler.cpp | 2 +- src/game/World.cpp | 7 +- src/shared/Database/SQLStorage.cpp | 4 +- src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 19 files changed, 689 insertions(+), 455 deletions(-) create mode 100644 sql/updates/8923_01_mangos_gossip.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index f861b0df1..496dc9075 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_8917_01_mangos_spell_proc_event` bit(1) default NULL + `required_8923_01_mangos_gossip` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -1899,6 +1899,88 @@ LOCK TABLES `gameobject_template` WRITE; /*!40000 ALTER TABLE `gameobject_template` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `gossip_menu` +-- + +DROP TABLE IF EXISTS gossip_menu; +CREATE TABLE gossip_menu ( + entry smallint(6) unsigned NOT NULL default '0', + text_id mediumint(8) unsigned NOT NULL default '0', + cond_1 tinyint(3) unsigned NOT NULL default '0', + cond_1_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_1_val_2 mediumint(8) unsigned NOT NULL default '0', + cond_2 tinyint(3) unsigned NOT NULL default '0', + cond_2_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_2_val_2 mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (entry, text_id) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `gossip_menu` +-- + +LOCK TABLES `gossip_menu` WRITE; +/*!40000 ALTER TABLE `gossip_menu` DISABLE KEYS */; +/*!40000 ALTER TABLE `gossip_menu` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `gossip_menu_option` +-- + +DROP TABLE IF EXISTS gossip_menu_option; +CREATE TABLE gossip_menu_option ( + menu_id smallint(6) unsigned NOT NULL default '0', + id smallint(6) unsigned NOT NULL default '0', + option_icon mediumint(8) unsigned NOT NULL default '0', + option_text text, + option_id tinyint(3) unsigned NOT NULL default '0', + npc_option_npcflag int(10) unsigned NOT NULL default '0', + action_menu_id mediumint(8) unsigned NOT NULL default '0', + action_poi_id mediumint(8) unsigned NOT NULL default '0', + action_script_id mediumint(8) unsigned NOT NULL default '0', + box_coded tinyint(3) unsigned NOT NULL default '0', + box_money int(11) unsigned NOT NULL default '0', + box_text text, + cond_1 tinyint(3) unsigned NOT NULL default '0', + cond_1_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_1_val_2 mediumint(8) unsigned NOT NULL default '0', + cond_2 tinyint(3) unsigned NOT NULL default '0', + cond_2_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_2_val_2 mediumint(8) unsigned NOT NULL default '0', + cond_3 tinyint(3) unsigned NOT NULL default '0', + cond_3_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_3_val_2 mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (menu_id, id) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `gossip_menu_option` +-- + +LOCK TABLES `gossip_menu_option` WRITE; +/*!40000 ALTER TABLE `gossip_menu_option` DISABLE KEYS */; +INSERT INTO gossip_menu_option VALUES +(0,0,0,'GOSSIP_OPTION_QUESTGIVER',2,2,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,1,1,'GOSSIP_OPTION_VENDOR',3,128,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,2,2,'GOSSIP_OPTION_TAXIVENDOR',4,8192,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,3,3,'GOSSIP_OPTION_TRAINER',5,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,4,4,'GOSSIP_OPTION_SPIRITHEALER',6,16384,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,5,4,'GOSSIP_OPTION_SPIRITGUIDE',7,32768,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,6,5,'GOSSIP_OPTION_INNKEEPER',8,65536,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,7,6,'GOSSIP_OPTION_BANKER',9,131072,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,8,7,'GOSSIP_OPTION_PETITIONER',10,262144,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,9,8,'GOSSIP_OPTION_TABARDDESIGNER',11,524288,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,10,9,'GOSSIP_OPTION_BATTLEFIELD',12,1048576,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,11,6,'GOSSIP_OPTION_AUCTIONEER',13,2097152,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,12,0,'GOSSIP_OPTION_STABLEPET',14,4194304,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,13,1,'GOSSIP_OPTION_ARMORER',15,4096,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,14,2,'GOSSIP_OPTION_UNLEARNTALENTS',16,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,15,2,'GOSSIP_OPTION_UNLEARNPETSKILLS',17,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0); +/*!40000 ALTER TABLE `gossip_menu` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `instance_template` -- @@ -2344,6 +2426,42 @@ LOCK TABLES `locales_gameobject` WRITE; /*!40000 ALTER TABLE `locales_gameobject` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `locales_gossip_menu_option` +-- + +DROP TABLE IF EXISTS `locales_gossip_menu_option`; +CREATE TABLE `locales_gossip_menu_option` ( + `menu_id` smallint(6) unsigned NOT NULL default '0', + `id` smallint(6) unsigned NOT NULL default '0', + `option_text_loc1` text, + `option_text_loc2` text, + `option_text_loc3` text, + `option_text_loc4` text, + `option_text_loc5` text, + `option_text_loc6` text, + `option_text_loc7` text, + `option_text_loc8` text, + `box_text_loc1` text, + `box_text_loc2` text, + `box_text_loc3` text, + `box_text_loc4` text, + `box_text_loc5` text, + `box_text_loc6` text, + `box_text_loc7` text, + `box_text_loc8` text, + PRIMARY KEY (`menu_id`, `id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `locales_gossip_menu_option` +-- + +LOCK TABLES `locales_gossip_menu_option` WRITE; +/*!40000 ALTER TABLE `locales_gossip_menu_option` DISABLE KEYS */; +/*!40000 ALTER TABLE `locales_gossip_menu_option` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `locales_item` -- @@ -2379,42 +2497,6 @@ LOCK TABLES `locales_item` WRITE; /*!40000 ALTER TABLE `locales_item` ENABLE KEYS */; UNLOCK TABLES; - --- --- Table structure for table `locales_npc_option` --- - -DROP TABLE IF EXISTS `locales_npc_option`; -CREATE TABLE `locales_npc_option` ( - `entry` mediumint(8) unsigned NOT NULL default '0', - `option_text_loc1` text, - `option_text_loc2` text, - `option_text_loc3` text, - `option_text_loc4` text, - `option_text_loc5` text, - `option_text_loc6` text, - `option_text_loc7` text, - `option_text_loc8` text, - `box_text_loc1` text, - `box_text_loc2` text, - `box_text_loc3` text, - `box_text_loc4` text, - `box_text_loc5` text, - `box_text_loc6` text, - `box_text_loc7` text, - `box_text_loc8` text, - PRIMARY KEY (`entry`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Dumping data for table `locales_npc_option` --- - -LOCK TABLES `locales_npc_option` WRITE; -/*!40000 ALTER TABLE `locales_npc_option` DISABLE KEYS */; -/*!40000 ALTER TABLE `locales_npc_option` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `locales_npc_text` -- @@ -3530,54 +3612,6 @@ LOCK TABLES `npc_gossip` WRITE; /*!40000 ALTER TABLE `npc_gossip` ENABLE KEYS */; UNLOCK TABLES; --- --- Table structure for table `npc_gossip_textid` --- - -DROP TABLE IF EXISTS `npc_gossip_textid`; -CREATE TABLE `npc_gossip_textid` ( - `zoneid` smallint(5) unsigned NOT NULL default '0', - `action` smallint(5) unsigned NOT NULL default '0', - `textid` mediumint(8) unsigned NOT NULL default '0', - KEY `zoneid` (`zoneid`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Dumping data for table `npc_gossip_textid` --- - -LOCK TABLES `npc_gossip_textid` WRITE; -/*!40000 ALTER TABLE `npc_gossip_textid` DISABLE KEYS */; -/*!40000 ALTER TABLE `npc_gossip_textid` ENABLE KEYS */; -UNLOCK TABLES; - --- --- Table structure for table `npc_option` --- - -DROP TABLE IF EXISTS `npc_option`; -CREATE TABLE `npc_option` ( - `id` mediumint(8) unsigned NOT NULL default '0', - `gossip_id` mediumint(8) unsigned NOT NULL default '0', - `npcflag` int(10) unsigned NOT NULL default '0', - `icon` tinyint(3) unsigned NOT NULL default '0', - `action` mediumint(8) unsigned NOT NULL default '0', - `box_money` int(10) unsigned NOT NULL default '0', - `coded` tinyint(3) unsigned NOT NULL default '0', - `option_text` text, - `box_text` text, - PRIMARY KEY (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Dumping data for table `npc_option` --- - -LOCK TABLES `npc_option` WRITE; -/*!40000 ALTER TABLE `npc_option` DISABLE KEYS */; -/*!40000 ALTER TABLE `npc_option` ENABLE KEYS */; -UNLOCK TABLES; - -- -- Table structure for table `npc_spellclick_spells` -- diff --git a/sql/updates/8923_01_mangos_gossip.sql b/sql/updates/8923_01_mangos_gossip.sql new file mode 100644 index 000000000..896c66def --- /dev/null +++ b/sql/updates/8923_01_mangos_gossip.sql @@ -0,0 +1,72 @@ +ALTER TABLE db_version CHANGE COLUMN required_8917_01_mangos_spell_proc_event required_8923_01_mangos_gossip bit; + +DROP TABLE IF EXISTS gossip_menu; +CREATE TABLE gossip_menu ( + entry smallint(6) unsigned NOT NULL default '0', + text_id mediumint(8) unsigned NOT NULL default '0', + cond_1 tinyint(3) unsigned NOT NULL default '0', + cond_1_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_1_val_2 mediumint(8) unsigned NOT NULL default '0', + cond_2 tinyint(3) unsigned NOT NULL default '0', + cond_2_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_2_val_2 mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (entry, text_id) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS gossip_menu_option; +CREATE TABLE gossip_menu_option ( + menu_id smallint(6) unsigned NOT NULL default '0', + id smallint(6) unsigned NOT NULL default '0', + option_icon mediumint(8) unsigned NOT NULL default '0', + option_text text, + option_id tinyint(3) unsigned NOT NULL default '0', + npc_option_npcflag int(10) unsigned NOT NULL default '0', + action_menu_id mediumint(8) unsigned NOT NULL default '0', + action_poi_id mediumint(8) unsigned NOT NULL default '0', + action_script_id mediumint(8) unsigned NOT NULL default '0', + box_coded tinyint(3) unsigned NOT NULL default '0', + box_money int(11) unsigned NOT NULL default '0', + box_text text, + cond_1 tinyint(3) unsigned NOT NULL default '0', + cond_1_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_1_val_2 mediumint(8) unsigned NOT NULL default '0', + cond_2 tinyint(3) unsigned NOT NULL default '0', + cond_2_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_2_val_2 mediumint(8) unsigned NOT NULL default '0', + cond_3 tinyint(3) unsigned NOT NULL default '0', + cond_3_val_1 mediumint(8) unsigned NOT NULL default '0', + cond_3_val_2 mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (menu_id, id) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DELETE FROM gossip_menu_option WHERE menu_id=0; +INSERT INTO gossip_menu_option VALUES +(0,0,0,'GOSSIP_OPTION_QUESTGIVER',2,2,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,1,1,'GOSSIP_OPTION_VENDOR',3,128,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,2,2,'GOSSIP_OPTION_TAXIVENDOR',4,8192,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,3,3,'GOSSIP_OPTION_TRAINER',5,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,4,4,'GOSSIP_OPTION_SPIRITHEALER',6,16384,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,5,4,'GOSSIP_OPTION_SPIRITGUIDE',7,32768,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,6,5,'GOSSIP_OPTION_INNKEEPER',8,65536,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,7,6,'GOSSIP_OPTION_BANKER',9,131072,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,8,7,'GOSSIP_OPTION_PETITIONER',10,262144,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,9,8,'GOSSIP_OPTION_TABARDDESIGNER',11,524288,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,10,9,'GOSSIP_OPTION_BATTLEFIELD',12,1048576,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,11,6,'GOSSIP_OPTION_AUCTIONEER',13,2097152,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,12,0,'GOSSIP_OPTION_STABLEPET',14,4194304,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,13,1,'GOSSIP_OPTION_ARMORER',15,4096,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,14,2,'GOSSIP_OPTION_UNLEARNTALENTS',16,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), +(0,15,2,'GOSSIP_OPTION_UNLEARNPETSKILLS',17,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0); + +ALTER TABLE creature_template ADD gossip_menu_id mediumint(8) unsigned NOT NULL default 0 AFTER IconName; + +ALTER TABLE locales_npc_option CHANGE COLUMN entry id smallint(6) unsigned NOT NULL default '0'; +ALTER TABLE locales_npc_option ADD menu_id smallint(6) unsigned NOT NULL default '0' FIRST; + +ALTER TABLE locales_npc_option DROP PRIMARY KEY; +ALTER TABLE locales_npc_option ADD PRIMARY KEY (menu_id, id); + +RENAME TABLE locales_npc_option TO locales_gossip_menu_option; + +DROP TABLE IF EXISTS npc_option; +DROP TABLE IF EXISTS npc_gossip_textid; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 056287b36..14b603189 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -189,6 +189,7 @@ pkgdata_DATA = \ 8909_01_mangos_spell_proc_event.sql \ 8912_01_mangos_spell_proc_event.sql \ 8917_01_mangos_spell_proc_event.sql \ + 8923_01_mangos_gossip.sql \ README ## Additional files to include when running 'make dist' @@ -358,4 +359,5 @@ EXTRA_DIST = \ 8909_01_mangos_spell_proc_event.sql \ 8912_01_mangos_spell_proc_event.sql \ 8917_01_mangos_spell_proc_event.sql \ + 8923_01_mangos_gossip.sql \ README diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 8cd094a85..06949e94a 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -110,7 +110,7 @@ Unit(), i_AI(NULL), lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0), m_lootMoney(0), m_lootRecipient(0), m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f), -m_gossipOptionLoaded(false), m_isPet(false), m_isVehicle(false), m_isTotem(false), +m_isPet(false), m_isVehicle(false), m_isTotem(false), m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), @@ -744,21 +744,6 @@ bool Creature::isCanTrainingAndResetTalentsOf(Player* pPlayer) const && pPlayer->getClass() == GetCreatureInfo()->trainer_class; } -void Creature::LoadGossipOptions() -{ - if(m_gossipOptionLoaded) - return; - - uint32 npcflags=GetUInt32Value(UNIT_NPC_FLAGS); - - CacheNpcOptionList const& noList = sObjectMgr.GetNpcOptions (); - for (CacheNpcOptionList::const_iterator i = noList.begin (); i != noList.end (); ++i) - if(i->NpcFlag & npcflags) - addGossipOption(*i); - - m_gossipOptionLoaded = true; -} - void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, MonsterMovementFlags flags, uint8 type) { /* uint32 timeElap = getMSTime(); diff --git a/src/game/Creature.h b/src/game/Creature.h index 781acb9ad..e6e46fe79 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -36,102 +36,6 @@ class Quest; class Player; class WorldSession; -enum Gossip_Option -{ - GOSSIP_OPTION_NONE = 0, //UNIT_NPC_FLAG_NONE = 0, - GOSSIP_OPTION_GOSSIP = 1, //UNIT_NPC_FLAG_GOSSIP = 1, - GOSSIP_OPTION_QUESTGIVER = 2, //UNIT_NPC_FLAG_QUESTGIVER = 2, - GOSSIP_OPTION_VENDOR = 3, //UNIT_NPC_FLAG_VENDOR = 4, - GOSSIP_OPTION_TAXIVENDOR = 4, //UNIT_NPC_FLAG_TAXIVENDOR = 8, - GOSSIP_OPTION_TRAINER = 5, //UNIT_NPC_FLAG_TRAINER = 16, - GOSSIP_OPTION_SPIRITHEALER = 6, //UNIT_NPC_FLAG_SPIRITHEALER = 32, - GOSSIP_OPTION_SPIRITGUIDE = 7, //UNIT_NPC_FLAG_SPIRITGUIDE = 64, - GOSSIP_OPTION_INNKEEPER = 8, //UNIT_NPC_FLAG_INNKEEPER = 128, - GOSSIP_OPTION_BANKER = 9, //UNIT_NPC_FLAG_BANKER = 256, - GOSSIP_OPTION_PETITIONER = 10, //UNIT_NPC_FLAG_PETITIONER = 512, - GOSSIP_OPTION_TABARDDESIGNER = 11, //UNIT_NPC_FLAG_TABARDDESIGNER = 1024, - GOSSIP_OPTION_BATTLEFIELD = 12, //UNIT_NPC_FLAG_BATTLEFIELDPERSON = 2048, - GOSSIP_OPTION_AUCTIONEER = 13, //UNIT_NPC_FLAG_AUCTIONEER = 4096, - GOSSIP_OPTION_STABLEPET = 14, //UNIT_NPC_FLAG_STABLE = 8192, - GOSSIP_OPTION_ARMORER = 15, //UNIT_NPC_FLAG_ARMORER = 16384, - GOSSIP_OPTION_UNLEARNTALENTS = 16, //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER) - GOSSIP_OPTION_UNLEARNPETSKILLS = 17 //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER) -}; - -enum Gossip_Guard -{ - GOSSIP_GUARD_BANK = 32, - GOSSIP_GUARD_RIDE = 33, - GOSSIP_GUARD_GUILD = 34, - GOSSIP_GUARD_INN = 35, - GOSSIP_GUARD_MAIL = 36, - GOSSIP_GUARD_AUCTION = 37, - GOSSIP_GUARD_WEAPON = 38, - GOSSIP_GUARD_STABLE = 39, - GOSSIP_GUARD_BATTLE = 40, - GOSSIP_GUARD_SPELLTRAINER = 41, - GOSSIP_GUARD_SKILLTRAINER = 42 -}; - -enum Gossip_Guard_Spell -{ - GOSSIP_GUARD_SPELL_WARRIOR = 64, - GOSSIP_GUARD_SPELL_PALADIN = 65, - GOSSIP_GUARD_SPELL_HUNTER = 66, - GOSSIP_GUARD_SPELL_ROGUE = 67, - GOSSIP_GUARD_SPELL_PRIEST = 68, - GOSSIP_GUARD_SPELL_UNKNOWN1 = 69, - GOSSIP_GUARD_SPELL_SHAMAN = 70, - GOSSIP_GUARD_SPELL_MAGE = 71, - GOSSIP_GUARD_SPELL_WARLOCK = 72, - GOSSIP_GUARD_SPELL_UNKNOWN2 = 73, - GOSSIP_GUARD_SPELL_DRUID = 74 -}; - -enum Gossip_Guard_Skill -{ - GOSSIP_GUARD_SKILL_ALCHEMY = 80, - GOSSIP_GUARD_SKILL_BLACKSMITH = 81, - GOSSIP_GUARD_SKILL_COOKING = 82, - GOSSIP_GUARD_SKILL_ENCHANT = 83, - GOSSIP_GUARD_SKILL_FIRSTAID = 84, - GOSSIP_GUARD_SKILL_FISHING = 85, - GOSSIP_GUARD_SKILL_HERBALISM = 86, - GOSSIP_GUARD_SKILL_LEATHER = 87, - GOSSIP_GUARD_SKILL_MINING = 88, - GOSSIP_GUARD_SKILL_SKINNING = 89, - GOSSIP_GUARD_SKILL_TAILORING = 90, - GOSSIP_GUARD_SKILL_ENGINERING = 91 -}; - -enum GossipOptionIcon -{ - GOSSIP_ICON_CHAT = 0, //white chat bubble - GOSSIP_ICON_VENDOR = 1, //brown bag - GOSSIP_ICON_TAXI = 2, //flight - GOSSIP_ICON_TRAINER = 3, //book - GOSSIP_ICON_INTERACT_1 = 4, //interaction wheel - GOSSIP_ICON_INTERACT_2 = 5, //interaction wheel - GOSSIP_ICON_MONEY_BAG = 6, //brown bag with yellow dot - GOSSIP_ICON_TALK = 7, //white chat bubble with black dots - GOSSIP_ICON_TABARD = 8, //tabard - GOSSIP_ICON_BATTLE = 9, //two swords - GOSSIP_ICON_DOT = 10 //yellow dot -}; - -struct GossipOption -{ - uint32 Id; - uint32 GossipId; - uint32 NpcFlag; - uint32 Icon; - uint32 Action; - uint32 BoxMoney; - bool Coded; - std::string OptionText; - std::string BoxText; -}; - enum CreatureFlagsExtra { CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group @@ -165,6 +69,7 @@ struct CreatureInfo char* Name; char* SubName; char* IconName; + uint32 GossipMenuId; uint32 minlevel; uint32 maxlevel; uint32 minhealth; @@ -449,8 +354,6 @@ struct TrainerSpellData void Clear() { spellList.clear(); } }; -typedef std::list GossipOptionList; - typedef std::map CreatureSpellCooldowns; // max different by z coordinate for creature aggro reaction @@ -576,10 +479,6 @@ class MANGOS_DLL_SPEC Creature : public Unit std::string GetScriptName() const; uint32 GetScriptId() const; - void LoadGossipOptions(); - void addGossipOption(GossipOption const& gso) { m_goptions.push_back(gso); } - GossipOptionList &GetGossipOptionList() { return m_goptions; } - void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); } void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); } void TextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false) { MonsterTextEmote(textId,TargetGuid,IsBossEmote); } @@ -708,9 +607,6 @@ class MANGOS_DLL_SPEC Creature : public Unit uint32 m_corpseDelay; // (secs) delay between death and corpse disappearance float m_respawnradius; - bool m_gossipOptionLoaded; - GossipOptionList m_goptions; - bool m_isPet; // set only in Pet::Pet bool m_isVehicle; // set only in Vehicle::Vehicle bool m_isTotem; // set only in Totem::Totem diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 0aa6f7f99..e8aa32b67 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -872,13 +872,13 @@ void GameObject::Use(Unit* user) case GAMEOBJECT_TYPE_QUESTGIVER: //2 { - if(user->GetTypeId()!=TYPEID_PLAYER) + if (user->GetTypeId() != TYPEID_PLAYER) return; Player* player = (Player*)user; - player->PrepareQuestMenu( GetGUID() ); - player->SendPreparedQuest( GetGUID() ); + player->PrepareGossipMenu(this, GetGOInfo()->questgiver.gossipID); + player->SendPreparedGossip(this); return; } //Sitting: Wooden bench, chairs enzz @@ -952,12 +952,17 @@ void GameObject::Use(Unit* user) Player* player = (Player*)user; // show page - if(info->goober.pageId) + if (info->goober.pageId) { WorldPacket data(SMSG_GAMEOBJECT_PAGETEXT, 8); data << GetGUID(); player->GetSession()->SendPacket(&data); } + else if (info->questgiver.gossipID) + { + player->PrepareGossipMenu(this, info->goober.gossipID); + player->SendPreparedGossip(this); + } // possible quest objective for active quests player->CastedCreatureOrGO(info->id, GetGUID(), 0); diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp index 12fd7846c..5b269da61 100644 --- a/src/game/GossipDef.cpp +++ b/src/game/GossipDef.cpp @@ -27,6 +27,7 @@ GossipMenu::GossipMenu() { m_gItems.reserve(16); // can be set for max from most often sizes to speedup push_back and less memory use + m_gMenuId = 0; } GossipMenu::~GossipMenu() @@ -44,13 +45,24 @@ void GossipMenu::AddMenuItem(uint8 Icon, const std::string& Message, uint32 dtSe gItem.m_gMessage = Message; gItem.m_gCoded = Coded; gItem.m_gSender = dtSender; - gItem.m_gAction = dtAction; + gItem.m_gOptionId = dtAction; gItem.m_gBoxMessage = BoxMessage; gItem.m_gBoxMoney = BoxMoney; m_gItems.push_back(gItem); } +void GossipMenu::AddGossipMenuItemData(uint32 action_menu, uint32 action_poi, uint32 action_script) +{ + GossipMenuItemData pItemData; + + pItemData.m_gAction_menu = action_menu; + pItemData.m_gAction_poi = action_poi; + pItemData.m_gAction_script = action_script; + + m_gItemsData.push_back(pItemData); +} + void GossipMenu::AddMenuItem(uint8 Icon, const std::string& Message, bool Coded) { AddMenuItem( Icon, Message, 0, 0, "", 0, Coded); @@ -77,7 +89,7 @@ uint32 GossipMenu::MenuItemAction( unsigned int ItemId ) { if ( ItemId >= m_gItems.size() ) return 0; - return m_gItems[ ItemId ].m_gAction; + return m_gItems[ ItemId ].m_gOptionId; } bool GossipMenu::MenuItemCoded( unsigned int ItemId ) @@ -90,6 +102,7 @@ bool GossipMenu::MenuItemCoded( unsigned int ItemId ) void GossipMenu::ClearMenu() { m_gItems.clear(); + m_gItemsData.clear(); } PlayerMenu::PlayerMenu( WorldSession *session ) : pSession(session) @@ -122,13 +135,13 @@ bool PlayerMenu::GossipOptionCoded( unsigned int Selection ) return mGossipMenu.MenuItemCoded( Selection ); } -void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID ) +void PlayerMenu::SendGossipMenu(uint32 TitleTextId, uint64 objectGUID) { - WorldPacket data( SMSG_GOSSIP_MESSAGE, (100) ); // guess size - data << uint64(npcGUID); - data << uint32(0); // new 2.4.0 - data << uint32( TitleTextId ); - data << uint32( mGossipMenu.MenuItemCount() ); // max count 0x10 + WorldPacket data(SMSG_GOSSIP_MESSAGE, (100)); // guess size + data << uint64(objectGUID); + data << uint32(mGossipMenu.GetMenuId()); // new 2.4.0 + data << uint32(TitleTextId); + data << uint32(mGossipMenu.MenuItemCount()); // max count 0x10 for (uint32 iI = 0; iI < mGossipMenu.MenuItemCount(); ++iI ) { diff --git a/src/game/GossipDef.h b/src/game/GossipDef.h index ea31b4c15..335b010ca 100644 --- a/src/game/GossipDef.h +++ b/src/game/GossipDef.h @@ -28,6 +28,43 @@ class WorldSession; #define GOSSIP_MAX_MENU_ITEMS 64 // client supported items unknown, but provided number must be enough #define DEFAULT_GOSSIP_MESSAGE 0xffffff +enum Gossip_Option +{ + GOSSIP_OPTION_NONE = 0, //UNIT_NPC_FLAG_NONE (0) + GOSSIP_OPTION_GOSSIP = 1, //UNIT_NPC_FLAG_GOSSIP (1) + GOSSIP_OPTION_QUESTGIVER = 2, //UNIT_NPC_FLAG_QUESTGIVER (2) + GOSSIP_OPTION_VENDOR = 3, //UNIT_NPC_FLAG_VENDOR (128) + GOSSIP_OPTION_TAXIVENDOR = 4, //UNIT_NPC_FLAG_TAXIVENDOR (8192) + GOSSIP_OPTION_TRAINER = 5, //UNIT_NPC_FLAG_TRAINER (16) + GOSSIP_OPTION_SPIRITHEALER = 6, //UNIT_NPC_FLAG_SPIRITHEALER (16384) + GOSSIP_OPTION_SPIRITGUIDE = 7, //UNIT_NPC_FLAG_SPIRITGUIDE (32768) + GOSSIP_OPTION_INNKEEPER = 8, //UNIT_NPC_FLAG_INNKEEPER (65536) + GOSSIP_OPTION_BANKER = 9, //UNIT_NPC_FLAG_BANKER (131072) + GOSSIP_OPTION_PETITIONER = 10, //UNIT_NPC_FLAG_PETITIONER (262144) + GOSSIP_OPTION_TABARDDESIGNER = 11, //UNIT_NPC_FLAG_TABARDDESIGNER (524288) + GOSSIP_OPTION_BATTLEFIELD = 12, //UNIT_NPC_FLAG_BATTLEFIELDPERSON (1048576) + GOSSIP_OPTION_AUCTIONEER = 13, //UNIT_NPC_FLAG_AUCTIONEER (2097152) + GOSSIP_OPTION_STABLEPET = 14, //UNIT_NPC_FLAG_STABLE (4194304) + GOSSIP_OPTION_ARMORER = 15, //UNIT_NPC_FLAG_ARMORER (4096) + GOSSIP_OPTION_UNLEARNTALENTS = 16, //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER) + GOSSIP_OPTION_UNLEARNPETSKILLS = 17 //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER) +}; + +enum GossipOptionIcon +{ + GOSSIP_ICON_CHAT = 0, //white chat bubble + GOSSIP_ICON_VENDOR = 1, //brown bag + GOSSIP_ICON_TAXI = 2, //flight + GOSSIP_ICON_TRAINER = 3, //book + GOSSIP_ICON_INTERACT_1 = 4, //interaction wheel + GOSSIP_ICON_INTERACT_2 = 5, //interaction wheel + GOSSIP_ICON_MONEY_BAG = 6, //brown bag with yellow dot + GOSSIP_ICON_TALK = 7, //white chat bubble with black dots + GOSSIP_ICON_TABARD = 8, //tabard + GOSSIP_ICON_BATTLE = 9, //two swords + GOSSIP_ICON_DOT = 10 //yellow dot +}; + //POI icons. Many more exist, list not complete. enum Poi_Icon { @@ -80,13 +117,22 @@ struct GossipMenuItem bool m_gCoded; std::string m_gMessage; uint32 m_gSender; - uint32 m_gAction; + uint32 m_gOptionId; std::string m_gBoxMessage; uint32 m_gBoxMoney; }; typedef std::vector GossipMenuItemList; +struct GossipMenuItemData +{ + uint32 m_gAction_menu; + uint32 m_gAction_poi; + uint32 m_gAction_script; +}; + +typedef std::vector GossipMenuItemDataList; + struct QuestMenuItem { uint32 m_qId; @@ -108,6 +154,11 @@ class MANGOS_DLL_SPEC GossipMenu void AddMenuItem(uint8 Icon, char const* Message, bool Coded = false); void AddMenuItem(uint8 Icon, char const* Message, uint32 dtSender, uint32 dtAction, char const* BoxMessage, uint32 BoxMoney, bool Coded = false); + void SetMenuId(uint32 menu_id) { m_gMenuId = menu_id; } + uint32 GetMenuId() { return m_gMenuId; } + + void AddGossipMenuItemData(uint32 action_menu, uint32 action_poi, uint32 action_script); + unsigned int MenuItemCount() const { return m_gItems.size(); @@ -123,6 +174,11 @@ class MANGOS_DLL_SPEC GossipMenu return m_gItems[ Id ]; } + GossipMenuItemData const& GetItemData(unsigned int indexId) + { + return m_gItemsData[indexId]; + } + uint32 MenuItemSender( unsigned int ItemId ); uint32 MenuItemAction( unsigned int ItemId ); bool MenuItemCoded( unsigned int ItemId ); @@ -130,7 +186,10 @@ class MANGOS_DLL_SPEC GossipMenu void ClearMenu(); protected: - GossipMenuItemList m_gItems; + GossipMenuItemList m_gItems; + GossipMenuItemDataList m_gItemsData; + + uint32 m_gMenuId; }; class QuestMenu diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 94413af32..4320b5ae0 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -407,7 +407,8 @@ bool ChatHandler::HandleReloadMangosStringCommand(const char*) bool ChatHandler::HandleReloadNpcOptionCommand(const char*) { sLog.outString( "Re-Loading `npc_option` Table!" ); - sObjectMgr.LoadNpcOptions(); + //sObjectMgr.LoadGossipMenu(); + //sObjectMgr.LoadGossipMenuItems(); SendGlobalSysMessage("DB table `npc_option` reloaded."); return true; } diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index e3101cc1b..6d74f770e 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -277,7 +277,7 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket & recv_data) if (!Script->GossipHello(_player, pCreature)) { _player->TalkedToCreature(pCreature->GetEntry(), pCreature->GetGUID()); - _player->PrepareGossipMenu(pCreature); + _player->PrepareGossipMenu(pCreature, pCreature->GetCreatureInfo()->GossipMenuId); _player->SendPreparedGossip(pCreature); } } @@ -286,14 +286,14 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data ) { sLog.outDebug("WORLD: CMSG_GOSSIP_SELECT_OPTION"); - uint32 option; + uint32 gossipListId; uint32 menuId; uint64 guid; std::string code = ""; - recv_data >> guid >> menuId >> option; + recv_data >> guid >> menuId >> gossipListId; - if (_player->PlayerTalkClass->GossipOptionCoded(option)) + if (_player->PlayerTalkClass->GossipOptionCoded(gossipListId)) { sLog.outBasic("reading string"); recv_data >> code; @@ -314,13 +314,13 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data ) if (!code.empty()) { - if (!Script->GossipSelectWithCode(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(option), _player->PlayerTalkClass->GossipOptionAction(option), code.c_str())) - _player->OnGossipSelect(pCreature, option); + if (!Script->GossipSelectWithCode(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId), code.c_str())) + _player->OnGossipSelect(pCreature, gossipListId, menuId); } else { - if (!Script->GossipSelect(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(option), _player->PlayerTalkClass->GossipOptionAction(option))) - _player->OnGossipSelect(pCreature, option); + if (!Script->GossipSelect(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId))) + _player->OnGossipSelect(pCreature, gossipListId, menuId); } } diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 3407fd9ce..2bacdaa39 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -342,12 +342,12 @@ void ObjectMgr::LoadNpcOptionLocales() { mNpcOptionLocaleMap.clear(); // need for reload case - QueryResult *result = WorldDatabase.Query("SELECT entry," + QueryResult *result = WorldDatabase.Query("SELECT menu_id,id," "option_text_loc1,box_text_loc1,option_text_loc2,box_text_loc2," "option_text_loc3,box_text_loc3,option_text_loc4,box_text_loc4," "option_text_loc5,box_text_loc5,option_text_loc6,box_text_loc6," "option_text_loc7,box_text_loc7,option_text_loc8,box_text_loc8 " - "FROM locales_npc_option"); + "FROM locales_gossip_menu_option"); if(!result) { @@ -356,7 +356,7 @@ void ObjectMgr::LoadNpcOptionLocales() bar.step(); sLog.outString(); - sLog.outString(">> Loaded 0 npc_option locale strings. DB table `locales_npc_option` is empty."); + sLog.outString(">> Loaded 0 gossip_menu_option locale strings. DB table `locales_gossip_menu_option` is empty."); return; } @@ -367,9 +367,10 @@ void ObjectMgr::LoadNpcOptionLocales() Field *fields = result->Fetch(); bar.step(); - uint32 entry = fields[0].GetUInt32(); + uint16 menuId = fields[0].GetUInt16(); + uint16 id = fields[1].GetUInt16(); - NpcOptionLocale& data = mNpcOptionLocaleMap[entry]; + NpcOptionLocale& data = mNpcOptionLocaleMap[MAKE_PAIR32(menuId,id)]; for(int i = 1; i < MAX_LOCALE; ++i) { @@ -403,7 +404,7 @@ void ObjectMgr::LoadNpcOptionLocales() delete result; sLog.outString(); - sLog.outString( ">> Loaded %lu npc_option locale strings", (unsigned long)mNpcOptionLocaleMap.size() ); + sLog.outString( ">> Loaded %lu gossip_menu_option locale strings", (unsigned long)mNpcOptionLocaleMap.size() ); } void ObjectMgr::LoadPointOfInterestLocales() @@ -7825,23 +7826,21 @@ void ObjectMgr::LoadNpcTextId() sLog.outString( ">> Loaded %d NpcTextId ", count ); } -void ObjectMgr::LoadNpcOptions() +void ObjectMgr::LoadGossipMenu() { - m_mCacheNpcOptionList.clear(); // For reload case + m_mGossipMenusMap.clear(); - QueryResult *result = WorldDatabase.Query( - // 0 1 2 3 4 5 6 7 8 - "SELECT id,gossip_id,npcflag,icon,action,box_money,coded,option_text,box_text " - "FROM npc_option"); + QueryResult* result = WorldDatabase.Query("SELECT entry, text_id, " + "cond_1, cond_1_val_1, cond_1_val_2, cond_2, cond_2_val_1, cond_2_val_2 FROM gossip_menu"); - if( !result ) + if (!result) { - barGoLink bar( 1 ); + barGoLink bar(1); bar.step(); sLog.outString(); - sLog.outErrorDb(">> Loaded `npc_option`, table is empty!"); + sLog.outErrorDb(">> Loaded gossip_menu, table is empty!"); return; } @@ -7855,26 +7854,146 @@ void ObjectMgr::LoadNpcOptions() Field* fields = result->Fetch(); - GossipOption go; - go.Id = fields[0].GetUInt32(); - go.GossipId = fields[1].GetUInt32(); - go.NpcFlag = fields[2].GetUInt32(); - go.Icon = fields[3].GetUInt32(); - go.Action = fields[4].GetUInt32(); - go.BoxMoney = fields[5].GetUInt32(); - go.Coded = fields[6].GetUInt8()!=0; - go.OptionText = fields[7].GetCppString(); - go.BoxText = fields[8].GetCppString(); + GossipMenus gMenu; - m_mCacheNpcOptionList.push_back(go); + gMenu.entry = fields[0].GetUInt32(); + gMenu.text_id = fields[1].GetUInt32(); + + ConditionType cond_1 = (ConditionType)fields[2].GetUInt32(); + uint32 cond_1_val_1 = fields[3].GetUInt32(); + uint32 cond_1_val_2 = fields[4].GetUInt32(); + ConditionType cond_2 = (ConditionType)fields[5].GetUInt32(); + uint32 cond_2_val_1 = fields[6].GetUInt32(); + uint32 cond_2_val_2 = fields[7].GetUInt32(); + + if (!GetGossipText(gMenu.text_id)) + { + sLog.outErrorDb("Table gossip_menu entry %u are using non-existing text_id %u", gMenu.entry, gMenu.text_id); + continue; + } + + if (!PlayerCondition::IsValid(cond_1, cond_1_val_1, cond_1_val_2)) + { + sLog.outErrorDb("Table gossip_menu entry %u, invalid condition 1 for id %u", gMenu.entry, gMenu.text_id); + continue; + } + + if (!PlayerCondition::IsValid(cond_2, cond_2_val_1, cond_2_val_2)) + { + sLog.outErrorDb("Table gossip_menu entry %u, invalid condition 2 for id %u", gMenu.entry, gMenu.text_id); + continue; + } + + gMenu.cond_1 = GetConditionId(cond_1, cond_1_val_1, cond_1_val_2); + gMenu.cond_2 = GetConditionId(cond_2, cond_2_val_1, cond_2_val_2); + + m_mGossipMenusMap.insert(GossipMenusMap::value_type(gMenu.entry, gMenu)); ++count; + } + while(result->NextRow()); - } while (result->NextRow()); delete result; sLog.outString(); - sLog.outString( ">> Loaded %d npc_option entries", count ); + sLog.outString( ">> Loaded %u gossip_menu entries", count); +} + +void ObjectMgr::LoadGossipMenuItems() +{ + m_mGossipMenuItemsMap.clear(); + + QueryResult *result = WorldDatabase.Query( + "SELECT menu_id, id, option_icon, option_text, option_id, npc_option_npcflag, " + "action_menu_id, action_poi_id, action_script_id, box_coded, box_money, box_text, " + "cond_1, cond_1_val_1, cond_1_val_2, " + "cond_2, cond_2_val_1, cond_2_val_2, " + "cond_3, cond_3_val_1, cond_3_val_2 " + "FROM gossip_menu_option"); + + if (!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded gossip_menu_items, table is empty!"); + return; + } + + barGoLink bar(result->GetRowCount()); + + uint32 count = 0; + + do + { + bar.step(); + + Field* fields = result->Fetch(); + + GossipMenuItems gMenuItem; + + gMenuItem.menu_id = fields[0].GetUInt32(); + gMenuItem.id = fields[1].GetUInt32(); + gMenuItem.option_icon = fields[2].GetUInt8(); + gMenuItem.option_text = fields[3].GetCppString(); + gMenuItem.option_id = fields[4].GetUInt32(); + gMenuItem.npc_option_npcflag = fields[5].GetUInt32(); + gMenuItem.action_menu_id = fields[6].GetUInt32(); + gMenuItem.action_poi_id = fields[7].GetUInt32(); + gMenuItem.action_script_id = fields[8].GetUInt32(); + gMenuItem.box_coded = fields[9].GetUInt8() != 0; + gMenuItem.box_money = fields[10].GetUInt32(); + gMenuItem.box_text = fields[11].GetCppString(); + + ConditionType cond_1 = (ConditionType)fields[12].GetUInt32(); + uint32 cond_1_val_1 = fields[13].GetUInt32(); + uint32 cond_1_val_2 = fields[14].GetUInt32(); + ConditionType cond_2 = (ConditionType)fields[15].GetUInt32(); + uint32 cond_2_val_1 = fields[16].GetUInt32(); + uint32 cond_2_val_2 = fields[17].GetUInt32(); + ConditionType cond_3 = (ConditionType)fields[18].GetUInt32(); + uint32 cond_3_val_1 = fields[19].GetUInt32(); + uint32 cond_3_val_2 = fields[20].GetUInt32(); + + if (!PlayerCondition::IsValid(cond_1, cond_1_val_1, cond_1_val_2)) + { + sLog.outErrorDb("Table gossip_menu_items menu %u, invalid condition 1 for id %u", gMenuItem.menu_id, gMenuItem.id); + continue; + } + if (!PlayerCondition::IsValid(cond_2, cond_2_val_1, cond_2_val_2)) + { + sLog.outErrorDb("Table gossip_menu_items menu %u, invalid condition 2 for id %u", gMenuItem.menu_id, gMenuItem.id); + continue; + } + if (!PlayerCondition::IsValid(cond_3, cond_3_val_1, cond_3_val_2)) + { + sLog.outErrorDb("Table gossip_menu_items menu %u, invalid condition 3 for id %u", gMenuItem.menu_id, gMenuItem.id); + continue; + } + + if (gMenuItem.action_poi_id && !GetPointOfInterest(gMenuItem.action_poi_id)) + { + sLog.outErrorDb("Table gossip_menu_items for menu %u, id %u use non-existing action_poi_id %u, ignoring", gMenuItem.menu_id, gMenuItem.id, gMenuItem.action_poi_id); + gMenuItem.action_poi_id = 0; + } + + gMenuItem.cond_1 = GetConditionId(cond_1, cond_1_val_1, cond_1_val_2); + gMenuItem.cond_2 = GetConditionId(cond_2, cond_2_val_1, cond_2_val_2); + gMenuItem.cond_3 = GetConditionId(cond_3, cond_3_val_1, cond_3_val_2); + + m_mGossipMenuItemsMap.insert(GossipMenuItemsMap::value_type(gMenuItem.menu_id, gMenuItem)); + + ++count; + + } + while(result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString(">> Loaded %u gossip_menu_items entries", count); } void ObjectMgr::AddVendorItem( uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedcost ) diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index e4c90aadb..dbb9bed72 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -216,6 +216,38 @@ struct PointOfInterest std::string icon_name; }; +struct GossipMenuItems +{ + uint32 menu_id; + uint32 id; + uint8 option_icon; + std::string option_text; + uint32 option_id; + uint32 npc_option_npcflag; + uint32 action_menu_id; + uint32 action_poi_id; + uint32 action_script_id; + bool box_coded; + uint32 box_money; + std::string box_text; + uint16 cond_1; + uint16 cond_2; + uint16 cond_3; +}; + +struct GossipMenus +{ + uint32 entry; + uint32 text_id; + uint16 cond_1; + uint16 cond_2; +}; + +typedef std::multimap GossipMenusMap; +typedef std::pair GossipMenusMapBounds; +typedef std::multimap GossipMenuItemsMap; +typedef std::pair GossipMenuItemsMapBounds; + #define WEATHER_SEASONS 4 struct WeatherSeasonChances { @@ -275,7 +307,6 @@ struct PlayerCondition // NPC gossip text id typedef UNORDERED_MAP CacheNpcTextIdMap; -typedef std::list CacheNpcOptionList; typedef UNORDERED_MAP CacheVendorItemMap; typedef UNORDERED_MAP CacheTrainerSpellMap; @@ -557,8 +588,11 @@ class ObjectMgr void LoadWeatherZoneChances(); void LoadGameTele(); - void LoadNpcOptions(); void LoadNpcTextId(); + + void LoadGossipMenu(); + void LoadGossipMenuItems(); + void LoadVendors(); void LoadTrainerSpell(); @@ -751,8 +785,6 @@ class ObjectMgr bool AddGameTele(GameTele& data); bool DeleteGameTele(const std::string& name); - CacheNpcOptionList const& GetNpcOptions() const { return m_mCacheNpcOptionList; } - uint32 GetNpcGossip(uint32 entry) const { CacheNpcTextIdMap::const_iterator iter = m_mCacheNpcTextIdMap.find(entry); @@ -800,6 +832,16 @@ class ObjectMgr return ItemRequiredTargetMapBounds(m_ItemRequiredTarget.lower_bound(uiItemEntry),m_ItemRequiredTarget.upper_bound(uiItemEntry)); } + GossipMenusMapBounds GetGossipMenusMapBounds(uint32 uiMenuId) const + { + return GossipMenusMapBounds(m_mGossipMenusMap.lower_bound(uiMenuId),m_mGossipMenusMap.upper_bound(uiMenuId)); + } + + GossipMenuItemsMapBounds GetGossipMenuItemsMapBounds(uint32 uiMenuId) const + { + return GossipMenuItemsMapBounds(m_mGossipMenuItemsMap.lower_bound(uiMenuId),m_mGossipMenuItemsMap.upper_bound(uiMenuId)); + } + protected: // first free id for selected id type @@ -841,7 +883,9 @@ class ObjectMgr RepOnKillMap mRepOnKill; - PointOfInterestMap mPointsOfInterest; + GossipMenusMap m_mGossipMenusMap; + GossipMenuItemsMap m_mGossipMenuItemsMap; + PointOfInterestMap mPointsOfInterest; WeatherZoneMap mWeatherZoneMap; @@ -914,7 +958,6 @@ class ObjectMgr typedef std::vector ConditionStore; ConditionStore mConditions; - CacheNpcOptionList m_mCacheNpcOptionList; CacheNpcTextIdMap m_mCacheNpcTextIdMap; CacheVendorItemMap m_mCacheVendorItemMap; CacheTrainerSpellMap m_mCacheTrainerSpellMap; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 354272a51..4d34ff7f4 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -12179,126 +12179,148 @@ void Player::SendNewItem(Item *item, uint32 count, bool received, bool created, /*** GOSSIP SYSTEM ***/ /*********************************************************/ -void Player::PrepareGossipMenu(WorldObject *pSource, uint32 gossipid) +void Player::PrepareGossipMenu(WorldObject *pSource, uint32 menuId) { PlayerMenu* pMenu = PlayerTalkClass; pMenu->ClearMenus(); - if (pSource->GetTypeId() != TYPEID_UNIT) - return; + pMenu->GetGossipMenu().SetMenuId(menuId); - Creature *pCreature = (Creature*)pSource; + GossipMenuItemsMapBounds pMenuItemBounds = sObjectMgr.GetGossipMenuItemsMapBounds(menuId); - // lazy loading single time at use - pCreature->LoadGossipOptions(); - - GossipOptionList &iOptList = pCreature->GetGossipOptionList(); - - for(GossipOptionList::iterator i = iOptList.begin( ); i != iOptList.end( ); ++i) + for(GossipMenuItemsMap::const_iterator itr = pMenuItemBounds.first; itr != pMenuItemBounds.second; ++itr) { - GossipOption* gso = &*i; + bool bCanTalk = true; - if (gso->GossipId == gossipid) + if (itr->second.cond_1 && !sObjectMgr.IsPlayerMeetToCondition(this, itr->second.cond_1)) + continue; + + if (itr->second.cond_2 && !sObjectMgr.IsPlayerMeetToCondition(this, itr->second.cond_2)) + continue; + + if (itr->second.cond_3 && !sObjectMgr.IsPlayerMeetToCondition(this, itr->second.cond_3)) + continue; + + if (pSource->GetTypeId() == TYPEID_UNIT) { - bool cantalking = true; + Creature *pCreature = (Creature*)pSource; - if (gso->Id == 1) + uint32 npcflags = pCreature->GetUInt32Value(UNIT_NPC_FLAGS); + + if (!(itr->second.npc_option_npcflag & npcflags)) + continue; + + switch(itr->second.option_id) { - uint32 textid = GetGossipTextId(pSource); - - GossipText const* gossiptext = sObjectMgr.GetGossipText(textid); - - if (!gossiptext) - cantalking = false; - } - else - { - switch(gso->Action) + case GOSSIP_OPTION_QUESTGIVER: + PrepareQuestMenu(pSource->GetGUID()); + bCanTalk = false; + break; + case GOSSIP_OPTION_ARMORER: + bCanTalk = false; // added in special mode + break; + case GOSSIP_OPTION_SPIRITHEALER: + if (!isDead()) + bCanTalk = false; + break; + case GOSSIP_OPTION_VENDOR: { - case GOSSIP_OPTION_QUESTGIVER: + VendorItemData const* vItems = pCreature->GetVendorItems(); + if (!vItems || vItems->Empty()) + { + sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.", pCreature->GetGUIDLow(), pCreature->GetEntry()); + bCanTalk = false; + } + break; + } + case GOSSIP_OPTION_TRAINER: + if (!pCreature->isCanTrainingOf(this, false)) + bCanTalk = false; + break; + case GOSSIP_OPTION_UNLEARNTALENTS: + if (!pCreature->isCanTrainingAndResetTalentsOf(this)) + bCanTalk = false; + break; + case GOSSIP_OPTION_UNLEARNPETSKILLS: + if (!GetPet() || GetPet()->getPetType() != HUNTER_PET || GetPet()->m_spells.size() <= 1 || pCreature->GetCreatureInfo()->trainer_type != TRAINER_TYPE_PETS || pCreature->GetCreatureInfo()->trainer_class != CLASS_HUNTER) + bCanTalk = false; + break; + case GOSSIP_OPTION_TAXIVENDOR: + if (GetSession()->SendLearnNewTaxiNode(pCreature)) + return; + break; + case GOSSIP_OPTION_BATTLEFIELD: + if (!pCreature->isCanInteractWithBattleMaster(this, false)) + bCanTalk = false; + break; + case GOSSIP_OPTION_STABLEPET: + if (!GetPet() || GetPet()->getPetType() != HUNTER_PET) + bCanTalk = false; + break; + case GOSSIP_OPTION_GOSSIP: + case GOSSIP_OPTION_SPIRITGUIDE: + case GOSSIP_OPTION_INNKEEPER: + case GOSSIP_OPTION_BANKER: + case GOSSIP_OPTION_PETITIONER: + case GOSSIP_OPTION_TABARDDESIGNER: + case GOSSIP_OPTION_AUCTIONEER: + break; // no checks + default: + sLog.outErrorDb("Creature entry %u have unknown gossip option %u for menu %u", pCreature->GetEntry(), itr->second.option_id, itr->second.menu_id); + bCanTalk = false; + break; + } + } + else if (pSource->GetTypeId() == TYPEID_GAMEOBJECT) + { + GameObject *pGo = (GameObject*)pSource; + + switch(itr->second.option_id) + { + case GOSSIP_OPTION_QUESTGIVER: + if (pGo->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) PrepareQuestMenu(pSource->GetGUID()); - //if (pm->GetQuestMenu()->MenuItemCount() == 0) - cantalking = false; - //pm->GetQuestMenu()->ClearMenu(); - break; - case GOSSIP_OPTION_ARMORER: - cantalking = false; // added in special mode - break; - case GOSSIP_OPTION_SPIRITHEALER: - if (!isDead()) - cantalking = false; - break; - case GOSSIP_OPTION_VENDOR: - { - VendorItemData const* vItems = pCreature->GetVendorItems(); - if (!vItems || vItems->Empty()) - { - sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.", - pCreature->GetGUIDLow(), pCreature->GetEntry()); - cantalking = false; - } - break; - } - case GOSSIP_OPTION_TRAINER: - if (!pCreature->isCanTrainingOf(this, false)) - cantalking = false; - break; - case GOSSIP_OPTION_UNLEARNTALENTS: - if (!pCreature->isCanTrainingAndResetTalentsOf(this)) - cantalking = false; - break; - case GOSSIP_OPTION_UNLEARNPETSKILLS: - if(!GetPet() || GetPet()->getPetType() != HUNTER_PET || GetPet()->m_spells.size() <= 1 || pCreature->GetCreatureInfo()->trainer_type != TRAINER_TYPE_PETS || pCreature->GetCreatureInfo()->trainer_class != CLASS_HUNTER) - cantalking = false; - break; - case GOSSIP_OPTION_TAXIVENDOR: - if (GetSession()->SendLearnNewTaxiNode(pCreature)) - return; - break; - case GOSSIP_OPTION_BATTLEFIELD: - if (!pCreature->isCanInteractWithBattleMaster(this, false)) - cantalking = false; - break; - case GOSSIP_OPTION_SPIRITGUIDE: - case GOSSIP_OPTION_INNKEEPER: - case GOSSIP_OPTION_BANKER: - case GOSSIP_OPTION_PETITIONER: - case GOSSIP_OPTION_STABLEPET: - case GOSSIP_OPTION_TABARDDESIGNER: - case GOSSIP_OPTION_AUCTIONEER: - break; // no checks - default: - sLog.outErrorDb("Creature %u (entry: %u) have unknown gossip option %u", pCreature->GetDBTableGUIDLow(), pCreature->GetEntry(), gso->Action); - break; - } + bCanTalk = false; + break; + case GOSSIP_OPTION_GOSSIP: + if (pGo->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER || pGo->GetGoType() != GAMEOBJECT_TYPE_GOOBER) + bCanTalk = false; + break; + default: + sLog.outErrorDb("GameObject entry %u are using invalid gossip option %u for menu %u", pGo->GetEntry(), itr->second.option_id, itr->second.menu_id); + bCanTalk = false; + break; } + } - //note for future dev: should have database fields for BoxMessage & BoxMoney - if (!gso->OptionText.empty() && cantalking) + if (bCanTalk) + { + std::string strOptionText = itr->second.option_text; + std::string strBoxText = itr->second.box_text; + + int loc_idx = GetSession()->GetSessionDbLocaleIndex(); + + if (loc_idx >= 0) { - std::string OptionText = gso->OptionText; - std::string BoxText = gso->BoxText; - int loc_idx = GetSession()->GetSessionDbLocaleIndex(); + uint32 idxEntry = MAKE_PAIR32(menuId, itr->second.id); - if (loc_idx >= 0) + if (NpcOptionLocale const *no = sObjectMgr.GetNpcOptionLocale(idxEntry)) { - if (NpcOptionLocale const *no = sObjectMgr.GetNpcOptionLocale(gso->Id)) - { - if (no->OptionText.size() > (size_t)loc_idx && !no->OptionText[loc_idx].empty()) - OptionText = no->OptionText[loc_idx]; + if (no->OptionText.size() > (size_t)loc_idx && !no->OptionText[loc_idx].empty()) + strOptionText = no->OptionText[loc_idx]; - if (no->BoxText.size() > (size_t)loc_idx && !no->BoxText[loc_idx].empty()) - BoxText = no->BoxText[loc_idx]; - } + if (no->BoxText.size() > (size_t)loc_idx && !no->BoxText[loc_idx].empty()) + strBoxText = no->BoxText[loc_idx]; } - - pMenu->GetGossipMenu().AddMenuItem((uint8)gso->Icon,OptionText, gossipid,gso->Action,BoxText,gso->BoxMoney,gso->Coded); } + + pMenu->GetGossipMenu().AddMenuItem(itr->second.option_icon, strOptionText, 0, itr->second.option_id, strBoxText, itr->second.box_money, itr->second.box_coded); + pMenu->GetGossipMenu().AddGossipMenuItemData(itr->second.action_menu_id, itr->second.action_poi_id, itr->second.action_script_id); } } - ///some gossips aren't handled in normal way ... so we need to do it this way .. TODO: handle it in normal way ;-) - if (pMenu->Empty()) + // some gossips aren't handled in normal way ... so we need to do it this way .. TODO: handle it in normal way ;-) + /*if (pMenu->Empty()) { if (pCreature->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_TRAINER)) { @@ -12311,59 +12333,86 @@ void Player::PrepareGossipMenu(WorldObject *pSource, uint32 gossipid) // output error message if need pCreature->isCanInteractWithBattleMaster(this, true); } - } + }*/ } void Player::SendPreparedGossip(WorldObject *pSource) { - if (!pSource || pSource->GetTypeId() != TYPEID_UNIT) + if (!pSource) return; - // in case no gossip flag and quest menu not empty, open quest menu (client expect gossip menu with this flag) - if (!((Creature*)pSource)->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_GOSSIP) && !PlayerTalkClass->GetQuestMenu().Empty()) + if (pSource->GetTypeId() == TYPEID_UNIT) { - SendPreparedQuest(pSource->GetGUID()); - return; + // in case no gossip flag and quest menu not empty, open quest menu (client expect gossip menu with this flag) + if (!((Creature*)pSource)->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_GOSSIP) && !PlayerTalkClass->GetQuestMenu().Empty()) + { + SendPreparedQuest(pSource->GetGUID()); + return; + } + } + else if (pSource->GetTypeId() == TYPEID_GAMEOBJECT) + { + // probably need to find a better way here + if (!PlayerTalkClass->GetGossipMenu().GetMenuId() && !PlayerTalkClass->GetQuestMenu().Empty()) + { + SendPreparedQuest(pSource->GetGUID()); + return; + } } // in case non empty gossip menu (that not included quests list size) show it // (quest entries from quest menu will be included in list) - PlayerTalkClass->SendGossipMenu(GetGossipTextId(pSource), pSource->GetGUID()); + + uint32 textId = GetGossipTextId(pSource); + + if (uint32 menuId = PlayerTalkClass->GetGossipMenu().GetMenuId()) + textId = GetGossipTextId(menuId); + + PlayerTalkClass->SendGossipMenu(textId, pSource->GetGUID()); } -void Player::OnGossipSelect(WorldObject* pSource, uint32 option) +void Player::OnGossipSelect(WorldObject* pSource, uint32 gossipListId, uint32 menuId) { GossipMenu& gossipmenu = PlayerTalkClass->GetGossipMenu(); - if (option >= gossipmenu.MenuItemCount()) + if (gossipListId >= gossipmenu.MenuItemCount()) return; - uint32 action = gossipmenu.GetItem(option).m_gAction; - uint32 zoneid = GetZoneId(); + // if not same, then something funky is going on + if (menuId != gossipmenu.GetMenuId()) + return; + + uint32 gossipOptionId = gossipmenu.GetItem(gossipListId).m_gOptionId; uint64 guid = pSource->GetGUID(); - GossipOption const *gossip = GetGossipOption(pSource, action); - - if (!gossip) + if (pSource->GetTypeId() == TYPEID_GAMEOBJECT) { - zoneid = 0; - gossip = GetGossipOption(pSource, action); - - if (!gossip) + if (gossipOptionId > GOSSIP_OPTION_QUESTGIVER) + { + sLog.outError("Player guid %u request invalid gossip option for GameObject entry %u", GetGUIDLow(), pSource->GetEntry()); return; + } } - switch(gossip->Action) + GossipMenuItemData pMenuData = gossipmenu.GetItemData(gossipListId); + + switch(gossipOptionId) { case GOSSIP_OPTION_GOSSIP: { - uint32 textid = GetGossipTextId(action, zoneid); + if (pMenuData.m_gAction_menu) + { + PrepareGossipMenu(pSource, pMenuData.m_gAction_menu); + SendPreparedGossip(pSource); + } + else + { + PlayerTalkClass->CloseGossip(); + } - if (textid == 0) - textid = GetGossipTextId(pSource); + if (pMenuData.m_gAction_poi) + PlayerTalkClass->SendPointOfInterest(pMenuData.m_gAction_poi); - PlayerTalkClass->CloseGossip(); - PlayerTalkClass->SendTalking(textid); break; } case GOSSIP_OPTION_SPIRITHEALER: @@ -12414,9 +12463,7 @@ void Player::OnGossipSelect(WorldObject* pSource, uint32 option) GetSession()->SendAuctionHello(guid, ((Creature*)pSource)); break; case GOSSIP_OPTION_SPIRITGUIDE: - case GOSSIP_GUARD_SPELLTRAINER: - case GOSSIP_GUARD_SKILLTRAINER: - PrepareGossipMenu(pSource, gossip->Id); + PrepareGossipMenu(pSource); SendPreparedGossip(pSource); break; case GOSSIP_OPTION_BATTLEFIELD: @@ -12432,59 +12479,13 @@ void Player::OnGossipSelect(WorldObject* pSource, uint32 option) GetSession()->SendBattlegGroundList(guid, bgTypeId); break; } - default: - OnPoiSelect(pSource, gossip); - break; } } -void Player::OnPoiSelect(WorldObject *pSource, GossipOption const *gossip) -{ - if(gossip->GossipId==GOSSIP_GUARD_SPELLTRAINER || gossip->GossipId==GOSSIP_GUARD_SKILLTRAINER) - { - Poi_Icon icon = ICON_POI_BLANK; - //need add more case. - switch(gossip->Action) - { - case GOSSIP_GUARD_BANK: - icon=ICON_POI_SMALL_HOUSE; - break; - case GOSSIP_GUARD_RIDE: - icon=ICON_POI_RWHORSE; - break; - case GOSSIP_GUARD_GUILD: - icon=ICON_POI_BLUETOWER; - break; - default: - icon=ICON_POI_GREYTOWER; - break; - } - uint32 textid = GetGossipTextId(gossip->Action, GetZoneId()); - PlayerTalkClass->SendTalking(textid); - // std::string areaname= gossip->OptionText; - // how this could worked player->PlayerTalkClass->SendPointOfInterest( x, y, icon, 2, 15, areaname.c_str() ); - } -} - -uint32 Player::GetGossipTextId(uint32 action, uint32 zoneid) -{ - QueryResult *result= WorldDatabase.PQuery("SELECT textid FROM npc_gossip_textid WHERE action = '%u' AND zoneid ='%u'", action, zoneid ); - - if (!result) - return 0; - - Field *fields = result->Fetch(); - uint32 id = fields[0].GetUInt32(); - - delete result; - - return id; -} - uint32 Player::GetGossipTextId(WorldObject *pSource) { if (!pSource || pSource->GetTypeId() != TYPEID_UNIT || !((Creature*)pSource)->GetDBTableGUIDLow()) - return DEFAULT_GOSSIP_MESSAGE; + return 0; if (uint32 pos = sObjectMgr.GetNpcGossip(((Creature*)pSource)->GetDBTableGUIDLow())) return pos; @@ -12492,19 +12493,22 @@ uint32 Player::GetGossipTextId(WorldObject *pSource) return DEFAULT_GOSSIP_MESSAGE; } -GossipOption const* Player::GetGossipOption(WorldObject *pSource, uint32 id) const +uint32 Player::GetGossipTextId(uint32 menuId) { - if (pSource->GetTypeId() == TYPEID_UNIT) - { - GossipOptionList &iOptlist = ((Creature*)pSource)->GetGossipOptionList(); + uint32 textId = DEFAULT_GOSSIP_MESSAGE; - for(GossipOptionList::const_iterator i = iOptlist.begin( ); i != iOptlist.end( ); ++i) - { - if (i->Action == id) - return &*i; - } + if (!menuId) + return textId; + + GossipMenusMapBounds pMenuBounds = sObjectMgr.GetGossipMenusMapBounds(menuId); + + for(GossipMenusMap::const_iterator itr = pMenuBounds.first; itr != pMenuBounds.second; ++itr) + { + if (sObjectMgr.IsPlayerMeetToCondition(this, itr->second.cond_1) && sObjectMgr.IsPlayerMeetToCondition(this, itr->second.cond_2)) + textId = itr->second.text_id; } - return NULL; + + return textId; } /*********************************************************/ diff --git a/src/game/Player.h b/src/game/Player.h index 446b834c5..b7d29cc38 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1299,14 +1299,12 @@ class MANGOS_DLL_SPEC Player : public Unit /*** GOSSIP SYSTEM ***/ /*********************************************************/ - void PrepareGossipMenu(WorldObject *pSource, uint32 gossipid = 0); + void PrepareGossipMenu(WorldObject *pSource, uint32 menuId = 0); void SendPreparedGossip(WorldObject *pSource); - void OnGossipSelect(WorldObject *pSource, uint32 option); - void OnPoiSelect(WorldObject *pSource, GossipOption const *gossip); + void OnGossipSelect(WorldObject *pSource, uint32 gossipListId, uint32 menuId); - uint32 GetGossipTextId(uint32 action, uint32 zoneid); + uint32 GetGossipTextId(uint32 menuId); uint32 GetGossipTextId(WorldObject *pSource); - GossipOption const* GetGossipOption(WorldObject *pSource, uint32 id) const; /*********************************************************/ /*** QUEST SYSTEM ***/ diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index 87ef0b093..4d5334ebf 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -102,7 +102,7 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket & recv_data) if (Script->GossipHello(_player, pCreature)) return; - _player->PrepareGossipMenu(pCreature); + _player->PrepareGossipMenu(pCreature, pCreature->GetCreatureInfo()->GossipMenuId); _player->SendPreparedGossip(pCreature); } diff --git a/src/game/World.cpp b/src/game/World.cpp index ca23473be..d9b966c19 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1402,8 +1402,11 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading Npc Text Id..." ); sObjectMgr.LoadNpcTextId(); // must be after load Creature and NpcText - sLog.outString( "Loading Npc Options..." ); - sObjectMgr.LoadNpcOptions(); + sLog.outString( "Loading Gossip menus..." ); + sObjectMgr.LoadGossipMenu(); + + sLog.outString( "Loading Gossip menu options..." ); + sObjectMgr.LoadGossipMenuItems(); sLog.outString( "Loading Vendors..." ); sObjectMgr.LoadVendors(); // must be after load CreatureTemplate and ItemTemplate diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp index 0a16e71e0..513f4b51d 100644 --- a/src/shared/Database/SQLStorage.cpp +++ b/src/shared/Database/SQLStorage.cpp @@ -25,8 +25,8 @@ extern DatabasePostgre WorldDatabase; extern DatabaseMysql WorldDatabase; #endif -const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiis"; -const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiii"; +const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiis"; +const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiii"; const char CreatureDataAddonInfofmt[]="iiiiiis"; const char CreatureModelfmt[]="iffbi"; const char CreatureInfoAddonInfofmt[]="iiiiiis"; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e7f5055be..81b2993c1 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 "8922" + #define REVISION_NR "8923" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index e341811f7..a325173b9 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills" - #define REVISION_DB_MANGOS "required_8917_01_mangos_spell_proc_event" + #define REVISION_DB_MANGOS "required_8923_01_mangos_gossip" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__ From fef94f9b364af6271020ad3ee0cf7f2768b0dd9b Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 6 Dec 2009 08:19:21 +0300 Subject: [PATCH 11/59] [8924] Implement reapply permanent area auras for group. --- src/game/SpellAuras.cpp | 40 ++++++++++++++++++++++++++++++++-------- src/shared/revision_nr.h | 2 +- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 155efcaac..9311b4211 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1333,26 +1333,42 @@ bool Aura::isAffectedOnSpell(SpellEntry const *spell) const void Aura::ReapplyAffectedPassiveAuras( Unit* target ) { - std::set affectedPassives; + std::set affectedSelf; + std::set affectedAuraCaster; for(Unit::AuraMap::const_iterator itr = target->GetAuras().begin(); itr != target->GetAuras().end(); ++itr) { - // permanent passive - if (itr->second->IsPassive() && itr->second->IsPermanent() && + // permanent passive or permanent area aura + if (itr->second->IsPermanent() && (itr->second->IsPassive() || itr->second->IsAreaAura()) && // non deleted and not same aura (any with same spell id) !itr->second->IsDeleted() && itr->second->GetId() != GetId() && - // only applied by self and affected by aura - itr->second->GetCasterGUID() == target->GetGUID() && isAffectedOnSpell(itr->second->GetSpellProto())) + // and affected by aura + isAffectedOnSpell(itr->second->GetSpellProto())) { - affectedPassives.insert(itr->second->GetId()); + // only applied by self or aura caster + if(itr->second->GetCasterGUID() == target->GetGUID()) + affectedSelf.insert(itr->second->GetId()); + else if(itr->second->GetCasterGUID() == GetCasterGUID()) + affectedAuraCaster.insert(itr->second->GetId()); } } - for(std::set::const_iterator set_itr = affectedPassives.begin(); set_itr != affectedPassives.end(); ++set_itr) + for(std::set::const_iterator set_itr = affectedSelf.begin(); set_itr != affectedSelf.end(); ++set_itr) { target->RemoveAurasDueToSpell(*set_itr); target->CastSpell(m_target, *set_itr, true); } + + if (!affectedAuraCaster.empty()) + { + Unit* caster = GetCaster(); + for(std::set::const_iterator set_itr = affectedAuraCaster.begin(); set_itr != affectedAuraCaster.end(); ++set_itr) + { + target->RemoveAurasDueToSpell(*set_itr); + if (caster) + caster->CastSpell(m_target, *set_itr, true); + } + } } /*********************************************************/ @@ -1412,14 +1428,22 @@ void Aura::HandleAddModifier(bool apply, bool Real) // reapply talents to own passive persistent auras ReapplyAffectedPassiveAuras(m_target); - // re-aplly talents and passives applied to pet (it affected by player spellmods) + // re-apply talents/passives/area auras applied to pet (it affected by player spellmods) if(Pet* pet = m_target->GetPet()) ReapplyAffectedPassiveAuras(pet); + // re-apply talents/passives/area auras applied to totems (it affected by player spellmods) for(int i = 0; i < MAX_TOTEM; ++i) if(m_target->m_TotemSlot[i]) if(Creature* totem = m_target->GetMap()->GetCreature(m_target->m_TotemSlot[i])) ReapplyAffectedPassiveAuras(totem); + + // re-apply talents/passives/area auras applied to group members (it affected by player spellmods) + if (Group* group = ((Player*)m_target)->GetGroup()) + for(GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + if (Player* member = itr->getSource()) + if (member != m_target) + ReapplyAffectedPassiveAuras(member); } void Aura::HandleAddTargetTrigger(bool apply, bool /*Real*/) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 81b2993c1..abbdf1273 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 "8923" + #define REVISION_NR "8924" #endif // __REVISION_NR_H__ From 8c1ea4f4446ef675c3af4bf31a47964a026103e6 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 6 Dec 2009 08:21:25 +0300 Subject: [PATCH 12/59] [8925] Implement 34297 and rank in part health/mana effects. Original patch from unknown author. Used version provided by nanounico & KAPATEJIb Rewrited in more proper way. --- src/game/Unit.cpp | 38 +++++++++++++++++++++++++++++--------- src/shared/revision_nr.h | 2 +- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index ce7728f27..701e5ec2a 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5680,6 +5680,34 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu { switch(dummySpell->Id) { + // Leader of the Pack + case 24932: + { + // dummy m_amount store health percent (!=0 if Improved Leader of the Pack applied) + int32 heal_percent = triggeredByAura->GetModifier()->m_amount; + if (!heal_percent) + return false; + + // check explicitly only to prevent mana cast when halth cast cooldown + if (cooldown && ((Player*)this)->HasSpellCooldown(34299)) + return false; + + // health + triggered_spell_id = 34299; + basepoints0 = GetMaxHealth() * heal_percent / 100; + target = this; + + // mana to caster + if (triggeredByAura->GetCasterGUID() == GetGUID()) + { + if (SpellEntry const* manaCastEntry = sSpellStore.LookupEntry(60889)) + { + int32 mana_percent = manaCastEntry->CalculateSimpleValue(0) * heal_percent; + CastCustomSpell(this, manaCastEntry, &mana_percent, NULL, NULL, true, castItem, triggeredByAura); + } + } + break; + } // Healing Touch (Dreamwalker Raiment set) case 28719: { @@ -6999,16 +7027,8 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB } case SPELLFAMILY_DRUID: { - // Leader of the Pack - if (auraSpellInfo->Id == 24932) - { - if (triggerAmount == 0) - return false; - basepoints[0] = triggerAmount * GetMaxHealth() / 100; - trigger_spell_id = 34299; - } // Druid Forms Trinket - else if (auraSpellInfo->Id==37336) + if (auraSpellInfo->Id==37336) { switch(m_form) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index abbdf1273..bc8a17fca 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 "8924" + #define REVISION_NR "8925" #endif // __REVISION_NR_H__ From 1de6692e04c0b216746e6d13969d4cf4493ca402 Mon Sep 17 00:00:00 2001 From: balrok Date: Sat, 5 Dec 2009 10:19:38 +0000 Subject: [PATCH 13/59] [8926] BattleGround: call correct function at playerleave it will now correctly drop the flag and correctly remove the player from eye of the storm objectives + also avoid the spamming of all "Player not found!" messages in battlegrounds maybe all existing "player not found!" places should now get an assert(false) since this shouldn't happen anymore + also better error output in GetBattleGroundQueueIdFromLevel --- src/game/BattleGround.cpp | 43 ++++++++++++++++++++------------ src/game/BattleGroundEY.cpp | 4 +-- src/game/BattleGroundHandler.cpp | 3 ++- src/game/Player.cpp | 2 +- src/shared/revision_nr.h | 2 +- 5 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index 903485384..6a3b91382 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -519,11 +519,13 @@ void BattleGround::SendPacketToAll(WorldPacket *packet) { for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { + if (itr->second.OfflineRemoveTime) + continue; Player *plr = sObjectMgr.GetPlayer(itr->first); if (plr) plr->GetSession()->SendPacket(packet); else - sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); + sLog.outError("BattleGround:SendPacketToAll: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); } } @@ -531,11 +533,12 @@ void BattleGround::SendPacketToTeam(uint32 TeamID, WorldPacket *packet, Player * { for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { + if (itr->second.OfflineRemoveTime) + continue; Player *plr = sObjectMgr.GetPlayer(itr->first); - if (!plr) { - sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); + sLog.outError("BattleGround:SendPacketToTeam: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } @@ -563,11 +566,13 @@ void BattleGround::PlaySoundToTeam(uint32 SoundID, uint32 TeamID) for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { + if (itr->second.OfflineRemoveTime) + continue; Player *plr = sObjectMgr.GetPlayer(itr->first); if (!plr) { - sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); + sLog.outError("BattleGround:PlaySoundToTeam: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } @@ -586,11 +591,13 @@ void BattleGround::CastSpellOnTeam(uint32 SpellID, uint32 TeamID) { for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { + if (itr->second.OfflineRemoveTime) + continue; Player *plr = sObjectMgr.GetPlayer(itr->first); if (!plr) { - sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); + sLog.outError("BattleGround:CastSpellOnTeam: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } @@ -606,11 +613,13 @@ void BattleGround::RewardHonorToTeam(uint32 Honor, uint32 TeamID) { for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { + if (itr->second.OfflineRemoveTime) + continue; Player *plr = sObjectMgr.GetPlayer(itr->first); if (!plr) { - sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); + sLog.outError("BattleGround:RewardHonorToTeam: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } @@ -631,11 +640,13 @@ void BattleGround::RewardReputationToTeam(uint32 faction_id, uint32 Reputation, for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { + if (itr->second.OfflineRemoveTime) + continue; Player *plr = sObjectMgr.GetPlayer(itr->first); if (!plr) { - sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); + sLog.outError("BattleGround:RewardReputationToTeam: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } @@ -721,10 +732,9 @@ void BattleGround::EndBattleGround(uint32 winner) for(BattleGroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { - Player *plr = sObjectMgr.GetPlayer(itr->first); uint32 team = itr->second.Team; - if (!plr) + if (itr->second.OfflineRemoveTime) { //if rated arena match - make member lost! if (isArena() && isRated() && winner_arena_team && loser_arena_team) @@ -734,9 +744,11 @@ void BattleGround::EndBattleGround(uint32 winner) else loser_arena_team->OfflineMemberLost(itr->first, winner_rating); } - sLog.outError("BattleGround: Player (GUID: %u) not found!", GUID_LOPART(itr->first)); continue; } + Player *plr = sObjectMgr.GetPlayer(itr->first); + if (!plr) + sLog.outError("BattleGround:EndBattleGround Player (GUID: %u) not found!", GUID_LOPART(itr->first)); // should remove spirit of redemption if (plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) @@ -1285,14 +1297,13 @@ void BattleGround::EventPlayerLoggedOut(Player* player) m_Players[player->GetGUID()].OfflineRemoveTime = sWorld.GetGameTime() + MAX_OFFLINE_TIME; if (GetStatus() == STATUS_IN_PROGRESS) { - if (isBattleGround()) - EventPlayerDroppedFlag(player); - else - { - //1 player is logging out, if it is the last, then end arena! + // drop flag and handle other cleanups + RemovePlayer(player, player->GetGUID()); + + // 1 player is logging out, if it is the last, then end arena! + if (isArena()) if (GetAlivePlayersCountByTeam(player->GetTeam()) <= 1 && GetPlayersCountByTeam(GetOtherTeam(player->GetTeam()))) EndBattleGround(GetOtherTeam(player->GetTeam())); - } } } diff --git a/src/game/BattleGroundEY.cpp b/src/game/BattleGroundEY.cpp index 74f278c48..fa0b41679 100644 --- a/src/game/BattleGroundEY.cpp +++ b/src/game/BattleGroundEY.cpp @@ -134,7 +134,7 @@ void BattleGroundEY::CheckSomeoneJoinedPoint() Player *plr = sObjectMgr.GetPlayer(m_PlayersNearPoint[BG_EY_NODES_MAX][j]); if (!plr) { - sLog.outError("BattleGroundEY: Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[BG_EY_NODES_MAX][j])); + sLog.outError("BattleGroundEY:CheckSomeoneJoinedPoint: Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[BG_EY_NODES_MAX][j])); ++j; continue; } @@ -170,7 +170,7 @@ void BattleGroundEY::CheckSomeoneLeftPoint() Player *plr = sObjectMgr.GetPlayer(m_PlayersNearPoint[i][j]); if (!plr) { - sLog.outError("BattleGroundEY: Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[i][j])); + sLog.outError("BattleGroundEY:CheckSomeoneLeftPoint Player (GUID: %u) not found!", GUID_LOPART(m_PlayersNearPoint[i][j])); //move not existed player to "free space" - this will cause many error showing in log, but it is a very important bug m_PlayersNearPoint[BG_EY_NODES_MAX].push_back(m_PlayersNearPoint[i][j]); m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j); diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp index cb38b33cd..82fe63db0 100644 --- a/src/game/BattleGroundHandler.cpp +++ b/src/game/BattleGroundHandler.cpp @@ -366,7 +366,8 @@ void WorldSession::HandleBattleFieldPortOpcode( WorldPacket &recv_data ) //if player don't match battleground max level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue if (_player->getLevel() > bg->GetMaxLevel()) { - sLog.outError("Battleground: Player %s (%u) has level higher than maxlevel of battleground! Do not port him to battleground!", _player->GetName(), _player->GetGUIDLow()); + sLog.outError("Battleground: Player %s (%u) has level (%u) higher than maxlevel (%u) of battleground (%u)! Do not port him to battleground!", + _player->GetName(), _player->GetGUIDLow(), _player->getLevel(), bg->GetMaxLevel(), bg->GetTypeID()); action = 0; } } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 4d34ff7f4..7d962bb3c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -19123,7 +19123,7 @@ BGQueueIdBasedOnLevel Player::GetBattleGroundQueueIdFromLevel() const uint32 queue_id = ( getLevel() / 10) - 1; if( queue_id >= MAX_BATTLEGROUND_QUEUES ) { - sLog.outError("BattleGround: too high queue_id %u this shouldn't happen", queue_id); + sLog.outError("BattleGround: too high queue_id %u for player %u (acc: %u) with level %u", queue_id, GetGUIDLow(), GetSession()->GetAccountId(), getLevel()); return QUEUE_ID_MAX_LEVEL_80; } return BGQueueIdBasedOnLevel(queue_id); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index bc8a17fca..77963641a 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 "8925" + #define REVISION_NR "8926" #endif // __REVISION_NR_H__ From 23f603268d9d00e9ce12b6e5781c7f5d85a50b34 Mon Sep 17 00:00:00 2001 From: balrok Date: Sun, 6 Dec 2009 10:00:52 +0100 Subject: [PATCH 14/59] [8927] added missing continue for last commit --- src/game/BattleGround.cpp | 3 +++ src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index 6a3b91382..c909a6e70 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -748,7 +748,10 @@ void BattleGround::EndBattleGround(uint32 winner) } Player *plr = sObjectMgr.GetPlayer(itr->first); if (!plr) + { sLog.outError("BattleGround:EndBattleGround Player (GUID: %u) not found!", GUID_LOPART(itr->first)); + continue; + } // should remove spirit of redemption if (plr->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 77963641a..6f531c376 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 "8926" + #define REVISION_NR "8927" #endif // __REVISION_NR_H__ From ec0043ac641d8a1661b5fb336fa58b0bb42a607b Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Sun, 6 Dec 2009 11:54:19 +0100 Subject: [PATCH 15/59] [8928] Rename internal names for gossipLocale and also correct reload gossip tables Signed-off-by: NoFantasy --- src/game/Chat.cpp | 3 ++- src/game/Chat.h | 3 ++- src/game/Creature.h | 2 +- src/game/Level3.cpp | 26 ++++++++++++++++---------- src/game/ObjectMgr.cpp | 8 ++++---- src/game/ObjectMgr.h | 12 ++++++------ src/game/Player.cpp | 2 +- src/game/World.cpp | 2 +- src/shared/revision_nr.h | 2 +- 9 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 23457fdf7..b49aab964 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -423,6 +423,8 @@ ChatCommand * ChatHandler::getCommandTable() { "gameobject_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGOQuestRelationsCommand, "", NULL }, { "gameobject_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameObjectScriptsCommand, "", NULL }, { "gameobject_battleground", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadBattleEventCommand, "", NULL }, + { "gossip_menu", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGossipMenuCommand, "", NULL }, + { "gossip_menu_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGossipMenuOptionCommand, "", NULL }, { "item_enchantment_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL }, { "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL }, { "item_required_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemRequiredTragetCommand, "", NULL }, @@ -439,7 +441,6 @@ ChatCommand * ChatHandler::getCommandTable() { "mangos_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadMangosStringCommand, "", NULL }, { "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL }, { "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL }, - { "npc_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcOptionCommand, "", NULL }, { "npc_spellclick_spells", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellClickSpellsCommand, "",NULL}, { "npc_trainer", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL }, { "npc_vendor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcVendorCommand, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index a96dce943..665696a10 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -335,6 +335,8 @@ class ChatHandler bool HandleReloadGameGraveyardZoneCommand(const char* args); bool HandleReloadGameObjectScriptsCommand(const char* args); bool HandleReloadGameTeleCommand(const char* args); + bool HandleReloadGossipMenuCommand(const char* args); + bool HandleReloadGossipMenuOptionCommand(const char* args); bool HandleReloadGOQuestRelationsCommand(const char* args); bool HandleReloadGOQuestInvRelationsCommand(const char* args); bool HandleReloadItemEnchantementsCommand(const char* args); @@ -362,7 +364,6 @@ class ChatHandler bool HandleReloadMailLevelRewardCommand(const char* args); bool HandleReloadMangosStringCommand(const char* args); bool HandleReloadNpcGossipCommand(const char* args); - bool HandleReloadNpcOptionCommand(const char* args); bool HandleReloadNpcTrainerCommand(const char* args); bool HandleReloadNpcVendorCommand(const char* args); bool HandleReloadPageTextsCommand(const char* args); diff --git a/src/game/Creature.h b/src/game/Creature.h index e6e46fe79..e9031c251 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -164,7 +164,7 @@ struct CreatureLocale std::vector SubName; }; -struct NpcOptionLocale +struct GossipMenuItemsLocale { std::vector OptionText; std::vector BoxText; diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 4320b5ae0..aa72b0256 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -102,7 +102,6 @@ bool ChatHandler::HandleReloadAllLootCommand(const char*) bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/) { HandleReloadNpcGossipCommand("a"); - HandleReloadNpcOptionCommand("a"); HandleReloadNpcTrainerCommand("a"); HandleReloadNpcVendorCommand("a"); HandleReloadPointsOfInterestCommand("a"); @@ -252,6 +251,22 @@ bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*) return true; } +bool ChatHandler::HandleReloadGossipMenuCommand(const char*) +{ + sLog.outString( "Re-Loading `gossip_menu` Table!" ); + sObjectMgr.LoadGossipMenu(); + SendGlobalSysMessage("DB table `gossip_menu` reloaded."); + return true; +} + +bool ChatHandler::HandleReloadGossipMenuOptionCommand(const char*) +{ + sLog.outString( "Re-Loading `gossip_menu_option` Table!" ); + sObjectMgr.LoadGossipMenuItems(); + SendGlobalSysMessage("DB table `gossip_menu_option` reloaded."); + return true; +} + bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*) { sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" ); @@ -404,15 +419,6 @@ bool ChatHandler::HandleReloadMangosStringCommand(const char*) return true; } -bool ChatHandler::HandleReloadNpcOptionCommand(const char*) -{ - sLog.outString( "Re-Loading `npc_option` Table!" ); - //sObjectMgr.LoadGossipMenu(); - //sObjectMgr.LoadGossipMenuItems(); - SendGlobalSysMessage("DB table `npc_option` reloaded."); - return true; -} - bool ChatHandler::HandleReloadNpcGossipCommand(const char*) { sLog.outString( "Re-Loading `npc_gossip` Table!" ); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 2bacdaa39..3166d34ed 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -338,9 +338,9 @@ void ObjectMgr::LoadCreatureLocales() sLog.outString( ">> Loaded %lu creature locale strings", (unsigned long)mCreatureLocaleMap.size() ); } -void ObjectMgr::LoadNpcOptionLocales() +void ObjectMgr::LoadGossipMenuItemsLocales() { - mNpcOptionLocaleMap.clear(); // need for reload case + mGossipMenuItemsLocaleMap.clear(); // need for reload case QueryResult *result = WorldDatabase.Query("SELECT menu_id,id," "option_text_loc1,box_text_loc1,option_text_loc2,box_text_loc2," @@ -370,7 +370,7 @@ void ObjectMgr::LoadNpcOptionLocales() uint16 menuId = fields[0].GetUInt16(); uint16 id = fields[1].GetUInt16(); - NpcOptionLocale& data = mNpcOptionLocaleMap[MAKE_PAIR32(menuId,id)]; + GossipMenuItemsLocale& data = mGossipMenuItemsLocaleMap[MAKE_PAIR32(menuId,id)]; for(int i = 1; i < MAX_LOCALE; ++i) { @@ -404,7 +404,7 @@ void ObjectMgr::LoadNpcOptionLocales() delete result; sLog.outString(); - sLog.outString( ">> Loaded %lu gossip_menu_option locale strings", (unsigned long)mNpcOptionLocaleMap.size() ); + sLog.outString( ">> Loaded %lu gossip_menu_option locale strings", (unsigned long)mGossipMenuItemsLocaleMap.size() ); } void ObjectMgr::LoadPointOfInterestLocales() diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index dbb9bed72..2fc21293e 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -162,7 +162,7 @@ typedef UNORDERED_MAP QuestLocaleMap; typedef UNORDERED_MAP NpcTextLocaleMap; typedef UNORDERED_MAP PageTextLocaleMap; typedef UNORDERED_MAP MangosStringLocaleMap; -typedef UNORDERED_MAP NpcOptionLocaleMap; +typedef UNORDERED_MAP GossipMenuItemsLocaleMap; typedef UNORDERED_MAP PointOfInterestLocaleMap; typedef std::multimap QuestRelations; @@ -556,7 +556,7 @@ class ObjectMgr void LoadQuestLocales(); void LoadNpcTextLocales(); void LoadPageTextLocales(); - void LoadNpcOptionLocales(); + void LoadGossipMenuItemsLocales(); void LoadPointOfInterestLocales(); void LoadInstanceTemplate(); void LoadMailLevelRewards(); @@ -703,10 +703,10 @@ class ObjectMgr if(itr==mPageTextLocaleMap.end()) return NULL; return &itr->second; } - NpcOptionLocale const* GetNpcOptionLocale(uint32 entry) const + GossipMenuItemsLocale const* GetGossipMenuItemsLocale(uint32 entry) const { - NpcOptionLocaleMap::const_iterator itr = mNpcOptionLocaleMap.find(entry); - if(itr==mNpcOptionLocaleMap.end()) return NULL; + GossipMenuItemsLocaleMap::const_iterator itr = mGossipMenuItemsLocaleMap.find(entry); + if(itr==mGossipMenuItemsLocaleMap.end()) return NULL; return &itr->second; } PointOfInterestLocale const* GetPointOfInterestLocale(uint32 poi_id) const @@ -949,7 +949,7 @@ class ObjectMgr NpcTextLocaleMap mNpcTextLocaleMap; PageTextLocaleMap mPageTextLocaleMap; MangosStringLocaleMap mMangosStringLocaleMap; - NpcOptionLocaleMap mNpcOptionLocaleMap; + GossipMenuItemsLocaleMap mGossipMenuItemsLocaleMap; PointOfInterestLocaleMap mPointOfInterestLocaleMap; RespawnTimes mCreatureRespawnTimes; RespawnTimes mGORespawnTimes; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 7d962bb3c..dc8958d58 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -12304,7 +12304,7 @@ void Player::PrepareGossipMenu(WorldObject *pSource, uint32 menuId) { uint32 idxEntry = MAKE_PAIR32(menuId, itr->second.id); - if (NpcOptionLocale const *no = sObjectMgr.GetNpcOptionLocale(idxEntry)) + if (GossipMenuItemsLocale const *no = sObjectMgr.GetGossipMenuItemsLocale(idxEntry)) { if (no->OptionText.size() > (size_t)loc_idx && !no->OptionText[loc_idx].empty()) strOptionText = no->OptionText[loc_idx]; diff --git a/src/game/World.cpp b/src/game/World.cpp index d9b966c19..c91bba636 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1176,7 +1176,7 @@ void World::SetInitialWorldSettings() sObjectMgr.LoadQuestLocales(); sObjectMgr.LoadNpcTextLocales(); sObjectMgr.LoadPageTextLocales(); - sObjectMgr.LoadNpcOptionLocales(); + sObjectMgr.LoadGossipMenuItemsLocales(); sObjectMgr.LoadPointOfInterestLocales(); sObjectMgr.SetDBCLocaleIndex(GetDefaultDbcLocale()); // Get once for all the locale index of DBC language (console/broadcasts) sLog.outString( ">>> Localization strings loaded" ); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 6f531c376..7883c9cec 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 "8927" + #define REVISION_NR "8928" #endif // __REVISION_NR_H__ From 5d2189b7b74eb07e1d1e1af15b4a53ca585be8c9 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Sun, 6 Dec 2009 19:44:44 +0100 Subject: [PATCH 16/59] [8929] Implement gossip scripts to be used with gossip_menu_option.action_script_id Note that script is implemented for GOSSIP_OPTION_GOSSIP only (as not expected needed for other gossip options). Also add a few more startup checks for LoadGossipMenuItems with check for basic errors in fields --- sql/mangos.sql | 29 +++++++++- sql/updates/8929_01_mangos_gossip_scripts.sql | 15 +++++ sql/updates/Makefile.am | 2 + src/game/GossipDef.h | 6 +- src/game/ObjectMgr.cpp | 58 +++++++++++++++++-- src/game/ObjectMgr.h | 2 + src/game/Player.cpp | 8 +++ src/game/World.cpp | 3 + src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 10 files changed, 116 insertions(+), 11 deletions(-) create mode 100644 sql/updates/8929_01_mangos_gossip_scripts.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 496dc9075..d782ee46c 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_8923_01_mangos_gossip` bit(1) default NULL + `required_8929_01_mangos_gossip_scripts` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -1981,6 +1981,33 @@ INSERT INTO gossip_menu_option VALUES /*!40000 ALTER TABLE `gossip_menu` ENABLE KEYS */; UNLOCK TABLES; +-- +-- Table structure for table `gossip_scripts` +-- + +DROP TABLE IF EXISTS `gossip_scripts`; +CREATE TABLE `gossip_scripts` ( + `id` mediumint(8) unsigned NOT NULL default '0', + `delay` int(10) unsigned NOT NULL default '0', + `command` mediumint(8) unsigned NOT NULL default '0', + `datalong` mediumint(8) unsigned NOT NULL default '0', + `datalong2` int(10) unsigned NOT NULL default '0', + `dataint` int(11) NOT NULL default '0', + `x` float NOT NULL default '0', + `y` float NOT NULL default '0', + `z` float NOT NULL default '0', + `o` float NOT NULL default '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- +-- Dumping data for table `gossip_scripts` +-- + +LOCK TABLES `gossip_scripts` WRITE; +/*!40000 ALTER TABLE `gossip_scripts` DISABLE KEYS */; +/*!40000 ALTER TABLE `gossip_scripts` ENABLE KEYS */; +UNLOCK TABLES; + -- -- Table structure for table `instance_template` -- diff --git a/sql/updates/8929_01_mangos_gossip_scripts.sql b/sql/updates/8929_01_mangos_gossip_scripts.sql new file mode 100644 index 000000000..0a52a37da --- /dev/null +++ b/sql/updates/8929_01_mangos_gossip_scripts.sql @@ -0,0 +1,15 @@ +ALTER TABLE db_version CHANGE COLUMN required_8923_01_mangos_gossip required_8929_01_mangos_gossip_scripts bit; + +DROP TABLE IF EXISTS `gossip_scripts`; +CREATE TABLE `gossip_scripts` ( + `id` mediumint(8) unsigned NOT NULL default '0', + `delay` int(10) unsigned NOT NULL default '0', + `command` mediumint(8) unsigned NOT NULL default '0', + `datalong` mediumint(8) unsigned NOT NULL default '0', + `datalong2` int(10) unsigned NOT NULL default '0', + `dataint` int(11) NOT NULL default '0', + `x` float NOT NULL default '0', + `y` float NOT NULL default '0', + `z` float NOT NULL default '0', + `o` float NOT NULL default '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 14b603189..a130d0092 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -190,6 +190,7 @@ pkgdata_DATA = \ 8912_01_mangos_spell_proc_event.sql \ 8917_01_mangos_spell_proc_event.sql \ 8923_01_mangos_gossip.sql \ + 8929_01_mangos_gossip_scripts.sql \ README ## Additional files to include when running 'make dist' @@ -360,4 +361,5 @@ EXTRA_DIST = \ 8912_01_mangos_spell_proc_event.sql \ 8917_01_mangos_spell_proc_event.sql \ 8923_01_mangos_gossip.sql \ + 8929_01_mangos_gossip_scripts.sql \ README diff --git a/src/game/GossipDef.h b/src/game/GossipDef.h index 335b010ca..1cb39b7d0 100644 --- a/src/game/GossipDef.h +++ b/src/game/GossipDef.h @@ -47,7 +47,8 @@ enum Gossip_Option GOSSIP_OPTION_STABLEPET = 14, //UNIT_NPC_FLAG_STABLE (4194304) GOSSIP_OPTION_ARMORER = 15, //UNIT_NPC_FLAG_ARMORER (4096) GOSSIP_OPTION_UNLEARNTALENTS = 16, //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER) - GOSSIP_OPTION_UNLEARNPETSKILLS = 17 //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER) + GOSSIP_OPTION_UNLEARNPETSKILLS = 17, //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER) + GOSSIP_OPTION_MAX }; enum GossipOptionIcon @@ -62,7 +63,8 @@ enum GossipOptionIcon GOSSIP_ICON_TALK = 7, //white chat bubble with black dots GOSSIP_ICON_TABARD = 8, //tabard GOSSIP_ICON_BATTLE = 9, //two swords - GOSSIP_ICON_DOT = 10 //yellow dot + GOSSIP_ICON_DOT = 10, //yellow dot + GOSSIP_ICON_MAX }; //POI icons. Many more exist, list not complete. diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 3166d34ed..117cd0867 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -43,6 +43,7 @@ #include "SpellAuras.h" #include "Util.h" #include "WaypointManager.h" +#include "GossipDef.h" INSTANTIATE_SINGLETON_1(ObjectMgr); @@ -51,6 +52,7 @@ ScriptMapMap sQuestStartScripts; ScriptMapMap sSpellScripts; ScriptMapMap sGameObjectScripts; ScriptMapMap sEventScripts; +ScriptMapMap sGossipScripts; bool normalizePlayerName(std::string& name) { @@ -4442,6 +4444,13 @@ void ObjectMgr::LoadEventScripts() } } +void ObjectMgr::LoadGossipScripts() +{ + LoadScripts(sGossipScripts, "gossip_scripts"); + + // checks are done in LoadGossipMenuItems +} + void ObjectMgr::LoadItemTexts() { QueryResult *result = CharacterDatabase.Query("SELECT id, text FROM item_text"); @@ -7918,7 +7927,7 @@ void ObjectMgr::LoadGossipMenuItems() bar.step(); sLog.outString(); - sLog.outErrorDb(">> Loaded gossip_menu_items, table is empty!"); + sLog.outErrorDb(">> Loaded gossip_menu_option, table is empty!"); return; } @@ -7926,6 +7935,11 @@ void ObjectMgr::LoadGossipMenuItems() uint32 count = 0; + std::set gossipScriptSet; + + for(ScriptMapMap::const_iterator itr = sGossipScripts.begin(); itr != sGossipScripts.end(); ++itr) + gossipScriptSet.insert(itr->first); + do { bar.step(); @@ -7959,26 +7973,52 @@ void ObjectMgr::LoadGossipMenuItems() if (!PlayerCondition::IsValid(cond_1, cond_1_val_1, cond_1_val_2)) { - sLog.outErrorDb("Table gossip_menu_items menu %u, invalid condition 1 for id %u", gMenuItem.menu_id, gMenuItem.id); + sLog.outErrorDb("Table gossip_menu_option menu %u, invalid condition 1 for id %u", gMenuItem.menu_id, gMenuItem.id); continue; } if (!PlayerCondition::IsValid(cond_2, cond_2_val_1, cond_2_val_2)) { - sLog.outErrorDb("Table gossip_menu_items menu %u, invalid condition 2 for id %u", gMenuItem.menu_id, gMenuItem.id); + sLog.outErrorDb("Table gossip_menu_option menu %u, invalid condition 2 for id %u", gMenuItem.menu_id, gMenuItem.id); continue; } if (!PlayerCondition::IsValid(cond_3, cond_3_val_1, cond_3_val_2)) { - sLog.outErrorDb("Table gossip_menu_items menu %u, invalid condition 3 for id %u", gMenuItem.menu_id, gMenuItem.id); + sLog.outErrorDb("Table gossip_menu_option menu %u, invalid condition 3 for id %u", gMenuItem.menu_id, gMenuItem.id); continue; } + if (gMenuItem.option_icon >= GOSSIP_ICON_MAX) + { + sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u has unknown icon id %u. Replacing with GOSSIP_ICON_CHAT", gMenuItem.menu_id, gMenuItem.id, gMenuItem.option_icon); + gMenuItem.option_icon = GOSSIP_ICON_CHAT; + } + + if (gMenuItem.option_id >= GOSSIP_OPTION_MAX) + sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u has unknown option id %u. Option will not be used", gMenuItem.menu_id, gMenuItem.id, gMenuItem.option_id); + if (gMenuItem.action_poi_id && !GetPointOfInterest(gMenuItem.action_poi_id)) { - sLog.outErrorDb("Table gossip_menu_items for menu %u, id %u use non-existing action_poi_id %u, ignoring", gMenuItem.menu_id, gMenuItem.id, gMenuItem.action_poi_id); + sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u use non-existing action_poi_id %u, ignoring", gMenuItem.menu_id, gMenuItem.id, gMenuItem.action_poi_id); gMenuItem.action_poi_id = 0; } + if (gMenuItem.action_script_id) + { + if (gMenuItem.option_id != GOSSIP_OPTION_GOSSIP) + { + sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u have action_script_id %u but option_id is not GOSSIP_OPTION_GOSSIP, ignoring", gMenuItem.menu_id, gMenuItem.id, gMenuItem.action_script_id); + continue; + } + + if (sGossipScripts.find(gMenuItem.action_script_id) == sGossipScripts.end()) + { + sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u have action_script_id %u that does not exist in `gossip_scripts`, ignoring", gMenuItem.menu_id, gMenuItem.id, gMenuItem.action_script_id); + continue; + } + + gossipScriptSet.erase(gMenuItem.action_script_id); + } + gMenuItem.cond_1 = GetConditionId(cond_1, cond_1_val_1, cond_1_val_2); gMenuItem.cond_2 = GetConditionId(cond_2, cond_2_val_1, cond_2_val_2); gMenuItem.cond_3 = GetConditionId(cond_3, cond_3_val_1, cond_3_val_2); @@ -7992,8 +8032,14 @@ void ObjectMgr::LoadGossipMenuItems() delete result; + if (!gossipScriptSet.empty()) + { + for(std::set::const_iterator itr = gossipScriptSet.begin(); itr != gossipScriptSet.end(); ++itr) + sLog.outErrorDb("Table `gossip_scripts` contain unused script, id %u.", *itr); + } + sLog.outString(); - sLog.outString(">> Loaded %u gossip_menu_items entries", count); + sLog.outString(">> Loaded %u gossip_menu_option entries", count); } void ObjectMgr::AddVendorItem( uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedcost ) diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 2fc21293e..931a853c1 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -93,6 +93,7 @@ extern ScriptMapMap sQuestStartScripts; extern ScriptMapMap sSpellScripts; extern ScriptMapMap sGameObjectScripts; extern ScriptMapMap sEventScripts; +extern ScriptMapMap sGossipScripts; struct SpellClickInfo { @@ -536,6 +537,7 @@ class ObjectMgr void LoadQuestStartScripts(); void LoadEventScripts(); void LoadSpellScripts(); + void LoadGossipScripts(); bool LoadMangosStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value); bool LoadMangosStrings() { return LoadMangosStrings(WorldDatabase,"mangos_string",MIN_MANGOS_STRING_ID,MAX_MANGOS_STRING_ID); } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index dc8958d58..d44360d5d 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -12413,6 +12413,14 @@ void Player::OnGossipSelect(WorldObject* pSource, uint32 gossipListId, uint32 me if (pMenuData.m_gAction_poi) PlayerTalkClass->SendPointOfInterest(pMenuData.m_gAction_poi); + if (pMenuData.m_gAction_script) + { + if (pSource->GetTypeId() == TYPEID_UNIT) + GetMap()->ScriptsStart(sGossipScripts, pMenuData.m_gAction_script, this, pSource); + else if (pSource->GetTypeId() == TYPEID_GAMEOBJECT) + GetMap()->ScriptsStart(sGossipScripts, pMenuData.m_gAction_script, pSource, this); + } + break; } case GOSSIP_OPTION_SPIRITHEALER: diff --git a/src/game/World.cpp b/src/game/World.cpp index c91bba636..ad772bdf7 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1402,6 +1402,9 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading Npc Text Id..." ); sObjectMgr.LoadNpcTextId(); // must be after load Creature and NpcText + sLog.outString( "Loading Gossip scripts..." ); + sObjectMgr.LoadGossipScripts(); // must be before gossip menu options + sLog.outString( "Loading Gossip menus..." ); sObjectMgr.LoadGossipMenu(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7883c9cec..27f77340c 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 "8928" + #define REVISION_NR "8929" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index a325173b9..851acb02d 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills" - #define REVISION_DB_MANGOS "required_8923_01_mangos_gossip" + #define REVISION_DB_MANGOS "required_8929_01_mangos_gossip_scripts" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__ From 258e0d73898af3f5e550cf350bde4a6620cfaf00 Mon Sep 17 00:00:00 2001 From: MrLama Date: Sun, 6 Dec 2009 21:42:07 +0300 Subject: [PATCH 17/59] [8930] Implement bonus periodic heal part for spell 19750 and ranks. Signed-off-by: VladimirMangos Also code ordering and cleanups. --- sql/mangos.sql | 3 +- .../8930_01_mangos_spell_proc_event.sql | 5 + sql/updates/Makefile.am | 2 + src/game/Unit.cpp | 116 ++++++++++-------- src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 6 files changed, 75 insertions(+), 55 deletions(-) create mode 100644 sql/updates/8930_01_mangos_spell_proc_event.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index d782ee46c..cd01f1f02 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_8929_01_mangos_gossip_scripts` bit(1) default NULL + `required_8930_01_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -18391,6 +18391,7 @@ INSERT INTO `spell_proc_event` VALUES (58364, 0x00000000, 4, 0x00000400, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (58372, 0x00000000, 4, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (58386, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0.000000, 0.000000, 0), +(58597, 0x00000000, 10, 0x40000000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0.000000, 100.000000,0), (58616, 0x00000000, 15, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (58620, 0x00000000, 15, 0x00000000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (58626, 0x00000000, 15, 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), diff --git a/sql/updates/8930_01_mangos_spell_proc_event.sql b/sql/updates/8930_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..9b05a2e63 --- /dev/null +++ b/sql/updates/8930_01_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8929_01_mangos_gossip_scripts required_8930_01_mangos_spell_proc_event bit; + +DELETE FROM `spell_proc_event` WHERE `entry` IN (58597); +INSERT INTO `spell_proc_event` VALUES +(58597, 0x00000000, 10, 0x40000000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0.000000, 100.000000,0); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index a130d0092..fa414d1ac 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -191,6 +191,7 @@ pkgdata_DATA = \ 8917_01_mangos_spell_proc_event.sql \ 8923_01_mangos_gossip.sql \ 8929_01_mangos_gossip_scripts.sql \ + 8930_01_mangos_spell_proc_event.sql \ README ## Additional files to include when running 'make dist' @@ -362,4 +363,5 @@ EXTRA_DIST = \ 8917_01_mangos_spell_proc_event.sql \ 8923_01_mangos_gossip.sql \ 8929_01_mangos_gossip_scripts.sql \ + 8930_01_mangos_spell_proc_event.sql \ README diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 701e5ec2a..1c7a8a7e8 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5933,13 +5933,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu basepoints0 = GetAttackTime(BASE_ATTACK) * int32(ap*0.022f + 0.044f * holy) / 1000; break; } - // Sacred Shield - if (dummySpell->SpellFamilyFlags & UI64LIT(0x0008000000000000)) - { - triggered_spell_id = 58597; - target = this; - break; - } // Righteous Vengeance if (dummySpell->SpellIconID == 3025) { @@ -6040,6 +6033,20 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu } break; } + // Spiritual Attunement + case 31785: + case 33776: + { + // if healed by another unit (pVictim) + if(this == pVictim) + return false; + + // heal amount + basepoints0 = triggerAmount*damage/100; + target = this; + triggered_spell_id = 31786; + break; + } // Seal of Vengeance (damage calc on apply aura) case 31801: { @@ -6077,20 +6084,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu // Replenishment CastSpell(this, 57669, true, NULL, triggeredByAura); break; - // Spiritual Attunement - case 31785: - case 33776: - { - // if healed by another unit (pVictim) - if(this == pVictim) - return false; - - // heal amount - basepoints0 = triggerAmount*damage/100; - target = this; - triggered_spell_id = 31786; - break; - } // Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal) case 40470: { @@ -6119,29 +6112,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu break; } - // Seal of Corruption (damage calc on apply aura) - case 53736: - { - if(effIndex != 0) // effect 1,2 used by seal unleashing code - return false; - - triggered_spell_id = 53742; - - // Add 5-stack effect - int8 stacks = 0; - AuraList const& auras = target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); - for(AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) - { - if( ((*itr)->GetId() == 53742) && (*itr)->GetCasterGUID()==GetGUID()) - { - stacks = (*itr)->GetStackAmount(); - break; - } - } - if(stacks >= 5) - CastSpell(target,53739,true,NULL,triggeredByAura); - break; - } // Light's Beacon (heal target area aura) case 53651: { @@ -6177,6 +6147,43 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu beacon->CastCustomSpell(beacon,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura,pVictim->GetGUID()); return true; } + // Seal of Corruption (damage calc on apply aura) + case 53736: + { + if(effIndex != 0) // effect 1,2 used by seal unleashing code + return false; + + triggered_spell_id = 53742; + + // Add 5-stack effect + int8 stacks = 0; + AuraList const& auras = target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE); + for(AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr) + { + if( ((*itr)->GetId() == 53742) && (*itr)->GetCasterGUID()==GetGUID()) + { + stacks = (*itr)->GetStackAmount(); + break; + } + } + if(stacks >= 5) + CastSpell(target,53739,true,NULL,triggeredByAura); + break; + } + // Glyph of Flash of Light + case 54936: + { + triggered_spell_id = 54957; + basepoints0 = triggerAmount*damage/100; + break; + } + // Glyph of Holy Light + case 54937: + { + triggered_spell_id = 54968; + basepoints0 = triggerAmount*damage/100; + break; + } // Glyph of Divinity case 54939: { @@ -6190,18 +6197,23 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu } return true; } - // Glyph of Flash of Light - case 54936: + // Sacred Shield (buff) + case 58597: { - triggered_spell_id = 54957; - basepoints0 = triggerAmount*damage/100; + triggered_spell_id = 66922; + SpellEntry const* triggeredEntry = sSpellStore.LookupEntry(triggered_spell_id); + if (!triggeredEntry) + return false; + + basepoints0 = int32(damage / (GetSpellDuration(triggeredEntry) / triggeredEntry->EffectAmplitude[0])); + target = this; break; } - // Glyph of Holy Light - case 54937: + // Sacred Shield (talent rank) + case 53601: { - triggered_spell_id = 54968; - basepoints0 = triggerAmount*damage/100; + triggered_spell_id = 58597; + target = this; break; } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 27f77340c..80ae63a67 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 "8929" + #define REVISION_NR "8930" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 851acb02d..c1d431514 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills" - #define REVISION_DB_MANGOS "required_8929_01_mangos_gossip_scripts" + #define REVISION_DB_MANGOS "required_8930_01_mangos_spell_proc_event" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__ From 98a83f7270701d3501235d1908c42a359c373c4f Mon Sep 17 00:00:00 2001 From: Syn Date: Sun, 6 Dec 2009 22:08:30 +0300 Subject: [PATCH 18/59] [8931] Fixed typo om `spell_bonus_data` for spell 172 Signed-off-by: VladimirMangos --- sql/mangos.sql | 4 ++-- sql/updates/8931_01_mangos_spell_bonus_data.sql | 5 +++++ sql/updates/Makefile.am | 2 ++ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 sql/updates/8931_01_mangos_spell_bonus_data.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index cd01f1f02..d12ff52b1 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_8930_01_mangos_spell_proc_event` bit(1) default NULL + `required_8931_01_mangos_spell_bonus_data` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -14148,7 +14148,7 @@ INSERT INTO `spell_bonus_data` VALUES (3606, 0.1667, 0, 0, 'Shaman - Searing Totem Attack'), /* Warlock */ (17962, 0, 0, 0, 'Warlock - Conflagrate'), -(172, 0, 0.3, 0, 'Warlock - Corruption'), +(172, 0, 0.2, 0, 'Warlock - Corruption'), (980, 0, 0.1, 0, 'Warlock - Curse of Agony'), (603, 0, 2, 0, 'Warlock - Curse of Doom'), (18220, 0.96, 0, 0, 'Warlock - Dark Pact'), diff --git a/sql/updates/8931_01_mangos_spell_bonus_data.sql b/sql/updates/8931_01_mangos_spell_bonus_data.sql new file mode 100644 index 000000000..545a7d5f0 --- /dev/null +++ b/sql/updates/8931_01_mangos_spell_bonus_data.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8930_01_mangos_spell_proc_event required_8931_01_mangos_spell_bonus_data bit; + +DELETE FROM spell_bonus_data WHERE entry = 172; +INSERT INTO spell_bonus_data (entry, direct_bonus, dot_bonus, ap_bonus, comments) VALUES +(172, 0, 0.2, 0, 'Warlock - Corruption'); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index fa414d1ac..aa0fbb7df 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -192,6 +192,7 @@ pkgdata_DATA = \ 8923_01_mangos_gossip.sql \ 8929_01_mangos_gossip_scripts.sql \ 8930_01_mangos_spell_proc_event.sql \ + 8931_01_mangos_spell_bonus_data.sql \ README ## Additional files to include when running 'make dist' @@ -364,4 +365,5 @@ EXTRA_DIST = \ 8923_01_mangos_gossip.sql \ 8929_01_mangos_gossip_scripts.sql \ 8930_01_mangos_spell_proc_event.sql \ + 8931_01_mangos_spell_bonus_data.sql \ README diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 80ae63a67..73384fe16 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 "8930" + #define REVISION_NR "8931" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index c1d431514..2ae42c3ef 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills" - #define REVISION_DB_MANGOS "required_8930_01_mangos_spell_proc_event" + #define REVISION_DB_MANGOS "required_8931_01_mangos_spell_bonus_data" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__ From 32dda71cd8d36455fee6bb482f0bac90dba8425b Mon Sep 17 00:00:00 2001 From: przemratajczak Date: Sun, 6 Dec 2009 22:26:39 +0300 Subject: [PATCH 19/59] [8932] Add spell_chain data for spell 50518 and ranks. Signed-off-by: VladimirMangos --- sql/mangos.sql | 12 +++++++++++- sql/updates/8932_01_mangos_spell_chain.sql | 10 ++++++++++ sql/updates/Makefile.am | 2 ++ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 5 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 sql/updates/8932_01_mangos_spell_chain.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index d12ff52b1..432c3177d 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_8931_01_mangos_spell_bonus_data` bit(1) default NULL + `required_8932_01_mangos_spell_chain` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -17094,6 +17094,16 @@ INSERT INTO spell_chain VALUES (53597,53596,50274,5,0), (53598,53597,50274,6,0), /*------------------ +--(767)Pet - Ravager +------------------*/ +/*Ravage*/ +(50518,0,50518,1,0), +(53558,50518,50518,2,0), +(53559,53558,50518,3,0), +(53560,53559,50518,4,0), +(53561,53560,50518,5,0), +(53562,53561,50518,6,0), +/*------------------ --(768)Pet-Serpent ------------------*/ /*PoisonSpit*/ diff --git a/sql/updates/8932_01_mangos_spell_chain.sql b/sql/updates/8932_01_mangos_spell_chain.sql new file mode 100644 index 000000000..7727f2933 --- /dev/null +++ b/sql/updates/8932_01_mangos_spell_chain.sql @@ -0,0 +1,10 @@ +ALTER TABLE db_version CHANGE COLUMN required_8931_01_mangos_spell_bonus_data required_8932_01_mangos_spell_chain bit; + +DELETE FROM spell_chain WHERE spell_id IN (50518,53558,53559,53560,53561,53562); +INSERT INTO spell_chain VALUES +(50518,0,50518,1,0), +(53558,50518,50518,2,0), +(53559,53558,50518,3,0), +(53560,53559,50518,4,0), +(53561,53560,50518,5,0), +(53562,53561,50518,6,0); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index aa0fbb7df..6d24b3bd6 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -193,6 +193,7 @@ pkgdata_DATA = \ 8929_01_mangos_gossip_scripts.sql \ 8930_01_mangos_spell_proc_event.sql \ 8931_01_mangos_spell_bonus_data.sql \ + 8932_01_mangos_spell_chain.sql \ README ## Additional files to include when running 'make dist' @@ -366,4 +367,5 @@ EXTRA_DIST = \ 8929_01_mangos_gossip_scripts.sql \ 8930_01_mangos_spell_proc_event.sql \ 8931_01_mangos_spell_bonus_data.sql \ + 8932_01_mangos_spell_chain.sql \ README diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 73384fe16..9c867a275 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 "8931" + #define REVISION_NR "8932" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 2ae42c3ef..049557284 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills" - #define REVISION_DB_MANGOS "required_8931_01_mangos_spell_bonus_data" + #define REVISION_DB_MANGOS "required_8932_01_mangos_spell_chain" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__ From 014f92870d5adc5945ab2164070f56c3af471c45 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 6 Dec 2009 22:30:44 +0300 Subject: [PATCH 20/59] [8933] Fxied typo in mangos.sql `gossip_menu_option` --- sql/mangos.sql | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/mangos.sql b/sql/mangos.sql index 432c3177d..dc135ff61 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -1978,7 +1978,7 @@ INSERT INTO gossip_menu_option VALUES (0,13,1,'GOSSIP_OPTION_ARMORER',15,4096,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), (0,14,2,'GOSSIP_OPTION_UNLEARNTALENTS',16,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0), (0,15,2,'GOSSIP_OPTION_UNLEARNPETSKILLS',17,16,0,0,0,0,0,NULL,0,0,0,0,0,0,0,0,0); -/*!40000 ALTER TABLE `gossip_menu` ENABLE KEYS */; +/*!40000 ALTER TABLE `gossip_menu_option` ENABLE KEYS */; UNLOCK TABLES; -- diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9c867a275..925633ff8 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 "8932" + #define REVISION_NR "8933" #endif // __REVISION_NR_H__ From 486c628ce2ce1b7d507a7c3698d6c47ae3fafa08 Mon Sep 17 00:00:00 2001 From: darkstalker Date: Sun, 6 Dec 2009 23:05:25 +0300 Subject: [PATCH 21/59] [8934] Implement aura PELL_AURA_MOD_MINIMUM_SPEED (305) and it used for FORM_GHOSTWOLF. Signed-off-by: VladimirMangos --- src/game/SpellAuraDefines.h | 2 +- src/game/SpellAuras.cpp | 4 +++- src/game/SpellMgr.cpp | 4 ++++ src/game/Unit.cpp | 5 +++++ src/shared/revision_nr.h | 2 +- 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 3ccdb1ee6..9ab461284 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -347,7 +347,7 @@ enum AuraType SPELL_AURA_302 = 302, SPELL_AURA_303 = 303, SPELL_AURA_304 = 304, - SPELL_AURA_305 = 305, + SPELL_AURA_MOD_MINIMUM_SPEED = 305, SPELL_AURA_306 = 306, TOTAL_AURAS = 307 }; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 9311b4211..0e67c1cf5 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -355,7 +355,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleUnused, //302 unused (3.2.2a) &Aura::HandleNULL, //303 17 spells &Aura::HandleNULL, //304 2 spells (alcohol effect?) - &Aura::HandleNULL, //305 2 spells + &Aura::HandleAuraModIncreaseSpeed, //305 SPELL_AURA_MOD_MINIMUM_SPEED &Aura::HandleNULL //306 1 spell }; @@ -5726,6 +5726,8 @@ void Aura::HandleShapeshiftBoosts(bool apply) ((Player*)m_target)->RemoveSpellCooldown(49868); break; case FORM_GHOSTWOLF: + spellId1 = 67116; + break; case FORM_AMBIENT: case FORM_GHOUL: case FORM_STEALTH: diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index cba3c9635..75bf86ccf 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1661,6 +1661,10 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons if( spellInfo_1->SpellIconID==220 && spellInfo_2->SpellIconID==220 && spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags ) return false; + + // Ghost Wolf + if (spellInfo_1->SpellIconID == 67 && spellInfo_2->SpellIconID == 67) + return false; } // Bloodlust and Bloodthirst (multi-family check) if( spellInfo_1->Id == 2825 && spellInfo_2->SpellIconID == 38 && spellInfo_2->SpellVisual[0] == 0 ) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 1c7a8a7e8..6480b1ef4 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10364,7 +10364,12 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) // Apply strongest slow aura mod to speed int32 slow = GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED); if (slow) + { speed *=(100.0f + slow)/100.0f; + float min_speed = (float)GetMaxPositiveAuraModifier(SPELL_AURA_MOD_MINIMUM_SPEED) / 100.0f; + if (speed < min_speed) + speed = min_speed; + } SetSpeed(mtype, speed, forced); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 925633ff8..791db7c40 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 "8933" + #define REVISION_NR "8934" #endif // __REVISION_NR_H__ From 338375c16d07e03a170dd422213e3514f924dd50 Mon Sep 17 00:00:00 2001 From: MrLama Date: Sun, 6 Dec 2009 23:30:30 +0300 Subject: [PATCH 22/59] [8935] Implement talent 51480 and ranks buff at dispel 8050 and ranks. Signed-off-by: VladimirMangos --- src/game/Unit.cpp | 38 ++++++++++++++++++++++++++++++++++++-- src/shared/revision_nr.h | 2 +- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 6480b1ef4..003640faa 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3947,7 +3947,7 @@ void Unit::RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, { SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellId); - // Custom dispel case + // Custom dispel cases // Unstable Affliction if(spellEntry->SpellFamilyName == SPELLFAMILY_WARLOCK && (spellEntry->SpellFamilyFlags & UI64LIT(0x010000000000))) { @@ -3961,9 +3961,43 @@ void Unit::RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, // backfire damage and silence dispeler->CastCustomSpell(dispeler, 31117, &damage, NULL, NULL, true, NULL, NULL,casterGUID); } + return; } - else + // Flame Shock + if (spellEntry->SpellFamilyName == SPELLFAMILY_SHAMAN && (spellEntry->SpellFamilyFlags & UI64LIT(0x10000000))) + { + Unit* caster = NULL; + uint32 triggeredSpell = 0; + + if (Aura* dotAura = GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, UI64LIT(0x10000000), 0x00000000, casterGUID)) + caster = dotAura->GetCaster(); + + if (caster && !caster->isDead()) + { + Unit::AuraList const& auras = caster->GetAurasByType(SPELL_AURA_DUMMY); + for (Unit::AuraList::const_iterator i = auras.begin(); i != auras.end(); ++i) + { + switch((*i)->GetId()) + { + case 51480: triggeredSpell=64694; break;// Lava Flows, Rank 1 + case 51481: triggeredSpell=65263; break;// Lava Flows, Rank 2 + case 51482: triggeredSpell=65264; break;// Lava Flows, Rank 3 + default: continue; + } + break; + } + } + + // Remove spell auras from stack RemoveSingleSpellAurasByCasterSpell(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); + + // Haste + if (triggeredSpell) + caster->CastSpell(caster, triggeredSpell, true); + return; + } + + RemoveSingleSpellAurasByCasterSpell(spellId, casterGUID, AURA_REMOVE_BY_DISPEL); } void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 791db7c40..0506af3ee 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 "8934" + #define REVISION_NR "8935" #endif // __REVISION_NR_H__ From b0a69930313b8bb198fbaf6635bf29b675727a83 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 7 Dec 2009 14:04:12 +0300 Subject: [PATCH 23/59] [8936] Implement spell 48743 --- src/game/Spell.cpp | 38 +++++++++++++++++++++++++++++++++++++- src/game/SpellEffects.cpp | 3 +++ src/shared/revision_nr.h | 2 +- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index c55b0e06a..54dde501f 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -1685,8 +1685,16 @@ void Spell::SetTargetMap(uint32 effIndex,uint32 targetMode,UnitList& TagUnitMap) } break; case TARGET_ALL_FRIENDLY_UNITS_IN_AREA: + // Death Pact (in fact selection by player selection) + if (m_spellInfo->Id == 48743) + { + // checked in Spell::CheckCast + if (m_caster->GetTypeId()==TYPEID_PLAYER) + if (Unit* target = m_caster->GetMap()->GetPet(((Player*)m_caster)->GetSelection())) + TagUnitMap.push_back(target); + } // Wild Growth - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellIconID == 2864) + else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellIconID == 2864) { Unit* target = m_targets.getUnitTarget(); if(!target) @@ -4299,6 +4307,34 @@ SpellCastResult Spell::CheckCast(bool strict) // for effects of spells that have only one target switch(m_spellInfo->Effect[i]) { + case SPELL_EFFECT_INSTAKILL: + // Death Pact + if(m_spellInfo->Id == 48743) + { + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return SPELL_FAILED_ERROR; + + if (!((Player*)m_caster)->GetSelection()) + return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + Pet* target = m_caster->GetMap()->GetPet(((Player*)m_caster)->GetSelection()); + + // alive + if (!target || target->isDead()) + return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + // undead + if (target->GetCreatureType() != CREATURE_TYPE_UNDEAD) + return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + // owned + if (target->GetOwnerGUID() != m_caster->GetGUID()) + return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + + float dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + if (!target->IsWithinDistInMap(m_caster,dist)) + return SPELL_FAILED_OUT_OF_RANGE; + + // will set in target selection code + } + break; case SPELL_EFFECT_DUMMY: { if(m_spellInfo->SpellIconID == 1648) // Execute diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index acdfc33b8..29b55a1d8 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -2676,6 +2676,9 @@ void Spell::EffectHeal( uint32 /*i*/ ) addhealth += damageAmount; } + // Death Pact (percent heal) + else if (m_spellInfo->Id==48743) + addhealth = addhealth * m_caster->GetMaxHealth() / 100; // Swiftmend - consumes Regrowth or Rejuvenation else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND)) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0506af3ee..53bd7ebb4 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 "8935" + #define REVISION_NR "8936" #endif // __REVISION_NR_H__ From 4ee8cb35047d8479567bc1f7d644931d25803e54 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 7 Dec 2009 14:46:37 +0300 Subject: [PATCH 24/59] [8937] Small lost change, just more correct code by form. --- src/game/SpellEffects.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 29b55a1d8..916ecaace 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -2678,7 +2678,7 @@ void Spell::EffectHeal( uint32 /*i*/ ) } // Death Pact (percent heal) else if (m_spellInfo->Id==48743) - addhealth = addhealth * m_caster->GetMaxHealth() / 100; + addhealth = addhealth * unitTarget->GetMaxHealth() / 100; // Swiftmend - consumes Regrowth or Rejuvenation else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND)) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 53bd7ebb4..175bd0cbe 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 "8936" + #define REVISION_NR "8937" #endif // __REVISION_NR_H__ From a4c972faec193122f9debf8a9203df52c6801193 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 7 Dec 2009 15:43:54 +0300 Subject: [PATCH 25/59] [8938] Implement talent 50880 and ranks. --- sql/mangos.sql | 3 ++- sql/updates/8938_01_mangos_spell_proc_event.sql | 5 +++++ sql/updates/Makefile.am | 2 ++ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 5 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 sql/updates/8938_01_mangos_spell_proc_event.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index dc135ff61..37c19c84d 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_8932_01_mangos_spell_chain` bit(1) default NULL + `required_8938_01_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -18239,6 +18239,7 @@ INSERT INTO `spell_proc_event` VALUES (49622, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 60), (49657, 0x00000000, 15, 0x00000000, 0x00004000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (50781, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), +(50880, 0x00000010, 15, 0x00000000, 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (51123, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (51127, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (51128, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), diff --git a/sql/updates/8938_01_mangos_spell_proc_event.sql b/sql/updates/8938_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..40546f575 --- /dev/null +++ b/sql/updates/8938_01_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8932_01_mangos_spell_chain required_8938_01_mangos_spell_proc_event bit; + +DELETE FROM `spell_proc_event` WHERE `entry` IN (50880); +INSERT INTO `spell_proc_event` VALUES +(50880, 0x00000010, 15, 0x00000000, 0x00000800, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 6d24b3bd6..08c1c5129 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -194,6 +194,7 @@ pkgdata_DATA = \ 8930_01_mangos_spell_proc_event.sql \ 8931_01_mangos_spell_bonus_data.sql \ 8932_01_mangos_spell_chain.sql \ + 8938_01_mangos_spell_proc_event.sql \ README ## Additional files to include when running 'make dist' @@ -368,4 +369,5 @@ EXTRA_DIST = \ 8930_01_mangos_spell_proc_event.sql \ 8931_01_mangos_spell_bonus_data.sql \ 8932_01_mangos_spell_chain.sql \ + 8938_01_mangos_spell_proc_event.sql \ README diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 175bd0cbe..a9ba4bee3 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 "8937" + #define REVISION_NR "8938" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 049557284..1a6354ca0 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills" - #define REVISION_DB_MANGOS "required_8932_01_mangos_spell_chain" + #define REVISION_DB_MANGOS "required_8938_01_mangos_spell_proc_event" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__ From 17e9cafecf822679b3929a3c71a1b01060c8c349 Mon Sep 17 00:00:00 2001 From: Corfen Date: Mon, 7 Dec 2009 16:12:34 +0300 Subject: [PATCH 26/59] [8939] Fixed talent 49200 and ranks triggered spell for arcane school. Signed-off-by: VladimirMangos --- src/game/Unit.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 003640faa..1a3d0ee6e 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -7298,7 +7298,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB case SPELL_SCHOOL_NATURE: trigger_spell_id = 50488; break; case SPELL_SCHOOL_FROST: trigger_spell_id = 50485; break; case SPELL_SCHOOL_SHADOW: trigger_spell_id = 50489; break; - case SPELL_SCHOOL_ARCANE: trigger_spell_id = 54373; break; + case SPELL_SCHOOL_ARCANE: trigger_spell_id = 50486; break; default: return false; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a9ba4bee3..cd859134d 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 "8938" + #define REVISION_NR "8939" #endif // __REVISION_NR_H__ From 1f7163f449a2e65f2587aed9f86411085aee927b Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 7 Dec 2009 17:25:15 +0300 Subject: [PATCH 27/59] [8940] Make players and totems always immune to taunt. --- src/game/Player.cpp | 19 +++++++++++++++++++ src/game/Player.h | 1 + src/game/Totem.cpp | 8 ++++++++ src/shared/revision_nr.h | 2 +- 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index d44360d5d..37ac59a8d 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -21241,3 +21241,22 @@ void Player::SendDuelCountdown(uint32 counter) data << uint32(counter); // seconds GetSession()->SendPacket(&data); } + +bool Player::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const +{ + switch(spellInfo->Effect[index]) + { + case SPELL_EFFECT_ATTACK_ME: + return true; + default: + break; + } + switch(spellInfo->EffectApplyAuraName[index]) + { + case SPELL_AURA_MOD_TAUNT: + return true; + default: + break; + } + return Unit::IsImmunedToSpellEffect(spellInfo, index); +} diff --git a/src/game/Player.h b/src/game/Player.h index b7d29cc38..477701718 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1547,6 +1547,7 @@ class MANGOS_DLL_SPEC Player : public Unit TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell) const; bool IsSpellFitByClassAndRace( uint32 spell_id ) const; bool IsNeedCastPassiveSpellAtLearn(SpellEntry const* spellInfo) const; + bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const; void SendProficiency(uint8 pr1, uint32 pr2); void SendInitialSpells(); diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp index 5811c88d9..698e811c2 100644 --- a/src/game/Totem.cpp +++ b/src/game/Totem.cpp @@ -160,12 +160,20 @@ void Totem::SetTypeBySummonSpell(SpellEntry const * spellProto) bool Totem::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const { // TODO: possibly all negative auras immune? + switch(spellInfo->Effect[index]) + { + case SPELL_EFFECT_ATTACK_ME: + return true; + default: + break; + } switch(spellInfo->EffectApplyAuraName[index]) { case SPELL_AURA_PERIODIC_DAMAGE: case SPELL_AURA_PERIODIC_LEECH: case SPELL_AURA_MOD_FEAR: case SPELL_AURA_TRANSFORM: + case SPELL_AURA_MOD_TAUNT: return true; default: break; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index cd859134d..45f857087 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 "8939" + #define REVISION_NR "8940" #endif // __REVISION_NR_H__ From 65f1d6ba146d7188ca0f8a5fd57c8371de026386 Mon Sep 17 00:00:00 2001 From: Nick Nitro Date: Mon, 7 Dec 2009 18:05:38 +0300 Subject: [PATCH 28/59] [8941] Limit used energe as expected for spell 22568 and ranks. Thanks also to Sarjuuk for code simplification. Signed-off-by: VladimirMangos --- src/game/SpellEffects.cpp | 8 +++++--- src/shared/revision_nr.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 916ecaace..24afdf48d 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -515,12 +515,14 @@ void Spell::EffectSchoolDMG(uint32 effect_idx) // Ferocious Bite if (m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & UI64LIT(0x000800000)) && m_spellInfo->SpellVisual[0]==6587) { - // converts each extra point of energy into ($f1+$AP/410) additional damage + // converts up to 30 points of energy into ($f1+$AP/410) additional damage float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); float multiple = ap / 410 + m_spellInfo->DmgMultiplier[effect_idx]; - damage += int32(m_caster->GetPower(POWER_ENERGY) * multiple); damage += int32(((Player*)m_caster)->GetComboPoints() * ap * 7 / 100); - m_caster->SetPower(POWER_ENERGY,0); + uint32 energy = m_caster->GetPower(POWER_ENERGY); + uint32 used_energy = energy > 30 ? 30 : energy; + damage += int32(used_energy * multiple); + m_caster->SetPower(POWER_ENERGY,energy-used_energy); } // Rake else if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000000000001000) && m_spellInfo->Effect[2]==SPELL_EFFECT_ADD_COMBO_POINTS) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 45f857087..6cb0bafe8 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 "8940" + #define REVISION_NR "8941" #endif // __REVISION_NR_H__ From 895c84b8b0f995edcd6ea40db8940fe926b38e3a Mon Sep 17 00:00:00 2001 From: MrLama Date: Mon, 7 Dec 2009 22:12:50 +0300 Subject: [PATCH 29/59] [8942] Spells 20911 and 25899 stats bonus. Signed-off-by: VladimirMangos Also stacking rule to prevent log spam. --- src/game/SpellAuras.cpp | 12 ++++++++++++ src/game/SpellMgr.cpp | 9 +++++++++ src/shared/revision_nr.h | 2 +- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 0e67c1cf5..785ea9ec5 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2732,6 +2732,18 @@ void Aura::HandleAuraDummy(bool apply, bool Real) case SPELLFAMILY_HUNTER: break; case SPELLFAMILY_PALADIN: + switch(GetId()) + { + case 20911: // Blessing of Sanctuary + case 25899: // Greater Blessing of Sanctuary + { + if (apply) + m_target->CastSpell(m_target, 67480, true, NULL, this); + else + m_target->RemoveAurasDueToSpell(67480); + return; + } + } break; case SPELLFAMILY_SHAMAN: { diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 75bf86ccf..15b16d51c 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1412,6 +1412,10 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons if( spellId_1 == 35081 && spellInfo_2->SpellIconID==561 && spellInfo_2->SpellVisual[0]==7992) return false; + // Blessing of Sanctuary (multi-family check, some from 16 spell icon spells) + if (spellInfo_1->Id == 67480 && spellInfo_2->Id == 20911) + return false; + break; } } @@ -1640,8 +1644,13 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons // Concentration Aura and Improved Concentration Aura and Aura Mastery if ((spellInfo_1->SpellIconID == 1487) && (spellInfo_2->SpellIconID == 1487)) return false; + } + // Blessing of Sanctuary (multi-family check, some from 16 spell icon spells) + if (spellInfo_2->Id == 67480 && spellInfo_1->Id == 20911) + return false; + // Combustion and Fire Protection Aura (multi-family check) if( spellInfo_2->Id == 11129 && spellInfo_1->SpellIconID == 33 && spellInfo_1->SpellVisual[0] == 321 ) return false; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 6cb0bafe8..f8d4f3052 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 "8941" + #define REVISION_NR "8942" #endif // __REVISION_NR_H__ From e8b19056307a8a16addb9be4b1dc6f6f8d4f017e Mon Sep 17 00:00:00 2001 From: Shad00w Date: Mon, 7 Dec 2009 22:29:57 +0300 Subject: [PATCH 30/59] [8943] Add spell_chain data for 24604 and ranks. Signed-off-by: VladimirMangos --- sql/mangos.sql | 36 ++++++++++++++-------- sql/updates/8943_01_mangos_spell_chain.sql | 11 +++++++ sql/updates/Makefile.am | 2 ++ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 5 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 sql/updates/8943_01_mangos_spell_chain.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 37c19c84d..37bc53413 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_8938_01_mangos_spell_proc_event` bit(1) default NULL + `required_8943_01_mangos_spell_chain` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -15344,6 +15344,18 @@ INSERT INTO spell_chain VALUES (26801,12180,3908,5,0), (51309,26790,3908,6,0), /*------------------ +-- (202) Engineering +------------------*/ +/*Engineering*/ +(4036,0,4036,1,0), +(4037,4036,4036,2,0), +(4038,4037,4036,3,0), +(12656,4038,4036,4,0), +(20219,12656,4036,5,0), +(20222,12656,4036,5,0), +(30350,12656,4036,5,0), +(51306,30350,4036,6,0), +/*------------------ --(203)Pet-Spider --(208)Pet-Wolf --(212)Pet-Crocolisk @@ -15365,18 +15377,6 @@ INSERT INTO spell_chain VALUES (52473,27050,17253,10,0), (52474,52473,17253,11,0), /*------------------ --- (202) Engineering -------------------*/ -/*Engineering*/ -(4036,0,4036,1,0), -(4037,4036,4036,2,0), -(4038,4037,4036,3,0), -(12656,4038,4036,4,0), -(20219,12656,4036,5,0), -(20222,12656,4036,5,0), -(30350,12656,4036,5,0), -(51306,30350,4036,6,0), -/*------------------ -- (204) Pet - Voidwalker ------------------*/ /*Consume Shadows*/ @@ -15437,6 +15437,16 @@ INSERT INTO spell_chain VALUES (11785,11784,6360,4,0), (27275,11785,6360,5,0), /*------------------ +-- (208) Pet - Wolf +------------------*/ +/* Furious Howl */ +(24604,0,24604,1,0), +(64491,24604,24604,2,0), +(64492,64491,24604,3,0), +(64493,64492,24604,4,0), +(64494,64493,24604,5,0), +(64495,64494,24604,6,0), +/*------------------ -- (209) Pet - Cat ------------------*/ /*Prowl*/ diff --git a/sql/updates/8943_01_mangos_spell_chain.sql b/sql/updates/8943_01_mangos_spell_chain.sql new file mode 100644 index 000000000..5daf661a3 --- /dev/null +++ b/sql/updates/8943_01_mangos_spell_chain.sql @@ -0,0 +1,11 @@ +ALTER TABLE db_version CHANGE COLUMN required_8938_01_mangos_spell_proc_event required_8943_01_mangos_spell_chain bit; + +DELETE FROM spell_chain WHERE spell_id IN (24604,64491,64492,64493,64494,64495); +-- Furious Howl +INSERT INTO spell_chain VALUES +(24604,0,24604,1,0), +(64491,24604,24604,2,0), +(64492,64491,24604,3,0), +(64493,64492,24604,4,0), +(64494,64493,24604,5,0), +(64495,64494,24604,6,0); \ No newline at end of file diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 08c1c5129..21b930d6e 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -195,6 +195,7 @@ pkgdata_DATA = \ 8931_01_mangos_spell_bonus_data.sql \ 8932_01_mangos_spell_chain.sql \ 8938_01_mangos_spell_proc_event.sql \ + 8943_01_mangos_spell_chain.sql \ README ## Additional files to include when running 'make dist' @@ -370,4 +371,5 @@ EXTRA_DIST = \ 8931_01_mangos_spell_bonus_data.sql \ 8932_01_mangos_spell_chain.sql \ 8938_01_mangos_spell_proc_event.sql \ + 8943_01_mangos_spell_chain.sql \ README diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index f8d4f3052..a4e0ea961 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 "8942" + #define REVISION_NR "8943" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 1a6354ca0..8b67c5c7a 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills" - #define REVISION_DB_MANGOS "required_8938_01_mangos_spell_proc_event" + #define REVISION_DB_MANGOS "required_8943_01_mangos_spell_chain" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__ From ffca4301d0057863c5629054df116726a77d35fd Mon Sep 17 00:00:00 2001 From: qsa Date: Mon, 7 Dec 2009 23:18:33 +0300 Subject: [PATCH 31/59] [8944] Use DBC data for summon effect functionality. Also some more local fixes: * Alow multiply same type guardians req. for some spells. * Apply spell duration mods to summons Many summon spells must start work. Great work qsa! :) Thanks The_Game_Master for updaing patch to recent sources. Signed-off-by: VladimirMangos --- src/game/DBCEnums.h | 20 +-- src/game/DBCStores.cpp | 6 +- src/game/DBCStores.h | 2 +- src/game/DBCStructure.h | 6 +- src/game/DBCfmt.h | 2 +- src/game/SharedDefines.h | 32 ----- src/game/Spell.cpp | 18 +-- src/game/Spell.h | 9 +- src/game/SpellEffects.cpp | 252 +++++++++++++++++--------------------- src/shared/revision_nr.h | 2 +- 10 files changed, 136 insertions(+), 213 deletions(-) diff --git a/src/game/DBCEnums.h b/src/game/DBCEnums.h index 229ebd004..0c4459c2c 100644 --- a/src/game/DBCEnums.h +++ b/src/game/DBCEnums.h @@ -325,26 +325,26 @@ enum TotemCategoryType // SummonProperties.dbc, col 1 enum SummonPropGroup { - SUMMON_PROP_GROUP_UNKNOWN1 = 0, // 1160 spells in 3.0.3 - SUMMON_PROP_GROUP_UNKNOWN2 = 1, // 861 spells in 3.0.3 - SUMMON_PROP_GROUP_PETS = 2, // 52 spells in 3.0.3, pets mostly - SUMMON_PROP_GROUP_CONTROLLABLE = 3, // 13 spells in 3.0.3, mostly controllable - SUMMON_PROP_GROUP_UNKNOWN3 = 4 // 86 spells in 3.0.3, taxi/mounts + SUMMON_PROP_GROUP_WILD = 0, + SUMMON_PROP_GROUP_FRIENDLY = 1, + SUMMON_PROP_GROUP_PETS = 2, + SUMMON_PROP_GROUP_CONTROLLABLE = 3, + SUMMON_PROP_GROUP_VEHICLE = 4 }; // SummonProperties.dbc, col 3 enum SummonPropType { - SUMMON_PROP_TYPE_UNKNOWN = 0, // different summons, 1330 spells in 3.0.3 + SUMMON_PROP_TYPE_OTHER = 0, // different summons, 1330 spells in 3.0.3 SUMMON_PROP_TYPE_SUMMON = 1, // generic summons, 49 spells in 3.0.3 SUMMON_PROP_TYPE_GUARDIAN = 2, // summon guardian, 393 spells in 3.0.3 SUMMON_PROP_TYPE_ARMY = 3, // summon army, 5 spells in 3.0.3 SUMMON_PROP_TYPE_TOTEM = 4, // summon totem, 169 spells in 3.0.3 SUMMON_PROP_TYPE_CRITTER = 5, // critter/minipet, 195 spells in 3.0.3 - SUMMON_PROP_TYPE_DK = 6, // summon DRW/Ghoul, 2 spells in 3.0.3 - SUMMON_PROP_TYPE_BOMB = 7, // summon bot/bomb, 4 spells in 3.0.3 - SUMMON_PROP_TYPE_PHASING = 8, // something todo with DK prequest line, 2 spells in 3.0.3 - SUMMON_PROP_TYPE_SIEGE_VEH = 9, // summon different vehicles, 14 spells in 3.0.3 + SUMMON_PROP_TYPE_DK = 6, // summon DRW/Ghoul, 2 spells in 3.0.3 "%s's Runeblade" + SUMMON_PROP_TYPE_CONSTRUCT = 7, // summon bot/bomb, 4 spells in 3.0.3 "%s's Construct" + SUMMON_PROP_TYPE_PHASING = 8, // something todo with DK prequest line, 2 spells in 3.0.3 "%s's Opponent" + SUMMON_PROP_TYPE_SIEGE_VEH = 9, // summon different vehicles, 14 spells in 3.0.3 "%s's Vehicle" SUMMON_PROP_TYPE_DRAKE_VEH = 10, // summon drake (vehicle), 3 spells SUMMON_PROP_TYPE_LIGHTWELL = 11 // summon lightwell, 6 spells in 3.0.3 }; diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp index 743c79552..d5bf0cbc3 100644 --- a/src/game/DBCStores.cpp +++ b/src/game/DBCStores.cpp @@ -129,7 +129,7 @@ DBCStorage sSpellRangeStore(SpellRangefmt); DBCStorage sSpellRuneCostStore(SpellRuneCostfmt); DBCStorage sSpellShapeshiftStore(SpellShapeshiftfmt); DBCStorage sStableSlotPricesStore(StableSlotPricesfmt); -//DBCStorage sSummonPropertiesStore(SummonPropertiesfmt); +DBCStorage sSummonPropertiesStore(SummonPropertiesfmt); DBCStorage sTalentStore(TalentEntryfmt); TalentSpellPosMap sTalentSpellPosMap; DBCStorage sTalentTabStore(TalentTabEntryfmt); @@ -206,7 +206,7 @@ void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath+"dbc/"; - const uint32 DBCFilesCount = 80; + const uint32 DBCFilesCount = 81; barGoLink bar( DBCFilesCount ); @@ -360,7 +360,7 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRuneCostStore, dbcPath,"SpellRuneCost.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshiftForm.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc"); - //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc"); // create talent spells set diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h index 691c4354c..24aa45ace 100644 --- a/src/game/DBCStores.h +++ b/src/game/DBCStores.h @@ -136,7 +136,7 @@ extern DBCStorage sSpellRuneCostStore; extern DBCStorage sSpellShapeshiftStore; extern DBCStorage sSpellStore; extern DBCStorage sStableSlotPricesStore; -//extern DBCStorage sSummonPropertiesStore; +extern DBCStorage sSummonPropertiesStore; extern DBCStorage sTalentStore; extern DBCStorage sTalentTabStore; extern DBCStorage sTaxiNodesStore; diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index 9a43ea9e9..2e0ce9043 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -1544,17 +1544,15 @@ struct StableSlotPricesEntry uint32 Price; }; -/* unused currently struct SummonPropertiesEntry { uint32 Id; // 0 - uint32 Group; // 1, enum SummonPropGroup, 0 - can't be controlled?, 1 - something guardian?, 2 - pet?, 3 - something controllable?, 4 - taxi/mount? + uint32 Group; // 1, enum SummonPropGroup uint32 FactionId; // 2, 14 rows > 0 uint32 Type; // 3, enum SummonPropType - uint32 Slot; // 4, 0-6 + uint32 Slot; // 4, if type = SUMMON_PROP_TYPE_TOTEM, its actual slot 0-6 uint32 Flags; // 5, enum SummonPropFlags }; -*/ #define MAX_TALENT_RANK 5 #define MAX_PET_TALENT_RANK 3 // use in calculations, expected <= MAX_TALENT_RANK diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h index aa5105066..53667b17c 100644 --- a/src/game/DBCfmt.h +++ b/src/game/DBCfmt.h @@ -93,7 +93,7 @@ const char SpellRangefmt[]="nffffxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; const char SpellRuneCostfmt[]="niiii"; const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxx"; const char StableSlotPricesfmt[] = "ni"; -//const char SummonPropertiesfmt[] = "niiiii"; +const char SummonPropertiesfmt[] = "niiiii"; const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx"; const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiiix"; const char TaxiNodesEntryfmt[]="nifffssssssssssssssssxii"; diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 62fb2c029..9052f386b 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -2442,38 +2442,6 @@ enum DiminishingGroup DIMINISHING_LIMITONLY }; -enum SummonType -{ - SUMMON_TYPE_CRITTER = 41, - SUMMON_TYPE_GUARDIAN = 61, - SUMMON_TYPE_TOTEM_SLOT1 = 63, - SUMMON_TYPE_WILD = 64, - SUMMON_TYPE_POSESSED = 65, - SUMMON_TYPE_DEMON = 66, - SUMMON_TYPE_SUMMON = 67, - SUMMON_TYPE_TOTEM_SLOT2 = 81, - SUMMON_TYPE_TOTEM_SLOT3 = 82, - SUMMON_TYPE_TOTEM_SLOT4 = 83, - SUMMON_TYPE_TOTEM = 121, - SUMMON_TYPE_UNKNOWN3 = 181, - SUMMON_TYPE_UNKNOWN4 = 187, - SUMMON_TYPE_UNKNOWN1 = 247, - SUMMON_TYPE_CRITTER2 = 407, - SUMMON_TYPE_CRITTER3 = 307, - SUMMON_TYPE_UNKNOWN5 = 409, - SUMMON_TYPE_UNKNOWN2 = 427, - SUMMON_TYPE_POSESSED2 = 428, - SUMMON_TYPE_QUEST_CRITTER = 487, - SUMMON_TYPE_QUEST_WILD = 587, - SUMMON_TYPE_INFERNO = 711, - SUMMON_TYPE_GUARDIAN2 = 713, - SUMMON_TYPE_LIGHTWELL = 1141, - SUMMON_TYPE_GUARDIAN3 = 1161, - SUMMON_TYPE_CREATURE = 1302, - SUMMON_TYPE_ELEMENTAL = 1561, - SUMMON_TYPE_FORCE_OF_NATURE = 1562 -}; - enum ResponseCodes { RESPONSE_SUCCESS = 0x00, diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 54dde501f..f4f6b22ae 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2225,13 +2225,6 @@ void Spell::SetTargetMap(uint32 effIndex,uint32 targetMode,UnitList& TagUnitMap) } break; case SPELL_EFFECT_SUMMON: - if (m_spellInfo->EffectMiscValueB[effIndex] == SUMMON_TYPE_POSESSED || - m_spellInfo->EffectMiscValueB[effIndex] == SUMMON_TYPE_POSESSED2) - { - if (m_targets.getUnitTarget()) - TagUnitMap.push_back(m_targets.getUnitTarget()); - } - else TagUnitMap.push_back(m_caster); break; case SPELL_EFFECT_SUMMON_CHANGE_ITEM: @@ -4603,24 +4596,17 @@ SpellCastResult Spell::CheckCast(bool strict) // This is generic summon effect case SPELL_EFFECT_SUMMON: { - switch(m_spellInfo->EffectMiscValueB[i]) + if(SummonPropertiesEntry const *summon_prop = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i])) { - case SUMMON_TYPE_POSESSED: - case SUMMON_TYPE_POSESSED2: - case SUMMON_TYPE_DEMON: - case SUMMON_TYPE_SUMMON: - case SUMMON_TYPE_ELEMENTAL: - case SUMMON_TYPE_INFERNO: + if(summon_prop->Group == SUMMON_PROP_GROUP_PETS) { if(m_caster->GetPetGUID()) return SPELL_FAILED_ALREADY_HAVE_SUMMON; if(m_caster->GetCharmGUID()) return SPELL_FAILED_ALREADY_HAVE_CHARM; - break; } } - break; } // Not used for summon? case SPELL_EFFECT_SUMMON_PHANTASM: diff --git a/src/game/Spell.h b/src/game/Spell.h index bda3a1871..0dc845f16 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -248,8 +248,8 @@ class Spell void EffectDualWield(uint32 i); void EffectPickPocket(uint32 i); void EffectAddFarsight(uint32 i); - void EffectSummonWild(uint32 i); - void EffectSummonGuardian(uint32 i); + void EffectSummonWild(uint32 i, uint32 forceFaction = 0); + void EffectSummonGuardian(uint32 i, uint32 forceFaction = 0); void EffectHealMechanical(uint32 i); void EffectJump(uint32 i); void EffectTeleUnitsFaceCaster(uint32 i); @@ -277,7 +277,7 @@ class Spell void EffectSummonPlayer(uint32 i); void EffectActivateObject(uint32 i); void EffectApplyGlyph(uint32 i); - void EffectSummonTotem(uint32 i); + void EffectSummonTotem(uint32 i, uint8 slot = 0); void EffectEnchantHeldItem(uint32 i); void EffectSummonObject(uint32 i); void EffectResurrect(uint32 i); @@ -299,7 +299,7 @@ class Spell void EffectMilling(uint32 i); void EffectRenamePet(uint32 i); void EffectSendTaxi(uint32 i); - void EffectSummonCritter(uint32 i); + void EffectSummonCritter(uint32 i, uint32 forceFaction = 0); void EffectKnockBack(uint32 i); void EffectPlayerPull(uint32 i); void EffectDispelMechanic(uint32 i); @@ -314,7 +314,6 @@ class Spell void EffectAddExtraAttacks(uint32 i); void EffectSpiritHeal(uint32 i); void EffectSkinPlayerCorpse(uint32 i); - void EffectSummonDemon(uint32 i); void EffectStealBeneficialBuff(uint32 i); void EffectUnlearnSpecialization(uint32 i); void EffectHealPct(uint32 i); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 24afdf48d..c4d47929f 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3398,54 +3398,99 @@ void Spell::EffectApplyAreaAura(uint32 i) void Spell::EffectSummonType(uint32 i) { - switch(m_spellInfo->EffectMiscValueB[i]) + uint32 prop_id = m_spellInfo->EffectMiscValueB[i]; + SummonPropertiesEntry const *summon_prop = sSummonPropertiesStore.LookupEntry(prop_id); + if(!summon_prop) { - case SUMMON_TYPE_GUARDIAN: - case SUMMON_TYPE_POSESSED: - case SUMMON_TYPE_POSESSED2: - case SUMMON_TYPE_FORCE_OF_NATURE: - case SUMMON_TYPE_GUARDIAN2: - case SUMMON_TYPE_GUARDIAN3: - // Jewelery statue case (totem like) - if(m_spellInfo->SpellIconID == 2056) - EffectSummonTotem(i); + sLog.outError("EffectSummonType: Unhandled summon type %u", prop_id); + return; + } + + switch(summon_prop->Group) + { + // faction handled later on, or loaded from template + case SUMMON_PROP_GROUP_WILD: + case SUMMON_PROP_GROUP_FRIENDLY: + { + switch(summon_prop->Type) + { + case SUMMON_PROP_TYPE_SIEGE_VEH: + case SUMMON_PROP_TYPE_DRAKE_VEH: + { + // TODO + // EffectSummonVehicle(i); + break; + } + case SUMMON_PROP_TYPE_TOTEM: + { + EffectSummonTotem(i, summon_prop->Slot); + break; + } + case SUMMON_PROP_TYPE_SUMMON: + case SUMMON_PROP_TYPE_GUARDIAN: + case SUMMON_PROP_TYPE_ARMY: + case SUMMON_PROP_TYPE_DK: + case SUMMON_PROP_TYPE_CONSTRUCT: + { + // JC golems - 32804, etc -- fits much better totem AI + if(m_spellInfo->SpellIconID == 2056) + EffectSummonTotem(i); + if(prop_id == 832) // scrapbot + EffectSummonWild(i, summon_prop->FactionId); + else + EffectSummonGuardian(i, summon_prop->FactionId); + break; + } + case SUMMON_PROP_TYPE_CRITTER: + { + EffectSummonCritter(i, summon_prop->FactionId); + break; + } + case SUMMON_PROP_TYPE_OTHER: + case SUMMON_PROP_TYPE_PHASING: + case SUMMON_PROP_TYPE_LIGHTWELL: + { + // those are classical totems - effectbasepoints is their hp and not summon ammount! + //SUMMON_TYPE_TOTEM = 121: 23035, battlestands + //SUMMON_TYPE_TOTEM2 = 647: 52893, Anti-Magic Zone (npc used) + if(prop_id == 121 || prop_id == 647) + EffectSummonTotem(i); + else + EffectSummonWild(i, summon_prop->FactionId); + break; + } + default: + sLog.outError("EffectSummonType: Unhandled summon type %u", summon_prop->Type); + break; + } + break; + } + case SUMMON_PROP_GROUP_PETS: + { + // FIXME : multiple summons - not yet supported as pet + //1562 - force of nature - sid 33831 + //1161 - feral spirit - sid 51533 + if(prop_id == 1562) // 3 uncontrolable instead of one controllable :/ + EffectSummonGuardian(i, summon_prop->FactionId); else - EffectSummonGuardian(i); + EffectSummon(i); break; - case SUMMON_TYPE_WILD: - case SUMMON_TYPE_QUEST_WILD: - case SUMMON_TYPE_CREATURE: - EffectSummonWild(i); + } + case SUMMON_PROP_GROUP_CONTROLLABLE: + { + // no type here + // maybe wrong - but thats the handler currently used for those + EffectSummonGuardian(i, summon_prop->FactionId); break; - case SUMMON_TYPE_DEMON: - case SUMMON_TYPE_INFERNO: - EffectSummonDemon(i); - break; - case SUMMON_TYPE_SUMMON: - case SUMMON_TYPE_ELEMENTAL: - EffectSummon(i); - break; - case SUMMON_TYPE_CRITTER: - case SUMMON_TYPE_CRITTER2: - case SUMMON_TYPE_CRITTER3: - case SUMMON_TYPE_QUEST_CRITTER: - EffectSummonCritter(i); - break; - case SUMMON_TYPE_TOTEM_SLOT1: - case SUMMON_TYPE_TOTEM_SLOT2: - case SUMMON_TYPE_TOTEM_SLOT3: - case SUMMON_TYPE_TOTEM_SLOT4: - case SUMMON_TYPE_TOTEM: - EffectSummonTotem(i); - break; - case SUMMON_TYPE_UNKNOWN1: - case SUMMON_TYPE_UNKNOWN2: - case SUMMON_TYPE_UNKNOWN3: - case SUMMON_TYPE_UNKNOWN4: - case SUMMON_TYPE_UNKNOWN5: + } + case SUMMON_PROP_GROUP_VEHICLE: + { + // TODO + // EffectSummonVehicle(i); break; + } default: - sLog.outError("EffectSummonType: Unhandled summon type %u", m_spellInfo->EffectMiscValueB[i]); + sLog.outError("EffectSummonType: Unhandled summon group type %u", summon_prop->Group); break; } } @@ -3463,6 +3508,10 @@ void Spell::EffectSummon(uint32 i) uint32 level = m_caster->getLevel(); Pet* spawnCreature = new Pet(SUMMON_PET); + int32 duration = GetSpellDuration(m_spellInfo); + if(Player* modOwner = m_caster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); + if (m_caster->GetTypeId()==TYPEID_PLAYER && spawnCreature->LoadPetFromDB((Player*)m_caster,pet_entry)) { // Summon in dest location @@ -3476,7 +3525,6 @@ void Spell::EffectSummon(uint32 i) } // set timer for unsummon - int32 duration = GetSpellDuration(m_spellInfo); if (duration > 0) spawnCreature->SetDuration(duration); @@ -3515,7 +3563,6 @@ void Spell::EffectSummon(uint32 i) } // set timer for unsummon - int32 duration = GetSpellDuration(m_spellInfo); if (duration > 0) spawnCreature->SetDuration(duration); @@ -3786,7 +3833,7 @@ void Spell::EffectAddFarsight(uint32 i) ((Player*)m_caster)->SetFarSightGUID(dynObj->GetGUID()); } -void Spell::EffectSummonWild(uint32 i) +void Spell::EffectSummonWild(uint32 i, uint32 forceFaction) { uint32 creature_entry = m_spellInfo->EffectMiscValue[i]; if (!creature_entry) @@ -3802,9 +3849,7 @@ void Spell::EffectSummonWild(uint32 i) { uint16 skill202 = ((Player*)m_caster)->GetSkillValue(SKILL_ENGINERING); if (skill202) - { level = skill202/5; - } } } @@ -3814,6 +3859,8 @@ void Spell::EffectSummonWild(uint32 i) float center_z = m_targets.m_destZ; float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + int32 duration = GetSpellDuration(m_spellInfo); + TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_OR_DEAD_DESPAWN; int32 amount = damage > 0 ? damage : 1; @@ -3838,30 +3885,23 @@ void Spell::EffectSummonWild(uint32 i) else m_caster->GetClosePoint(px, py, pz, 3.0f); - int32 duration = GetSpellDuration(m_spellInfo); + if(Creature *summon = m_caster->SummonCreature(creature_entry, px, py, pz, m_caster->GetOrientation(), summonType, duration)) + { + summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + summon->SetCreatorGUID(m_caster->GetGUID()); - TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_OR_DEAD_DESPAWN; - - m_caster->SummonCreature(creature_entry, px, py, pz, m_caster->GetOrientation(), summonType, duration); + if(forceFaction) + summon->setFaction(forceFaction); + } } } -void Spell::EffectSummonGuardian(uint32 i) +void Spell::EffectSummonGuardian(uint32 i, uint32 forceFaction) { uint32 pet_entry = m_spellInfo->EffectMiscValue[i]; if (!pet_entry) return; - // set timer for unsummon - int32 duration = GetSpellDuration(m_spellInfo); - - // Search old Guardian only for players (if casted spell not have duration or cooldown) - // FIXME: some guardians have control spell applied and controlled by player and anyway player can't summon in this time - // so this code hack in fact - if (m_caster->GetTypeId() == TYPEID_PLAYER && (duration <= 0 || GetSpellRecoveryTime(m_spellInfo) == 0)) - if(m_caster->FindGuardianWithEntry(pet_entry)) - return; // find old guardian, ignore summon - // in another case summon new uint32 level = m_caster->getLevel(); @@ -3885,6 +3925,9 @@ void Spell::EffectSummonGuardian(uint32 i) float center_z = m_targets.m_destZ; float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); + int32 duration = GetSpellDuration(m_spellInfo); + if(Player* modOwner = m_caster->GetSpellModOwner()) + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); int32 amount = damage > 0 ? damage : 1; @@ -3936,8 +3979,8 @@ void Spell::EffectSummonGuardian(uint32 i) spawnCreature->SetOwnerGUID(m_caster->GetGUID()); spawnCreature->setPowerType(POWER_MANA); - spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); - spawnCreature->setFaction(m_caster->getFaction()); + spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS, spawnCreature->GetCreatureInfo()->npcflag); + spawnCreature->setFaction(forceFaction ? forceFaction : m_caster->getFaction()); spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS, 0); spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0); @@ -5847,21 +5890,9 @@ void Spell::EffectApplyGlyph(uint32 i) } } -void Spell::EffectSummonTotem(uint32 i) +void Spell::EffectSummonTotem(uint32 i, uint8 slot) { - uint8 slot = 0; - switch(m_spellInfo->EffectMiscValueB[i]) - { - case SUMMON_TYPE_TOTEM_SLOT1: slot = 0; break; - case SUMMON_TYPE_TOTEM_SLOT2: slot = 1; break; - case SUMMON_TYPE_TOTEM_SLOT3: slot = 2; break; - case SUMMON_TYPE_TOTEM_SLOT4: slot = 3; break; - // Battle standard case - case SUMMON_TYPE_TOTEM: slot = 254; break; - // jewelery statue case, like totem without slot - case SUMMON_TYPE_GUARDIAN: slot = 255; break; - default: return; - } + slot = slot ? (slot - 1): 255; if(slot < MAX_TOTEM) { @@ -6353,7 +6384,7 @@ void Spell::EffectCharge2(uint32 /*i*/) m_caster->Attack(unitTarget,true); } -void Spell::EffectSummonCritter(uint32 i) +void Spell::EffectSummonCritter(uint32 i, uint32 forceFaction) { if(m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -6413,9 +6444,9 @@ void Spell::EffectSummonCritter(uint32 i) critter->SetOwnerGUID(m_caster->GetGUID()); critter->SetCreatorGUID(m_caster->GetGUID()); - critter->setFaction(m_caster->getFaction()); - critter->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + critter->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + critter->setFaction(forceFaction ? forceFaction : m_caster->getFaction()); critter->AIM_Initialize(); critter->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as critter... //critter->InitLevelupSpellsForLevel(); // none? @@ -6778,65 +6809,6 @@ void Spell::EffectSkill(uint32 /*i*/) sLog.outDebug("WORLD: SkillEFFECT"); } -void Spell::EffectSummonDemon(uint32 i) -{ - // select center of summon position - float center_x = m_targets.m_destX; - float center_y = m_targets.m_destY; - float center_z = m_targets.m_destZ; - - float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i])); - - int32 amount = damage > 0 ? damage : 1; - - if (m_spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_INFERNO) - amount = 1; - - for(int32 count = 0; count < amount; ++count) - { - float px, py, pz; - // If dest location if present - if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) - { - // Summon 1 unit in dest location - if (count == 0) - { - px = m_targets.m_destX; - py = m_targets.m_destY; - pz = m_targets.m_destZ; - } - // Summon in random point all other units if location present - else - m_caster->GetRandomPoint(center_x,center_y,center_z,radius,px,py,pz); - } - // Summon if dest location not present near caster - else - m_caster->GetClosePoint(px,py,pz,3.0f); - - int32 duration = GetSpellDuration(m_spellInfo); - - Creature* Charmed = m_caster->SummonCreature(m_spellInfo->EffectMiscValue[i], px, py, pz, m_caster->GetOrientation(),TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,duration); - if (!Charmed) // something fatal, not attempt more - return; - - // might not always work correctly, maybe the creature that dies from CoD casts the effect on itself and is therefore the caster? - Charmed->SetLevel(m_caster->getLevel()); - - // TODO: Add damage/mana/hp according to level - - // Enslave demon effect, without mana cost and cooldown - if (m_spellInfo->EffectMiscValue[i] == 89) // Inferno summon - { - // Enslave demon effect, without mana cost and cooldown - m_caster->CastSpell(Charmed, 20882, true); // FIXME: enslave does not scale with level, level 62+ minions cannot be enslaved - - // Inferno effect for non player calls - if (m_spellInfo->EffectMiscValueB[i]!=SUMMON_TYPE_INFERNO) - Charmed->CastSpell(Charmed, 22703, true, 0); - } - } -} - void Spell::EffectSpiritHeal(uint32 /*i*/) { // TODO player can't see the heal-animation - he should respawn some ticks later diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a4e0ea961..88f891599 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 "8943" + #define REVISION_NR "8944" #endif // __REVISION_NR_H__ From 51bdaa6b0e97ce0cfa4ff2600972568f9ddc9b27 Mon Sep 17 00:00:00 2001 From: MrLama Date: Tue, 8 Dec 2009 09:54:58 +0300 Subject: [PATCH 32/59] [8945] Update work triggered effect for 20271 Signed-off-by: VladimirMangos --- src/game/Unit.cpp | 9 +-------- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 1a3d0ee6e..c657b83d1 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5988,14 +5988,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu // Judgement of Light case 20185: { - // Get judgement caster - Unit *caster = triggeredByAura->GetCaster(); - if (!caster) - return false; - float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK); - int32 holy = caster->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_HOLY) + - caster->SpellBaseDamageBonusForVictim(SPELL_SCHOOL_MASK_HOLY, this); - basepoints0 = int32(ap*0.10f + 0.10f*holy); + basepoints0 = int32( pVictim->GetMaxHealth() * triggeredByAura->GetModifier()->m_amount / 100 ); pVictim->CastCustomSpell(pVictim, 20267, &basepoints0, NULL, NULL, true, NULL, triggeredByAura); return true; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 88f891599..8ea387052 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 "8944" + #define REVISION_NR "8945" #endif // __REVISION_NR_H__ From 87cc1412f85ca020066cc7596bf95cea551627b9 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 8 Dec 2009 10:47:06 +0300 Subject: [PATCH 33/59] [8946] Implement talent 57499. --- sql/mangos.sql | 3 ++- sql/updates/8946_01_mangos_spell_proc_event.sql | 5 +++++ sql/updates/Makefile.am | 2 ++ src/game/Unit.cpp | 3 +++ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 6 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 sql/updates/8946_01_mangos_spell_proc_event.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 37bc53413..74c6e840c 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_8943_01_mangos_spell_chain` bit(1) default NULL + `required_8946_01_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -18404,6 +18404,7 @@ INSERT INTO `spell_proc_event` VALUES (57352, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00010154, 0x00000003, 0.000000, 0.000000, 45), (57470, 0x00000000, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (57472, 0x00000000, 6, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(57499, 0x00000000, 4, 0x40000001, 0x00010000, 0x00000000, 0x00014000, 0x00000000, 0.000000, 0.000000, 0), (57878, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0), (57880, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0), (57881, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0.000000, 0.000000, 0), diff --git a/sql/updates/8946_01_mangos_spell_proc_event.sql b/sql/updates/8946_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..d7d3bd7c5 --- /dev/null +++ b/sql/updates/8946_01_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8943_01_mangos_spell_chain required_8946_01_mangos_spell_proc_event bit; + +DELETE FROM `spell_proc_event` WHERE `entry` IN (57499); +INSERT INTO `spell_proc_event` VALUES +(57499, 0x00000000, 4, 0x40000001, 0x00010000, 0x00000000, 0x00014000, 0x00000000, 0.000000, 0.000000,0); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 21b930d6e..d2d8f63fb 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -196,6 +196,7 @@ pkgdata_DATA = \ 8932_01_mangos_spell_chain.sql \ 8938_01_mangos_spell_proc_event.sql \ 8943_01_mangos_spell_chain.sql \ + 8946_01_mangos_spell_proc_event.sql \ README ## Additional files to include when running 'make dist' @@ -372,4 +373,5 @@ EXTRA_DIST = \ 8932_01_mangos_spell_chain.sql \ 8938_01_mangos_spell_proc_event.sql \ 8943_01_mangos_spell_chain.sql \ + 8946_01_mangos_spell_proc_event.sql \ README diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index c657b83d1..b373f8022 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -7664,6 +7664,9 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, Aura case 5497: // Improved Mana Gems (Serpent-Coil Braid) triggered_spell_id = 37445; // Mana Surge break; + case 6953: // Warbringer + RemoveAurasAtMechanicImmunity(IMMUNE_TO_ROOT_AND_SNARE_MASK,0,true); + return true; case 8152: // Serendipity { // if heal your target over maximum health diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 8ea387052..0ffcbe3e1 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 "8945" + #define REVISION_NR "8946" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 8b67c5c7a..af22f542a 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills" - #define REVISION_DB_MANGOS "required_8943_01_mangos_spell_chain" + #define REVISION_DB_MANGOS "required_8946_01_mangos_spell_proc_event" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__ From 58551fb582bc498302523970c4bdf98d33b8090e Mon Sep 17 00:00:00 2001 From: laise Date: Tue, 8 Dec 2009 12:09:43 +0300 Subject: [PATCH 34/59] [8947] Implement aura SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS (245) Used in spell 6117 (5/6 ranks) Signed-off-by: VladimirMangos --- src/game/SpellAuras.cpp | 2 +- src/game/Unit.cpp | 3 +++ src/shared/revision_nr.h | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 785ea9ec5..465634e03 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -295,7 +295,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleUnused, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING (only 2 test spels in 3.2.2a) &Aura::HandleNULL, //243 faction reaction override spells &Aura::HandleComprehendLanguage, //244 SPELL_AURA_COMPREHEND_LANGUAGE - &Aura::HandleNULL, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS + &Aura::HandleNoImmediateEffect, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS implemented in Unit::CalculateSpellDuration &Aura::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL implemented in Unit::CalculateSpellDuration &Aura::HandleNULL, //247 target to become a clone of the caster &Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index b373f8022..62374a308 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10857,6 +10857,9 @@ int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_in durationMod_always+=target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL, spellProto->Dispel); // Find max mod (negative bonus) int32 durationMod_not_stack = target->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK, mechanic); + + if (!IsPositiveSpell(spellProto->Id)) + durationMod_always += target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS, spellProto->DmgClass); int32 durationMod = 0; // Select strongest negative mod diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0ffcbe3e1..e7a24c87d 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 "8946" + #define REVISION_NR "8947" #endif // __REVISION_NR_H__ From c6bf3a2cdc41f9d0a9f3e73ac0c0e337aeaee58e Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 8 Dec 2009 21:25:23 +0300 Subject: [PATCH 35/59] [8948] Not check victim at apply SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL for ranged spells In same way as for other cases. For consistance. --- src/game/Unit.cpp | 5 ++--- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 62374a308..2000aa1f6 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9046,10 +9046,9 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM case SPELL_DAMAGE_CLASS_RANGED: { if (pVictim) - { crit_chance = GetUnitCriticalChance(attackType, pVictim); - crit_chance+= GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, schoolMask); - } + + crit_chance+= GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, schoolMask); break; } default: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e7a24c87d..d028d4d8e 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 "8947" + #define REVISION_NR "8948" #endif // __REVISION_NR_H__ From dbd317712192c6073a147bced296ce23c52b0895 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 8 Dec 2009 21:59:03 +0300 Subject: [PATCH 36/59] [8949] Implement proper support spell auras with maxstack > 1 and charges > 0. * Like auras expected to be proccessed in spell proc event code (not lost charge at use in spellmods code). Exist examples for like spells that affect value in spellmods but have different expire requirements. * Propertly work with stacked auras in spell proc event code - remove only one auras from stack - in case charges exist in same time not touch charges but return expire (all really used auars with maxstack>1 and charges have 1 in one from this values) --- src/game/SpellAuras.cpp | 92 +++++++++++++++++++++------------------- src/game/SpellAuras.h | 7 +++ src/game/Unit.cpp | 6 +-- src/shared/revision_nr.h | 2 +- 4 files changed, 59 insertions(+), 48 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 465634e03..be6b9e6be 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1418,7 +1418,10 @@ void Aura::HandleAddModifier(bool apply, bool Real) mod->mask = (uint64)ptr[0] | (uint64)ptr[1]<<32; mod->mask2= (uint64)ptr[2]; - mod->charges = m_procCharges; + + // prevent expire spell mods with (charges > 0 && m_stackAmount > 1) + // all this spell expected expire not at use but at spell proc event check + mod->charges = m_spellProto->StackAmount > 1 ? 0 : m_procCharges; m_spellmod = mod; } @@ -2236,50 +2239,51 @@ void Aura::HandleAuraDummy(bool apply, bool Real) // AT APPLY if(apply) { - switch(GetId()) - { - case 1515: // Tame beast - // FIX_ME: this is 2.0.12 threat effect replaced in 2.1.x by dummy aura, must be checked for correctness - if (m_target->CanHaveThreatList()) - if (Unit* caster = GetCaster()) - m_target->AddThreat(caster, 10.0f, false, GetSpellSchoolMask(GetSpellProto()), GetSpellProto()); - return; - case 13139: // net-o-matic - // root to self part of (root_target->charge->root_self sequence - if (Unit* caster = GetCaster()) - caster->CastSpell(caster, 13138, true, NULL, this); - return; - case 39850: // Rocket Blast - if(roll_chance_i(20)) // backfire stun - m_target->CastSpell(m_target, 51581, true, NULL, this); - return; - case 43873: // Headless Horseman Laugh - m_target->PlayDistanceSound(11965); - return; - case 46354: // Blood Elf Illusion - if (Unit* caster = GetCaster()) - { - switch(caster->getGender()) - { - case GENDER_FEMALE: - caster->CastSpell(m_target, 46356, true, NULL, this); - break; - case GENDER_MALE: - caster->CastSpell(m_target, 46355, true, NULL, this); - break; - default: - break; - } - } - return; - case 46699: // Requires No Ammo - if(m_target->GetTypeId() == TYPEID_PLAYER) - ((Player*)m_target)->RemoveAmmo(); // not use ammo and not allow use - return; - } - switch(m_spellProto->SpellFamilyName) { + case SPELLFAMILY_GENERIC: + switch(GetId()) + { + case 1515: // Tame beast + // FIX_ME: this is 2.0.12 threat effect replaced in 2.1.x by dummy aura, must be checked for correctness + if (m_target->CanHaveThreatList()) + if (Unit* caster = GetCaster()) + m_target->AddThreat(caster, 10.0f, false, GetSpellSchoolMask(GetSpellProto()), GetSpellProto()); + return; + case 13139: // net-o-matic + // root to self part of (root_target->charge->root_self sequence + if (Unit* caster = GetCaster()) + caster->CastSpell(caster, 13138, true, NULL, this); + return; + case 39850: // Rocket Blast + if(roll_chance_i(20)) // backfire stun + m_target->CastSpell(m_target, 51581, true, NULL, this); + return; + case 43873: // Headless Horseman Laugh + m_target->PlayDistanceSound(11965); + return; + case 46354: // Blood Elf Illusion + if (Unit* caster = GetCaster()) + { + switch(caster->getGender()) + { + case GENDER_FEMALE: + caster->CastSpell(m_target, 46356, true, NULL, this); + break; + case GENDER_MALE: + caster->CastSpell(m_target, 46355, true, NULL, this); + break; + default: + break; + } + } + return; + case 46699: // Requires No Ammo + if(m_target->GetTypeId() == TYPEID_PLAYER) + ((Player*)m_target)->RemoveAmmo(); // not use ammo and not allow use + return; + } + break; case SPELLFAMILY_WARRIOR: // Overpower if(m_spellProto->SpellFamilyFlags & UI64LIT(0x0000000000000004)) @@ -2317,7 +2321,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real) break; case SPELLFAMILY_SHAMAN: // Earth Shield - if ((GetSpellProto()->SpellFamilyFlags & UI64LIT(0x40000000000))) + else if ((GetSpellProto()->SpellFamilyFlags & UI64LIT(0x40000000000))) { // prevent double apply bonuses if(m_target->GetTypeId() != TYPEID_PLAYER || !((Player*)m_target)->GetSession()->PlayerLoading()) diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 0695271e7..8e573d498 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -268,6 +268,13 @@ class MANGOS_DLL_SPEC Aura { if (m_procCharges == 0) return false; + + // exist spells that have maxStack > 1 and m_procCharges > 0 (==1 in fact) + // all like stacks have 1 value in one from this fields + // so return true for allow remove one aura from stacks as expired + if (GetStackAmount() > 1) + return true; + m_procCharges--; SendAuraUpdate(false); return m_procCharges == 0; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 2000aa1f6..c734dfa02 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -6471,7 +6471,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu uint32 spell = (*itr)->GetSpellProto()->EffectTriggerSpell[(*itr)->GetEffIndex()]; CastSpell(this, spell, true, castItem, triggeredByAura); if ((*itr)->DropAuraCharge()) - RemoveAurasDueToSpell((*itr)->GetId()); + RemoveSingleSpellAurasFromStack((*itr)->GetId()); return true; } } @@ -6573,7 +6573,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu } CastSpell(target, spell, true, castItem, triggeredByAura); if ((*itr)->DropAuraCharge()) - RemoveAurasDueToSpell((*itr)->GetId()); + RemoveSingleSpellAurasFromStack((*itr)->GetId()); return true; } } @@ -12039,7 +12039,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag removedSpells.unique(); // Remove auras from removedAuras for(RemoveSpellList::const_iterator i = removedSpells.begin(); i != removedSpells.end();++i) - RemoveAurasDueToSpell(*i); + RemoveSingleSpellAurasFromStack(*i); } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d028d4d8e..14633a166 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 "8948" + #define REVISION_NR "8949" #endif // __REVISION_NR_H__ From 05d1dc40dc3f5717af0b9f13f65f862ebbf80722 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 8 Dec 2009 22:06:26 +0300 Subject: [PATCH 37/59] [8950] Implement talent 55198. --- sql/mangos.sql | 3 ++- sql/updates/8950_01_mangos_spell_proc_event.sql | 5 +++++ sql/updates/Makefile.am | 2 ++ src/game/SpellAuras.cpp | 10 ++++++++++ src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 6 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 sql/updates/8950_01_mangos_spell_proc_event.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 74c6e840c..125747865 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_8946_01_mangos_spell_proc_event` bit(1) default NULL + `required_8950_01_mangos_spell_proc_event` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -18368,6 +18368,7 @@ INSERT INTO `spell_proc_event` VALUES (54936, 0x00000000, 10, 0x40000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (54937, 0x00000000, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (54939, 0x00000000, 10, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), +(55166, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0), (55380, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), (55440, 0x00000000, 11, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0), (55640, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45), diff --git a/sql/updates/8950_01_mangos_spell_proc_event.sql b/sql/updates/8950_01_mangos_spell_proc_event.sql new file mode 100644 index 000000000..9d7a27546 --- /dev/null +++ b/sql/updates/8950_01_mangos_spell_proc_event.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_8946_01_mangos_spell_proc_event required_8950_01_mangos_spell_proc_event bit; + +DELETE FROM `spell_proc_event` WHERE `entry` IN (55166); +INSERT INTO `spell_proc_event` VALUES +(55166, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000,0); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index d2d8f63fb..101077bde 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -197,6 +197,7 @@ pkgdata_DATA = \ 8938_01_mangos_spell_proc_event.sql \ 8943_01_mangos_spell_chain.sql \ 8946_01_mangos_spell_proc_event.sql \ + 8950_01_mangos_spell_proc_event.sql \ README ## Additional files to include when running 'make dist' @@ -374,4 +375,5 @@ EXTRA_DIST = \ 8938_01_mangos_spell_proc_event.sql \ 8943_01_mangos_spell_chain.sql \ 8946_01_mangos_spell_proc_event.sql \ + 8950_01_mangos_spell_proc_event.sql \ README diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index be6b9e6be..0e2469377 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2320,6 +2320,16 @@ void Aura::HandleAuraDummy(bool apply, bool Real) } break; case SPELLFAMILY_SHAMAN: + // Tidal Force + if (GetId() == 55198) + { + // apply max stack bufs + SpellEntry const* buffEntry = sSpellStore.LookupEntry(55166); + if (!buffEntry) + return; + for(int k = 0; k < buffEntry->StackAmount; ++k) + m_target->CastSpell(m_target, buffEntry, true, NULL, this); + } // Earth Shield else if ((GetSpellProto()->SpellFamilyFlags & UI64LIT(0x40000000000))) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 14633a166..197a61f90 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 "8949" + #define REVISION_NR "8950" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index af22f542a..7dfbed989 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills" - #define REVISION_DB_MANGOS "required_8946_01_mangos_spell_proc_event" + #define REVISION_DB_MANGOS "required_8950_01_mangos_spell_proc_event" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__ From e150887b867f4259f470861d4291bfaf6ece1ae4 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 8 Dec 2009 22:09:41 +0300 Subject: [PATCH 38/59] Remove trailing spaces --- src/game/SpellAuras.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 0e2469377..36c53c22f 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1418,7 +1418,7 @@ void Aura::HandleAddModifier(bool apply, bool Real) mod->mask = (uint64)ptr[0] | (uint64)ptr[1]<<32; mod->mask2= (uint64)ptr[2]; - + // prevent expire spell mods with (charges > 0 && m_stackAmount > 1) // all this spell expected expire not at use but at spell proc event check mod->charges = m_spellProto->StackAmount > 1 ? 0 : m_procCharges; From d604b0a12048dd50c2609ddea0d31451dd81f932 Mon Sep 17 00:00:00 2001 From: Qowyn Date: Tue, 8 Dec 2009 22:14:19 +0300 Subject: [PATCH 39/59] [8951] Fixed loading `locales_gossip_menu_option`. Signed-off-by: VladimirMangos --- src/game/ObjectMgr.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 117cd0867..d4caed946 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -376,7 +376,7 @@ void ObjectMgr::LoadGossipMenuItemsLocales() for(int i = 1; i < MAX_LOCALE; ++i) { - std::string str = fields[1+2*(i-1)].GetCppString(); + std::string str = fields[2+2*(i-1)].GetCppString(); if(!str.empty()) { int idx = GetOrNewIndexForLocale(LocaleConstant(i)); @@ -388,7 +388,7 @@ void ObjectMgr::LoadGossipMenuItemsLocales() data.OptionText[idx] = str; } } - str = fields[1+2*(i-1)+1].GetCppString(); + str = fields[2+2*(i-1)+1].GetCppString(); if(!str.empty()) { int idx = GetOrNewIndexForLocale(LocaleConstant(i)); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 197a61f90..21b763cb5 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 "8950" + #define REVISION_NR "8951" #endif // __REVISION_NR_H__ From 4ca8b0defca1056a5f461931d537350a2e53d66e Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Tue, 8 Dec 2009 21:47:34 +0100 Subject: [PATCH 40/59] [8952] Use default gossip menu options if no options exist for "top level" menu. Also not close gossip menu in cases where no action_menu_id is set. Signed-off-by: NoFantasy --- src/game/GameObject.h | 10 ++++++++++ src/game/GossipDef.cpp | 1 + src/game/Player.cpp | 18 ++++++++++++++---- src/game/Player.h | 1 + src/shared/revision_nr.h | 2 +- 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/game/GameObject.h b/src/game/GameObject.h index db0a49665..3d2b2a426 100644 --- a/src/game/GameObject.h +++ b/src/game/GameObject.h @@ -489,6 +489,16 @@ struct GameObjectInfo default: return 0; } } + + uint32 GetGossipMenuId() const + { + switch(type) + { + case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.gossipID; + case GAMEOBJECT_TYPE_GOOBER: return goober.gossipID; + default: return 0; + } + } }; // GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp index 5b269da61..a192457e2 100644 --- a/src/game/GossipDef.cpp +++ b/src/game/GossipDef.cpp @@ -103,6 +103,7 @@ void GossipMenu::ClearMenu() { m_gItems.clear(); m_gItemsData.clear(); + m_gMenuId = 0; } PlayerMenu::PlayerMenu( WorldSession *session ) : pSession(session) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 37ac59a8d..2fa5ce06c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -12188,6 +12188,10 @@ void Player::PrepareGossipMenu(WorldObject *pSource, uint32 menuId) GossipMenuItemsMapBounds pMenuItemBounds = sObjectMgr.GetGossipMenuItemsMapBounds(menuId); + // if default menuId and no menu options exist for this, use options from default options + if (pMenuItemBounds.first == pMenuItemBounds.second && menuId == GetDefaultGossipMenuForSource(pSource)) + pMenuItemBounds = sObjectMgr.GetGossipMenuItemsMapBounds(0); + for(GossipMenuItemsMap::const_iterator itr = pMenuItemBounds.first; itr != pMenuItemBounds.second; ++itr) { bool bCanTalk = true; @@ -12405,10 +12409,6 @@ void Player::OnGossipSelect(WorldObject* pSource, uint32 gossipListId, uint32 me PrepareGossipMenu(pSource, pMenuData.m_gAction_menu); SendPreparedGossip(pSource); } - else - { - PlayerTalkClass->CloseGossip(); - } if (pMenuData.m_gAction_poi) PlayerTalkClass->SendPointOfInterest(pMenuData.m_gAction_poi); @@ -12519,6 +12519,16 @@ uint32 Player::GetGossipTextId(uint32 menuId) return textId; } +uint32 Player::GetDefaultGossipMenuForSource(WorldObject *pSource) +{ + if (pSource->GetTypeId() == TYPEID_UNIT) + return ((Creature*)pSource)->GetCreatureInfo()->GossipMenuId; + else if (pSource->GetTypeId() == TYPEID_GAMEOBJECT) + return((GameObject*)pSource)->GetGOInfo()->GetGossipMenuId(); + + return 0; +} + /*********************************************************/ /*** QUEST SYSTEM ***/ /*********************************************************/ diff --git a/src/game/Player.h b/src/game/Player.h index 477701718..501495b29 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1305,6 +1305,7 @@ class MANGOS_DLL_SPEC Player : public Unit uint32 GetGossipTextId(uint32 menuId); uint32 GetGossipTextId(WorldObject *pSource); + uint32 GetDefaultGossipMenuForSource(WorldObject *pSource); /*********************************************************/ /*** QUEST SYSTEM ***/ diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 21b763cb5..bc1c4623d 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 "8951" + #define REVISION_NR "8952" #endif // __REVISION_NR_H__ From 8d519d72196e8751609e06228d54138ceab23ac0 Mon Sep 17 00:00:00 2001 From: Quriq14 Date: Wed, 9 Dec 2009 00:26:59 +0300 Subject: [PATCH 41/59] [8953] Apply spell mutiplier to final damage for health calculation in Spell::EffectHealthLeech. Signed-off-by: VladimirMangos --- src/game/SpellEffects.cpp | 16 ++++++++-------- src/shared/revision_nr.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index c4d47929f..d61815e16 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -2776,21 +2776,21 @@ void Spell::EffectHealthLeech(uint32 i) sLog.outDebug("HealthLeech :%i", damage); + uint32 curHealth = unitTarget->GetHealth(); + damage = m_caster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage ); + if (curHealth < damage) + damage = curHealth; + float multiplier = m_spellInfo->EffectMultipleValue[i]; if (Player *modOwner = m_caster->GetSpellModOwner()) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_MULTIPLE_VALUE, multiplier); - int32 new_damage = int32(damage*multiplier); - uint32 curHealth = unitTarget->GetHealth(); - new_damage = m_caster->SpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, new_damage ); - if (curHealth < new_damage) - new_damage = curHealth; - + uint32 heal = uint32(damage*multiplier); if (m_caster->isAlive()) { - new_damage = m_caster->SpellHealingBonus(m_caster, m_spellInfo, new_damage, HEAL); - m_caster->DealHeal(m_caster, uint32(new_damage), m_spellInfo); + heal = m_caster->SpellHealingBonus(m_caster, m_spellInfo, heal, HEAL); + m_caster->DealHeal(m_caster, heal, m_spellInfo); } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index bc1c4623d..39f52804b 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 "8952" + #define REVISION_NR "8953" #endif // __REVISION_NR_H__ From 08e06584309745bab791c7ed59e01d3d1a263c89 Mon Sep 17 00:00:00 2001 From: LordJZ Date: Wed, 9 Dec 2009 13:55:32 +0300 Subject: [PATCH 42/59] [8954] Implement spells 65495 and 65386. Signed-off-by: VladimirMangos --- src/game/SpellAuras.cpp | 16 ++++++++++++++++ src/shared/revision_nr.h | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 36c53c22f..5649346b8 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3238,6 +3238,22 @@ void Aura::HandleAuraTransform(bool apply, bool Real) } // Murloc costume case 42365: m_target->SetDisplayId(21723); break; + // Honor the Dead + case 65386: + case 65495: + { + switch(m_target->getGender()) + { + case GENDER_MALE: + m_target->SetDisplayId(29203); // Chapman + break; + case GENDER_FEMALE: + case GENDER_NONE: + m_target->SetDisplayId(29204); // Catrina + break; + } + break; + } default: break; } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 39f52804b..ac80e734b 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 "8953" + #define REVISION_NR "8954" #endif // __REVISION_NR_H__ From d3b19f8aa464c16ed766744126d95d3dd72efe14 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Wed, 9 Dec 2009 12:51:35 +0100 Subject: [PATCH 43/59] [8955] Check gossip_menu_option table for GOSSIP_OPTION_NONE and output error if exist Signed-off-by: NoFantasy --- src/game/ObjectMgr.cpp | 3 +++ src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index d4caed946..b94fd4bd2 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -7993,6 +7993,9 @@ void ObjectMgr::LoadGossipMenuItems() gMenuItem.option_icon = GOSSIP_ICON_CHAT; } + if (gMenuItem.option_id == GOSSIP_OPTION_NONE) + sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u use option id GOSSIP_OPTION_NONE. Option will never be used", gMenuItem.menu_id, gMenuItem.id); + if (gMenuItem.option_id >= GOSSIP_OPTION_MAX) sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u has unknown option id %u. Option will not be used", gMenuItem.menu_id, gMenuItem.id, gMenuItem.option_id); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ac80e734b..01d674c21 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 "8954" + #define REVISION_NR "8955" #endif // __REVISION_NR_H__ From 0ec0f34be7c4d6ceb985162dce748e9bc2e01ef7 Mon Sep 17 00:00:00 2001 From: Maxxie Date: Wed, 9 Dec 2009 14:29:37 +0300 Subject: [PATCH 44/59] [8956] Implement aura SPELL_AURA_ALLOW_ONLY_ABILITY. (cherry picked from commit f4d1e05) Signed-off-by: VladimirMangos --- src/game/Spell.cpp | 14 +++++++++++++- src/game/Spell.h | 2 +- src/game/SpellAuras.cpp | 25 ++++++++++++++++++++++++- src/game/SpellAuras.h | 1 + src/shared/revision_nr.h | 2 +- 5 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index f4f6b22ae..58b97bd1f 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -4972,6 +4972,18 @@ SpellCastResult Spell::CheckCasterAuras() const prevented_reason = SPELL_FAILED_SILENCED; else if (unitflag & UNIT_FLAG_PACIFIED && m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_PACIFY) prevented_reason = SPELL_FAILED_PACIFIED; + else if(m_caster->HasAuraType(SPELL_AURA_ALLOW_ONLY_ABILITY)) + { + Unit::AuraList const& casingLimit = m_caster->GetAurasByType(SPELL_AURA_ALLOW_ONLY_ABILITY); + for(Unit::AuraList::const_iterator itr = casingLimit.begin(); itr != casingLimit.end(); ++itr) + { + if(!IsAffectedByAura(*itr)) + { + prevented_reason = SPELL_FAILED_CASTER_AURASTATE; + break; + } + } + } // Attr must make flag drop spell totally immune from all effects if (prevented_reason != SPELL_CAST_OK) @@ -5726,7 +5738,7 @@ void Spell::UpdatePointers() m_targets.Update(m_caster); } -bool Spell::IsAffectedByAura(Aura *aura) +bool Spell::IsAffectedByAura(Aura *aura) const { return sSpellMgr.IsAffectedByMod(m_spellInfo, aura->getAuraSpellMod()); } diff --git a/src/game/Spell.h b/src/game/Spell.h index 0dc845f16..096511463 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -441,7 +441,7 @@ class Spell void UpdatePointers(); // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc) - bool IsAffectedByAura(Aura *aura); + bool IsAffectedByAura(Aura *aura) const; bool CheckTargetCreatureType(Unit* target) const; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 5649346b8..ca1ff0522 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -313,7 +313,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &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::HandleNULL, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask + &Aura::HandleAllowOnlyAbility, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask &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) @@ -7627,3 +7627,26 @@ void Aura::HandleAuraModAllCritChance(bool apply, bool Real) // included in Player::UpdateSpellCritChance calculation ((Player*)m_target)->UpdateAllSpellCritChances(); } + +void Aura::HandleAllowOnlyAbility(bool apply, bool Real) +{ + if(!Real) + return; + + if(apply) + { + m_target->setAttackTimer(BASE_ATTACK,m_duration); + m_target->setAttackTimer(RANGED_ATTACK,m_duration); + m_target->setAttackTimer(OFF_ATTACK,m_duration); + } + else + { + m_target->resetAttackTimer(BASE_ATTACK); + m_target->resetAttackTimer(RANGED_ATTACK); + m_target->resetAttackTimer(OFF_ATTACK); + } + + m_target->UpdateDamagePhysical(BASE_ATTACK); + m_target->UpdateDamagePhysical(RANGED_ATTACK); + m_target->UpdateDamagePhysical(OFF_ATTACK); +} diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 8e573d498..e4a72aaab 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -214,6 +214,7 @@ class MANGOS_DLL_SPEC Aura void HandlePhase(bool Apply, bool Real); void HandleModTargetArmorPct(bool Apply, bool Real); void HandleAuraModAllCritChance(bool Apply, bool Real); + void HandleAllowOnlyAbility(bool Apply, bool Real); virtual ~Aura(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 01d674c21..26fa99044 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 "8955" + #define REVISION_NR "8956" #endif // __REVISION_NR_H__ From d3ee1ecc3d7413da0f7cb29c863bf2a7af8848fa Mon Sep 17 00:00:00 2001 From: Lightguard Date: Wed, 9 Dec 2009 17:59:56 +0300 Subject: [PATCH 45/59] [8957] Implement talent 53754. Signed-off-by: VladimirMangos --- src/game/SpellAuras.cpp | 34 +++++++++++++++++++++++++++++++++- src/shared/revision_nr.h | 2 +- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index ca1ff0522..1eae7fe10 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -5897,6 +5897,7 @@ void Aura::HandleShapeshiftBoosts(bool apply) void Aura::HandleSpellSpecificBoosts(bool apply) { + bool at_remove = false; // if spell must be casted at aura remove uint32 spellId1 = 0; uint32 spellId2 = 0; uint32 spellId3 = 0; @@ -5925,6 +5926,37 @@ void Aura::HandleSpellSpecificBoosts(bool apply) } break; } + case SPELLFAMILY_WARLOCK: + if(!apply) + { + // Fear + if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000040000000000)) + { + Unit* caster = GetCaster(); + if(!caster) + return; + + Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) + { + SpellEntry const* dummyEntry = (*itr)->GetSpellProto(); + // Improved Fear + if (dummyEntry->SpellFamilyName == SPELLFAMILY_WARLOCK && dummyEntry->SpellIconID == 98) + { + at_remove = true; + switch((*itr)->GetModifier()->m_amount) + { + // Rank 1 + case 0: spellId1 = 60946; break; + // Rank 1 + case 1: spellId1 = 60947; break; + } + break; + } + } + } + } + break; case SPELLFAMILY_PRIEST: switch(GetId()) { @@ -6071,7 +6103,7 @@ void Aura::HandleSpellSpecificBoosts(bool apply) // prevent aura deletion, specially in multi-boost case SetInUse(true); - if (apply) + if (apply || at_remove) { if (spellId1) m_target->CastSpell(m_target, spellId1, true, NULL, this); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 26fa99044..06fce51d0 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 "8956" + #define REVISION_NR "8957" #endif // __REVISION_NR_H__ From aad9e12a7098d7b0452a56a4fa063138ff041c40 Mon Sep 17 00:00:00 2001 From: qsa Date: Wed, 9 Dec 2009 21:25:28 +0300 Subject: [PATCH 46/59] [8958] Inlcude 15407 and ranks damage in talent 15286 affect. Signed-off-by: VladimirMangos --- src/game/Spell.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 58b97bd1f..a130bfc02 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -691,8 +691,8 @@ void Spell::prepareDataForTriggerSystem() if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0000800000000060)) m_canTrigger = true; break; - case SPELLFAMILY_PRIEST: // For Penance heal/damage triggers need do it - if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0001800000000000)) + case SPELLFAMILY_PRIEST: // For Penance,Mind Sear,Mind Flay heal/damage triggers need do it + if (m_spellInfo->SpellFamilyFlags & UI64LIT(0x0001800000800000) || (m_spellInfo->SpellFamilyFlags2 & 0x00000040)) m_canTrigger = true; break; case SPELLFAMILY_ROGUE: // For poisons need do it diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 06fce51d0..8905631fa 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 "8957" + #define REVISION_NR "8958" #endif // __REVISION_NR_H__ From 39c16a851062c5d4dc1085d3d4eb64c70f3a4d51 Mon Sep 17 00:00:00 2001 From: laise Date: Thu, 10 Dec 2009 00:45:41 +0300 Subject: [PATCH 47/59] [8959] Implement talent 15318 and ranks and move talent 44745 and ranks code. Signed-off-by: VladimirMangos --- src/game/SpellAuras.cpp | 99 ++++++++++++++++++++++++++++------------ src/shared/revision_nr.h | 2 +- 2 files changed, 72 insertions(+), 29 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 1eae7fe10..715eff697 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -5897,7 +5897,7 @@ void Aura::HandleShapeshiftBoosts(bool apply) void Aura::HandleSpellSpecificBoosts(bool apply) { - bool at_remove = false; // if spell must be casted at aura remove + bool cast_at_remove = false; // if spell must be casted at aura remove uint32 spellId1 = 0; uint32 spellId2 = 0; uint32 spellId3 = 0; @@ -5905,6 +5905,33 @@ void Aura::HandleSpellSpecificBoosts(bool apply) switch(GetSpellProto()->SpellFamilyName) { + case SPELLFAMILY_MAGE: + { + // Ice Barrier + if (m_spellProto->SpellIconID == 32) + { + if (!apply && (m_removeMode == AURA_REMOVE_BY_DISPEL || (m_removeMode == AURA_REMOVE_BY_DEFAULT && !GetModifier()->m_amount))) + { + Unit::AuraList const& dummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) + { + // Shattered Barrier + if ((*itr)->GetSpellProto()->SpellIconID == 2945) + { + cast_at_remove = true; + // first rank have 50% chance + if ((*itr)->GetId() != 44745 || roll_chance_i(50)) + spellId1 = 55080; + break; + } + } + } + else + return; + } + else + return; + } case SPELLFAMILY_WARRIOR: { if(!apply) @@ -5927,10 +5954,10 @@ void Aura::HandleSpellSpecificBoosts(bool apply) break; } case SPELLFAMILY_WARLOCK: - if(!apply) + // Fear + if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000040000000000)) { - // Fear - if (m_spellProto->SpellFamilyFlags & UI64LIT(0x0000040000000000)) + if(!apply) { Unit* caster = GetCaster(); if(!caster) @@ -5943,7 +5970,7 @@ void Aura::HandleSpellSpecificBoosts(bool apply) // Improved Fear if (dummyEntry->SpellFamilyName == SPELLFAMILY_WARLOCK && dummyEntry->SpellIconID == 98) { - at_remove = true; + cast_at_remove = true; switch((*itr)->GetModifier()->m_amount) { // Rank 1 @@ -5955,16 +5982,43 @@ void Aura::HandleSpellSpecificBoosts(bool apply) } } } + else + return; } + else + return; break; case SPELLFAMILY_PRIEST: + { + // Shadow Word: Pain (need visual check fro skip improvement talent) or Vampiric Touch + if (m_spellProto->SpellIconID == 234 && m_spellProto->SpellVisual[0] || m_spellProto->SpellIconID == 2213) + { + if (!apply && m_removeMode == AURA_REMOVE_BY_DISPEL) + { + Unit* caster = GetCaster(); + if(!caster) + return; + + Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) + { + // Shadow Affinity + if ((*itr)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST + && (*itr)->GetSpellProto()->SpellIconID == 178) + { + // custom cast code + int32 basepoints0 = (*itr)->GetModifier()->m_amount * caster->GetCreateMana() / 100; + caster->CastCustomSpell(caster, 64103, &basepoints0, NULL, NULL, true, NULL, this); + return; + } + } + } + else + return; + } + switch(GetId()) { - // Dispersion mana reg and immunity - case 47585: - spellId1 = 60069; // Dispersion - spellId2 = 63230; // Dispersion - break; // Abolish Disease (remove 1 more poison effect with Body and Soul) case 552: { @@ -5991,10 +6045,16 @@ void Aura::HandleSpellSpecificBoosts(bool apply) spellId1 = 64134; // Body and Soul (periodic dispel effect) break; } + // Dispersion mana reg and immunity + case 47585: + spellId1 = 60069; // Dispersion + spellId2 = 63230; // Dispersion + break; default: return; } break; + } case SPELLFAMILY_ROGUE: // Sprint (skip non player casted spells by category) if (GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000000040) && GetSpellProto()->Category == 44) @@ -6103,7 +6163,7 @@ void Aura::HandleSpellSpecificBoosts(bool apply) // prevent aura deletion, specially in multi-boost case SetInUse(true); - if (apply || at_remove) + if (apply || cast_at_remove) { if (spellId1) m_target->CastSpell(m_target, spellId1, true, NULL, this); @@ -6403,23 +6463,6 @@ void Aura::HandleSchoolAbsorb(bool apply, bool Real) } else { - // Ice Barrier (remove effect from Shattered Barrier) - if (m_spellProto->SpellIconID == 32 && m_spellProto->SpellFamilyName == SPELLFAMILY_MAGE) - { - if (!((m_removeMode == AURA_REMOVE_BY_DEFAULT && !m_modifier.m_amount) || m_removeMode == AURA_REMOVE_BY_DISPEL)) - return; - - if (m_target->HasAura(44745,0)) // Shattered Barrier, rank 1 - { - if(roll_chance_i(50)) - m_target->CastSpell(m_target, 55080, true, NULL, this); - } - else if (m_target->HasAura(54787,0)) // Shattered Barrier, rank 2 - { - m_target->CastSpell(m_target, 55080, true, NULL, this); - } - } - if (caster && // Power Word: Shield m_spellProto->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellProto->Mechanic == MECHANIC_SHIELD && diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 8905631fa..59fcd9997 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 "8958" + #define REVISION_NR "8959" #endif // __REVISION_NR_H__ From ba835f1d30da57d27d28365ab8462993b2f7bfed Mon Sep 17 00:00:00 2001 From: balrok Date: Wed, 9 Dec 2009 22:10:37 +0100 Subject: [PATCH 48/59] [8960] fix crash introduced with 8805 or actualy i didn't introduce a new crash there.. the old crash just changed a bit.. after we force the player to logout without valid mapcoords the player wasn't in world anymore and through that Getplayer()->GetMap()->RemoveFromWorld() caused a crash.. i changed now the error handling inside farteleport there.. instead of forcing a logout without saving, i just port him to his homebind which will be much nicer (minor cleanup with the other homebind teleportation.. we don't need to check for the error there.. homebind realy should be a valid coord) --- src/game/MovementHandler.cpp | 20 ++++++++------------ src/shared/revision_nr.h | 2 +- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 5853824ef..e9653c178 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -50,12 +50,12 @@ void WorldSession::HandleMoveWorldportAckOpcode() // possible errors in the coordinate validity check if(!MapManager::IsValidMapCoord(loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation)) { - sLog.outError("WorldSession::HandleMoveWorldportAckOpcode: player got's teleported far to a not valid location. (map:%u, x:%f, y:%f, z:%f) We log him out and don't save him..", loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); - // stop teleportation else we would try this again in the beginning of WorldSession::LogoutPlayer... + sLog.outError("WorldSession::HandleMoveWorldportAckOpcode: player %s (%d) was teleported far to a not valid location. (map:%u, x:%f, y:%f, " + "z:%f) We port him to his homebind instead..", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); + // stop teleportation else we would try this again and again in LogoutPlayer... GetPlayer()->SetSemaphoreTeleportFar(false); - // player don't gets saved - so his coords will stay at the point where - // he was last saved - LogoutPlayer(false); + // and teleport the player to a valid place + GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); return; } @@ -81,14 +81,10 @@ void WorldSession::HandleMoveWorldportAckOpcode() //if player wasn't added to map, reset his map pointer! GetPlayer()->ResetMap(); - sLog.outDebug("WORLD: teleport of player %s (%d) to location %d, %f, %f, %f, %f failed", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation); + sLog.outError("WorldSession::HandleMoveWorldportAckOpcode: player %s (%d) was teleported far but couldn't be added to map. (map:%u, x:%f, y:%f, " + "z:%f) We port him to his homebind instead..", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); // teleport the player home - if(!GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation())) - { - // the player must always be able to teleport home - sLog.outError("WORLD: failed to teleport player %s (%d) to homebind location %d, %f, %f, %f, %f!", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); - assert(false); - } + GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); return; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 59fcd9997..b2aec0f90 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 "8959" + #define REVISION_NR "8960" #endif // __REVISION_NR_H__ From 6f083e0c31250801a8e6d4012121c3e89c5012e0 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 10 Dec 2009 01:05:46 +0300 Subject: [PATCH 49/59] [8961] Prevent crash in Aura::HandleAddModifier for far group member --- src/game/SpellAuras.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 715eff697..ec4dbdb90 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1445,7 +1445,7 @@ void Aura::HandleAddModifier(bool apply, bool Real) if (Group* group = ((Player*)m_target)->GetGroup()) for(GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) if (Player* member = itr->getSource()) - if (member != m_target) + if (member != m_target && member->IsInMap(m_target)) ReapplyAffectedPassiveAuras(member); } void Aura::HandleAddTargetTrigger(bool apply, bool /*Real*/) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b2aec0f90..d6a19fe60 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 "8960" + #define REVISION_NR "8961" #endif // __REVISION_NR_H__ From 4a2dc2438c5a3067b3cb64ee0df4707fc9f56c55 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Thu, 10 Dec 2009 01:53:03 +0100 Subject: [PATCH 50/59] [8962] Check player class instead of just active pet for gossip stable option Signed-off-by: NoFantasy --- src/game/Player.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 2fa5ce06c..aeff05df8 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -12258,7 +12258,7 @@ void Player::PrepareGossipMenu(WorldObject *pSource, uint32 menuId) bCanTalk = false; break; case GOSSIP_OPTION_STABLEPET: - if (!GetPet() || GetPet()->getPetType() != HUNTER_PET) + if (getClass() != CLASS_HUNTER) bCanTalk = false; break; case GOSSIP_OPTION_GOSSIP: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d6a19fe60..3110b0863 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 "8961" + #define REVISION_NR "8962" #endif // __REVISION_NR_H__ From ed7d561597a912eeaa1fe399256145992b13e463 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 10 Dec 2009 12:14:11 +0300 Subject: [PATCH 51/59] [8963] Make bindpoint field private and add required functions for use. --- src/game/CharacterHandler.cpp | 2 +- src/game/Map.cpp | 2 +- src/game/MovementHandler.cpp | 4 ++-- src/game/NPCHandler.cpp | 8 +------- src/game/Player.cpp | 13 +++++++++++++ src/game/Player.h | 15 +++++++++------ src/game/SpellEffects.cpp | 4 ++-- src/game/WorldSession.cpp | 2 +- src/shared/revision_nr.h | 2 +- 9 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 7e2417593..c70492091 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -698,7 +698,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder) if(at) pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation()); else - pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation()); + pCurrChar->TeleportToHomebind(); } sObjectAccessor.AddObject(pCurrChar); diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 2d174e42d..090f394d6 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -2617,7 +2617,7 @@ void InstanceMap::UnloadAll(bool pForce) for(MapRefManager::iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) { Player* plr = itr->getSource(); - plr->TeleportTo(plr->m_homebindMapId, plr->m_homebindX, plr->m_homebindY, plr->m_homebindZ, plr->GetOrientation()); + plr->TeleportToHomebind(); } } diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index e9653c178..4620556cd 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -55,7 +55,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() // stop teleportation else we would try this again and again in LogoutPlayer... GetPlayer()->SetSemaphoreTeleportFar(false); // and teleport the player to a valid place - GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); + GetPlayer()->TeleportToHomebind(); return; } @@ -84,7 +84,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() sLog.outError("WorldSession::HandleMoveWorldportAckOpcode: player %s (%d) was teleported far but couldn't be added to map. (map:%u, x:%f, y:%f, " "z:%f) We port him to his homebind instead..", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.coord_x, loc.coord_y, loc.coord_z); // teleport the player home - GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); + GetPlayer()->TeleportToHomebind(); return; } diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index 6d74f770e..d0451cd0d 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -410,13 +410,7 @@ void WorldSession::SendBindPoint(Creature *npc) uint32 bindspell = 3286; uint32 zone_id = _player->GetZoneId(); - // update sql homebind - CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'", _player->GetMapId(), zone_id, _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetGUIDLow()); - _player->m_homebindMapId = _player->GetMapId(); - _player->m_homebindZoneId = zone_id; - _player->m_homebindX = _player->GetPositionX(); - _player->m_homebindY = _player->GetPositionY(); - _player->m_homebindZ = _player->GetPositionZ(); + _player->SetHomebindToCurrentPos(); // send spell for bind 3286 bind magic npc->CastSpell(_player, bindspell, true); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index aeff05df8..e89b34f9c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -21270,3 +21270,16 @@ bool Player::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) c } return Unit::IsImmunedToSpellEffect(spellInfo, index); } + +void Player::SetHomebindToCurrentPos() +{ + m_homebindMapId = GetMapId(); + m_homebindZoneId = GetZoneId(); + m_homebindX = GetPositionX(); + m_homebindY = GetPositionY(); + m_homebindZ = GetPositionZ(); + + // update sql homebind + CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'", + m_homebindMapId, m_homebindZoneId, m_homebindX, m_homebindY, m_homebindZ, GetGUIDLow()); +} \ No newline at end of file diff --git a/src/game/Player.h b/src/game/Player.h index 501495b29..4aa32bcb5 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2165,13 +2165,9 @@ class MANGOS_DLL_SPEC Player : public Unit float m_recallO; void SaveRecallPosition(); - // Homebind coordinates - uint32 m_homebindMapId; - uint16 m_homebindZoneId; - float m_homebindX; - float m_homebindY; - float m_homebindZ; + void SetHomebindToCurrentPos(); void RelocateToHomebind() { SetLocationMapId(m_homebindMapId); Relocate(m_homebindX,m_homebindY,m_homebindZ); } + void TeleportToHomebind(uint32 options = 0) { TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation(),options); } // currently visible objects at player client typedef std::set ClientGUIDs; @@ -2530,6 +2526,13 @@ class MANGOS_DLL_SPEC Player : public Unit GridReference m_gridRef; MapReference m_mapRef; + // Homebind coordinates + uint32 m_homebindMapId; + uint16 m_homebindZoneId; + float m_homebindX; + float m_homebindY; + float m_homebindZ; + uint32 m_lastFallTime; float m_lastFallZ; diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index d61815e16..c899656aa 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -2340,7 +2340,7 @@ void Spell::EffectTeleportUnits(uint32 i) if (unitTarget->GetTypeId() != TYPEID_PLAYER) return; - ((Player*)unitTarget)->TeleportTo(((Player*)unitTarget)->m_homebindMapId,((Player*)unitTarget)->m_homebindX,((Player*)unitTarget)->m_homebindY,((Player*)unitTarget)->m_homebindZ,unitTarget->GetOrientation(),unitTarget==m_caster ? TELE_TO_SPELL : 0); + ((Player*)unitTarget)->TeleportToHomebind(unitTarget==m_caster ? TELE_TO_SPELL : 0); return; } case TARGET_AREAEFFECT_INSTANT: // in all cases first TARGET_TABLE_X_Y_Z_COORDINATES @@ -5802,7 +5802,7 @@ void Spell::EffectStuck(uint32 /*i*/) return; // homebind location is loaded always - pTarget->TeleportTo(pTarget->m_homebindMapId,pTarget->m_homebindX,pTarget->m_homebindY,pTarget->m_homebindZ,pTarget->GetOrientation(), (unitTarget==m_caster ? TELE_TO_SPELL : 0)); + pTarget->TeleportToHomebind(unitTarget==m_caster ? TELE_TO_SPELL : 0); // Stuck spell trigger Hearthstone cooldown SpellEntry const *spellInfo = sSpellStore.LookupEntry(8690); diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 3ee5a7faa..a9d0e1cb2 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -355,7 +355,7 @@ void WorldSession::LogoutPlayer(bool Save) ///- Teleport to home if the player is in an invalid instance if(!_player->m_InstanceValid && !_player->isGameMaster()) { - _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation()); + _player->TeleportToHomebind(); //this is a bad place to call for far teleport because we need player to be in world for successful logout //maybe we should implement delayed far teleport logout? } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 3110b0863..4561b4e59 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 "8962" + #define REVISION_NR "8963" #endif // __REVISION_NR_H__ From b6cd243cefa6870da2df7887f68c91d8695fc5f6 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 10 Dec 2009 12:30:26 +0300 Subject: [PATCH 52/59] [8964] Return in TeleportToHomebind return result from TeleportTo --- src/game/Player.h | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Player.h b/src/game/Player.h index 4aa32bcb5..e1b4a271e 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -2167,7 +2167,7 @@ class MANGOS_DLL_SPEC Player : public Unit void SetHomebindToCurrentPos(); void RelocateToHomebind() { SetLocationMapId(m_homebindMapId); Relocate(m_homebindX,m_homebindY,m_homebindZ); } - void TeleportToHomebind(uint32 options = 0) { TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation(),options); } + bool TeleportToHomebind(uint32 options = 0) { return TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation(),options); } // currently visible objects at player client typedef std::set ClientGUIDs; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4561b4e59..355bad342 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 "8963" + #define REVISION_NR "8964" #endif // __REVISION_NR_H__ From a2bb6555016a90fc57ea9bd8a58d4f133b276521 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 10 Dec 2009 19:19:05 +0300 Subject: [PATCH 53/59] [8965] Implement `quit` command for close RA connection. World only in RA comandline. --- sql/mangos.sql | 4 +++- sql/updates/8965_01_mangos_mangos_string.sql | 6 ++++++ sql/updates/8965_02_mangos_command.sql | 6 ++++++ sql/updates/Makefile.am | 4 ++++ src/game/Chat.cpp | 1 + src/game/Chat.h | 1 + src/game/Language.h | 3 ++- src/game/MovementHandler.cpp | 1 - src/mangosd/CliRunnable.cpp | 8 ++++++++ src/mangosd/RASocket.cpp | 5 ++++- src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 12 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 sql/updates/8965_01_mangos_mangos_string.sql create mode 100644 sql/updates/8965_02_mangos_command.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 125747865..3fa594ec1 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -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_8950_01_mangos_spell_proc_event` bit(1) default NULL + `required_8965_02_mangos_command` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -705,6 +705,7 @@ INSERT INTO `command` VALUES ('quest add',3,'Syntax: .quest add #quest_id\r\n\r\nAdd to character quest log quest #quest_id. Quest started from item can\'t be added by this command but correct .additem call provided in command output.'), ('quest complete',3,'Syntax: .quest complete #questid\r\nMark all quest objectives as completed for target character active quest. After this target character can go and get quest reward.'), ('quest remove',3,'Syntax: .quest remove #quest_id\r\n\r\nSet quest #quest_id state to not completed and not active (and remove from active quest list) for selected player.'), +('quit',4,'Syntax: quit\r\n\r\nClose RA connection. Command must be typed fully (quit).'), ('recall',1,'Syntax: .recall [$playername]\r\n\r\nTeleport $playername or selected player to the place where he has been before last use of a teleportation command. If no $playername is entered and no player is selected, it will teleport you.'), ('reload all',3,'Syntax: .reload all\r\n\r\nReload all tables with reload support added and that can be _safe_ reloaded.'), ('reload all_area',3,'Syntax: .reload all_area\r\n\r\nReload all `areatrigger_*` tables if reload support added for this table and this table can be _safe_ reloaded.'), @@ -3555,6 +3556,7 @@ INSERT INTO `mangos_string` VALUES (1012,'===========================================================================',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1013,'|%15s| %20s | %15s |%4d| %9d |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1014,'No online players.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(1015,'Used not fully typed quit command, need type it fully (quit), or command used not in RA command line.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1100,'Account %s (Id: %u) have up to %u expansion allowed now.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1101,'Message of the day changed to:\r\n%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1102,'Message sent to %s: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), diff --git a/sql/updates/8965_01_mangos_mangos_string.sql b/sql/updates/8965_01_mangos_mangos_string.sql new file mode 100644 index 000000000..19937c686 --- /dev/null +++ b/sql/updates/8965_01_mangos_mangos_string.sql @@ -0,0 +1,6 @@ +ALTER TABLE db_version CHANGE COLUMN required_8950_01_mangos_spell_proc_event required_8965_01_mangos_mangos_string bit; + +DELETE FROM mangos_string WHERE entry in (1015); + +INSERT INTO mangos_string VALUES + (1015,'Used not fully typed quit command, need type it fully (quit), or command used not in RA command line.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); diff --git a/sql/updates/8965_02_mangos_command.sql b/sql/updates/8965_02_mangos_command.sql new file mode 100644 index 000000000..4a143e4ee --- /dev/null +++ b/sql/updates/8965_02_mangos_command.sql @@ -0,0 +1,6 @@ +ALTER TABLE db_version CHANGE COLUMN required_8965_01_mangos_mangos_string required_8965_02_mangos_command bit; + +DELETE FROM command where name IN ('quit'); + +INSERT INTO `command` VALUES +('quit',4,'Syntax: quit\r\n\r\nClose RA connection. Command must be typed fully (quit).'); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 101077bde..f4ea2d3db 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -198,6 +198,8 @@ pkgdata_DATA = \ 8943_01_mangos_spell_chain.sql \ 8946_01_mangos_spell_proc_event.sql \ 8950_01_mangos_spell_proc_event.sql \ + 8965_01_mangos_mangos_string.sql \ + 8965_02_mangos_command.sql \ README ## Additional files to include when running 'make dist' @@ -376,4 +378,6 @@ EXTRA_DIST = \ 8943_01_mangos_spell_chain.sql \ 8946_01_mangos_spell_proc_event.sql \ 8950_01_mangos_spell_proc_event.sql \ + 8965_01_mangos_mangos_string.sql \ + 8965_02_mangos_command.sql \ README diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index b49aab964..f510fc0e4 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -667,6 +667,7 @@ ChatCommand * ChatHandler::getCommandTable() { "flusharenapoints",SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL }, { "repairitems", SEC_GAMEMASTER, true, &ChatHandler::HandleRepairitemsCommand, "", NULL }, { "waterwalk", SEC_GAMEMASTER, false, &ChatHandler::HandleWaterwalkCommand, "", NULL }, + { "quit", SEC_CONSOLE, true, &ChatHandler::HandleQuitCommand, "", NULL }, { NULL, 0, false, NULL, "", NULL } }; diff --git a/src/game/Chat.h b/src/game/Chat.h index 665696a10..84231ac11 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -498,6 +498,7 @@ class ChatHandler bool HandleFlushArenaPointsCommand(const char *args); bool HandleRepairitemsCommand(const char* args); bool HandleWaterwalkCommand(const char* args); + bool HandleQuitCommand(const char* args); //! Development Commands bool HandleSaveAllCommand(const char* args); diff --git a/src/game/Language.h b/src/game/Language.h index 9f9f7afad..986f28872 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -780,7 +780,8 @@ enum MangosStrings LANG_ACCOUNT_LIST_BAR = 1012, LANG_ACCOUNT_LIST_LINE = 1013, LANG_ACCOUNT_LIST_EMPTY = 1014, - // Room for more level 4 1015-1099 not used + LANG_QUIT_WRONG_USE_ERROR = 1015, + // Room for more level 4 1016-1099 not used // Level 3 (continue) LANG_ACCOUNT_SETADDON = 1100, diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 4620556cd..76d6545be 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -238,7 +238,6 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) ReadMovementInfo(recv_data, &movementInfo); /*----------------*/ - recv_data.rpos(recv_data.wpos()); // prevent warnings spam if (!MaNGOS::IsValidMapCoord(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o)) { recv_data.rpos(recv_data.wpos()); // prevent warnings spam diff --git a/src/mangosd/CliRunnable.cpp b/src/mangosd/CliRunnable.cpp index d84bd79cf..a97fd7fb6 100644 --- a/src/mangosd/CliRunnable.cpp +++ b/src/mangosd/CliRunnable.cpp @@ -152,6 +152,14 @@ bool ChatHandler::HandleCharacterDeleteCommand(const char* args) return true; } +/// Close RA connection +bool ChatHandler::HandleQuitCommand(const char* /*args*/) +{ + // processed in RASocket + SendSysMessage(LANG_QUIT_WRONG_USE_ERROR); + return true; +} + /// Exit the realm bool ChatHandler::HandleServerExitCommand(const char* /*args*/) { diff --git a/src/mangosd/RASocket.cpp b/src/mangosd/RASocket.cpp index db03c6ae9..cceff509b 100644 --- a/src/mangosd/RASocket.cpp +++ b/src/mangosd/RASocket.cpp @@ -225,7 +225,10 @@ void RASocket::OnRead() if (strlen(buff)) { sLog.outRALog("Got '%s' cmd.\n",buff); - sWorld.QueueCliCommand(&RASocket::zprint , buff); + if (strncmp(buff,"quit",4)==0) + SetCloseAndDelete(); + else + sWorld.QueueCliCommand(&RASocket::zprint, buff); } else Sendf("mangos>"); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 355bad342..5b9d1f85a 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 "8964" + #define REVISION_NR "8965" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 7dfbed989..21a7eef2a 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_8874_01_characters_character_skills" - #define REVISION_DB_MANGOS "required_8950_01_mangos_spell_proc_event" + #define REVISION_DB_MANGOS "required_8965_02_mangos_command" #define REVISION_DB_REALMD "required_8728_01_realmd_account" #endif // __REVISION_SQL_H__ From f5895596c0d801db4be0e309330146da068fdbd2 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 11 Dec 2009 02:02:26 +0300 Subject: [PATCH 54/59] [8966] Restore full stack bufs from talent 51528 and ranks using unique aura type. --- src/game/SpellAuraDefines.h | 2 +- src/game/SpellAuras.cpp | 2 +- src/game/Unit.cpp | 8 ++++++++ src/shared/revision_nr.h | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 9ab461284..3407999e6 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -314,7 +314,7 @@ enum AuraType SPELL_AURA_MOD_IGNORE_DAMAGE_REDUCTION_SCHOOL = 269, SPELL_AURA_MOD_IGNORE_TARGET_RESIST = 270, // Possibly need swap vs 195 aura used only in 1 spell Chaos Bolt Passive SPELL_AURA_MOD_DAMAGE_FROM_CASTER = 271, - SPELL_AURA_272 = 272, + SPELL_AURA_MAELSTROM_WEAPON = 272, SPELL_AURA_X_RAY = 273, SPELL_AURA_274 = 274, SPELL_AURA_MOD_IGNORE_SHAPESHIFT = 275, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index ec4dbdb90..4b64326f4 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -322,7 +322,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNoImmediateEffect, //269 SPELL_AURA_MOD_IGNORE_DAMAGE_REDUCTION_SCHOOL implemented in Unit::CalcNotIgnoreDamageRedunction &Aura::HandleUnused, //270 SPELL_AURA_MOD_IGNORE_TARGET_RESIST (unused in 3.2.2a) &Aura::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus - &Aura::HandleNULL, //272 reduce spell cast time? + &Aura::HandleNoImmediateEffect, //272 SPELL_AURA_MAELSTROM_WEAPON (unclear use for aura, it used in (3.2.2a...3.3.0) in single spell 53817 that spellmode stacked and charged spell expected to be drop as stack &Aura::HandleNoImmediateEffect, //273 SPELL_AURA_X_RAY (client side implementation) &Aura::HandleNULL, //274 proc free shot? &Aura::HandleNoImmediateEffect, //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index c734dfa02..76dd4b20f 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -11727,6 +11727,7 @@ bool InitTriggerAuraData() isTriggerAura[SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE] = true; isTriggerAura[SPELL_AURA_MOD_DAMAGE_FROM_CASTER] = true; isTriggerAura[SPELL_AURA_MOD_SPELL_CRIT_CHANCE] = true; + isTriggerAura[SPELL_AURA_MAELSTROM_WEAPON] = true; isNonTriggerAura[SPELL_AURA_MOD_POWER_REGEN]=true; isNonTriggerAura[SPELL_AURA_REDUCE_PUSHBACK]=true; @@ -12017,6 +12018,13 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag continue; } break; + case SPELL_AURA_MAELSTROM_WEAPON: + sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s maelstrom aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId()); + + // remove all stack; + RemoveSpellsCausingAura(SPELL_AURA_MAELSTROM_WEAPON); + triggeredByAura->SetInUse(false); // this safe, aura locked + continue; // avoid re-remove attempts default: // nothing do, just charges counter break; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 5b9d1f85a..751323b36 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 "8965" + #define REVISION_NR "8966" #endif // __REVISION_NR_H__ From 25688fc8ebbc6dd17c9199e0b7ea019837df556c Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Fri, 11 Dec 2009 02:32:36 +0300 Subject: [PATCH 55/59] [8967] Fixed division by zero in Unit::CalcAbsorbResist. This also fix spell 31662 work. Signed-off-by: VladimirMangos --- src/game/Unit.cpp | 20 +++++++++++--------- src/shared/revision_nr.h | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 76dd4b20f..b5112b6df 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1994,13 +1994,18 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe else currentAbsorb = RemainingDamage; - float manaMultiplier = (*i)->GetSpellProto()->EffectMultipleValue[(*i)->GetEffIndex()]; - if(Player *modOwner = pVictim->GetSpellModOwner()) - modOwner->ApplySpellMod((*i)->GetId(), SPELLMOD_MULTIPLE_VALUE, manaMultiplier); + if (float manaMultiplier = (*i)->GetSpellProto()->EffectMultipleValue[(*i)->GetEffIndex()]) + { + if(Player *modOwner = pVictim->GetSpellModOwner()) + modOwner->ApplySpellMod((*i)->GetId(), SPELLMOD_MULTIPLE_VALUE, manaMultiplier); - int32 maxAbsorb = int32(pVictim->GetPower(POWER_MANA) / manaMultiplier); - if (currentAbsorb > maxAbsorb) - currentAbsorb = maxAbsorb; + int32 maxAbsorb = int32(pVictim->GetPower(POWER_MANA) / manaMultiplier); + if (currentAbsorb > maxAbsorb) + currentAbsorb = maxAbsorb; + + int32 manaReduction = int32(currentAbsorb * manaMultiplier); + pVictim->ApplyPowerMod(POWER_MANA, manaReduction, false); + } (*i)->GetModifier()->m_amount -= currentAbsorb; if((*i)->GetModifier()->m_amount <= 0) @@ -2009,9 +2014,6 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe next = vManaShield.begin(); } - int32 manaReduction = int32(currentAbsorb * manaMultiplier); - pVictim->ApplyPowerMod(POWER_MANA, manaReduction, false); - RemainingDamage -= currentAbsorb; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 751323b36..1de986d24 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 "8966" + #define REVISION_NR "8967" #endif // __REVISION_NR_H__ From f0e7f01a7b13b3403b10c7cdbb4f2637a83eda9b Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Fri, 11 Dec 2009 11:07:34 +0100 Subject: [PATCH 56/59] [8968] Implement gossip menu options for GameObject Signed-off-by: NoFantasy --- src/game/NPCHandler.cpp | 45 +++++++++++++++++++++++++++------------- src/game/Player.cpp | 15 +++++++------- src/game/Player.h | 2 +- src/shared/revision_nr.h | 2 +- 4 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index d0451cd0d..80a049303 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -300,27 +300,44 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data ) sLog.outBasic("string read: %s", code.c_str()); } - Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); - - if (!pCreature) - { - sLog.outDebug( "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); - return; - } - // remove fake death if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - if (!code.empty()) + // TODO: determine if scriptCall is needed for GO and also if scriptCall can be same as current, with modified argument WorldObject* + + if (IS_CREATURE_GUID(guid)) { - if (!Script->GossipSelectWithCode(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId), code.c_str())) - _player->OnGossipSelect(pCreature, gossipListId, menuId); + Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); + + if (!pCreature) + { + sLog.outDebug("WORLD: HandleGossipSelectOptionOpcode - Creature (GUID: %u) not found or you can't interact with it.", uint32(GUID_LOPART(guid))); + return; + } + + if (!code.empty()) + { + if (!Script->GossipSelectWithCode(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId), code.c_str())) + _player->OnGossipSelect(pCreature, gossipListId, menuId); + } + else + { + if (!Script->GossipSelect(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId))) + _player->OnGossipSelect(pCreature, gossipListId, menuId); + } } - else + else if (IS_GAMEOBJECT_GUID(guid)) { - if (!Script->GossipSelect(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId))) - _player->OnGossipSelect(pCreature, gossipListId, menuId); + GameObject *pGo = GetPlayer()->GetGameObjectIfCanInteractWith(guid); + + if (!pGo) + { + sLog.outDebug("WORLD: HandleGossipSelectOptionOpcode - GameObject (GUID: %u) not found or you can't interact with it.", uint32(GUID_LOPART(guid))); + return; + } + + _player->OnGossipSelect(pGo, gossipListId, menuId); } } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index e89b34f9c..61b06b0ea 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2117,14 +2117,14 @@ Creature* Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask) return unit; } -GameObject* Player::GetGameObjectIfCanInteractWith(uint64 guid, GameobjectTypes type) const +GameObject* Player::GetGameObjectIfCanInteractWith(uint64 guid, uint32 gameobject_type) const { - if(GameObject *go = GetMap()->GetGameObject(guid)) + if (GameObject *go = GetMap()->GetGameObject(guid)) { - if(go->GetGoType() == type) + if (uint32(go->GetGoType()) == gameobject_type || gameobject_type == MAX_GAMEOBJECT_TYPE) { float maxdist; - switch(type) + switch(go->GetGoType()) { // TODO: find out how the client calculates the maximal usage distance to spellless working // gameobjects like guildbanks and mailboxes - 10.0 is a just an abitrary choosen number @@ -2140,10 +2140,10 @@ GameObject* Player::GetGameObjectIfCanInteractWith(uint64 guid, GameobjectTypes break; } - if (go->IsWithinDistInMap(this, maxdist)) + if (go->IsWithinDistInMap(this, maxdist) && go->isSpawned()) return go; - sLog.outError("IsGameObjectOfTypeInRange: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal 10 is allowed)", go->GetGOInfo()->name, + sLog.outError("GetGameObjectIfCanInteractWith: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal 10 is allowed)", go->GetGOInfo()->name, go->GetGUIDLow(), GetName(), GetGUIDLow(), go->GetDistance(this)); } } @@ -12287,11 +12287,10 @@ void Player::PrepareGossipMenu(WorldObject *pSource, uint32 menuId) bCanTalk = false; break; case GOSSIP_OPTION_GOSSIP: - if (pGo->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER || pGo->GetGoType() != GAMEOBJECT_TYPE_GOOBER) + if (pGo->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER && pGo->GetGoType() != GAMEOBJECT_TYPE_GOOBER) bCanTalk = false; break; default: - sLog.outErrorDb("GameObject entry %u are using invalid gossip option %u for menu %u", pGo->GetEntry(), itr->second.option_id, itr->second.menu_id); bCanTalk = false; break; } diff --git a/src/game/Player.h b/src/game/Player.h index e1b4a271e..a9a00479f 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1066,7 +1066,7 @@ class MANGOS_DLL_SPEC Player : public Unit void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time); Creature* GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask); - GameObject* GetGameObjectIfCanInteractWith(uint64 guid, GameobjectTypes type) const; + GameObject* GetGameObjectIfCanInteractWith(uint64 guid, uint32 gameobject_type = MAX_GAMEOBJECT_TYPE) const; void UpdateVisibilityForPlayer(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 1de986d24..9cf4f2bc5 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 "8967" + #define REVISION_NR "8968" #endif // __REVISION_NR_H__ From 5e2c6e6b861bd1c559bf2579b83bf4893d68bec1 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 11 Dec 2009 15:10:28 +0300 Subject: [PATCH 57/59] [8969] Ignore in stacking check pure dummy spells. One more hacks to SpellMgr::IsNoStackSpellDueToSpell This fix for example 53601 with 20911 stacking. --- src/game/SpellMgr.cpp | 9 +++++++++ src/shared/revision_nr.h | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 15b16d51c..363385e12 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1722,13 +1722,22 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons if (spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName) return false; + bool dummy_only = true; for (int i = 0; i < 3; ++i) + { if (spellInfo_1->Effect[i] != spellInfo_2->Effect[i] || spellInfo_1->EffectItemType[i] != spellInfo_2->EffectItemType[i] || spellInfo_1->EffectMiscValue[i] != spellInfo_2->EffectMiscValue[i] || spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i]) return false; + // ignore dummy only spells + if(spellInfo_1->Effect[i] && spellInfo_1->Effect[i] != SPELL_EFFECT_DUMMY && spellInfo_1->EffectApplyAuraName[i] != SPELL_AURA_DUMMY) + dummy_only = false; + } + if (dummy_only) + return false; + return true; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9cf4f2bc5..c6bac02f9 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 "8968" + #define REVISION_NR "8969" #endif // __REVISION_NR_H__ From fb6712f3a34f7e6155356024894642f60af602e7 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Fri, 11 Dec 2009 18:37:06 +0100 Subject: [PATCH 58/59] [8970] Implement CONDITION_AREA_FLAG Value1 is for "include flag", Value2 for "not include flag" Signed-off-by: NoFantasy --- src/game/ObjectMgr.cpp | 18 ++++++++++++++++++ src/game/ObjectMgr.h | 3 ++- src/shared/revision_nr.h | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index b94fd4bd2..582cf9b40 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -7244,6 +7244,15 @@ bool PlayerCondition::Meets(Player const * player) const return !player->HasAura(value1, value2); case CONDITION_ACTIVE_EVENT: return sGameEventMgr.IsActiveEvent(value1); + case CONDITION_AREA_FLAG: + { + if (AreaTableEntry const *pAreaEntry = GetAreaEntryByAreaID(player->GetAreaId())) + { + if ((!value1 || (pAreaEntry->flags & value1)) && (!value2 || !(pAreaEntry->flags & value2))) + return true; + } + return false; + } default: return false; } @@ -7388,6 +7397,15 @@ bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 val } break; } + case CONDITION_AREA_FLAG: + { + if (!value1 && !value2) + { + sLog.outErrorDb("Area flag condition has both values like 0, skipped"); + return false; + } + break; + } case CONDITION_NONE: break; } diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 931a853c1..83f268b9d 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -284,9 +284,10 @@ enum ConditionType CONDITION_AD_COMMISSION_AURA = 10, // 0 0, for condition true while one from AD commission aura active CONDITION_NO_AURA = 11, // spell_id effindex CONDITION_ACTIVE_EVENT = 12, // event_id + CONDITION_AREA_FLAG = 13 // area_flag area_flag_not }; -#define MAX_CONDITION 13 // maximum value in ConditionType enum +#define MAX_CONDITION 14 // maximum value in ConditionType enum struct PlayerCondition { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c6bac02f9..7f2acbc18 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 "8969" + #define REVISION_NR "8970" #endif // __REVISION_NR_H__ From fe12e08f082e2c7aaed1a905e364094eae76c803 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Fri, 11 Dec 2009 19:42:23 +0100 Subject: [PATCH 59/59] [8971] Correct mangos.sql after changes to creature_template in rev 8923 Signed-off-by: NoFantasy --- sql/mangos.sql | 3 ++- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/mangos.sql b/sql/mangos.sql index 3fa594ec1..c7ce487fc 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -1079,6 +1079,7 @@ CREATE TABLE `creature_template` ( `name` char(100) NOT NULL default '0', `subname` char(100) default NULL, `IconName` char(100) default NULL, + `gossip_menu_id` mediumint(8) unsigned NOT NULL default '0', `minlevel` tinyint(3) unsigned NOT NULL default '1', `maxlevel` tinyint(3) unsigned NOT NULL default '1', `minhealth` int(10) unsigned NOT NULL default '0', @@ -1156,7 +1157,7 @@ CREATE TABLE `creature_template` ( LOCK TABLES `creature_template` WRITE; /*!40000 ALTER TABLE `creature_template` DISABLE KEYS */; INSERT INTO `creature_template` VALUES -(1,0,0,0,0,0,10045,0,10045,0,'Waypoint(Only GM can see it)','Visual',NULL,1,1,64,64,0,0,0,35,35,0,0.91,1,0,14,15,0,100,1,2000,2200,8,4096,0,0,0,0,0,0,1.76,2.42,100,8,5242886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,3,1.0,1.0,0,0,0,0,0,0,0,0,1,0,0,0x82,''); +(1,0,0,0,0,0,10045,0,10045,0,'Waypoint(Only GM can see it)','Visual',NULL,0,1,1,64,64,0,0,0,35,35,0,0.91,1,0,14,15,0,100,1,2000,2200,8,4096,0,0,0,0,0,0,1.76,2.42,100,8,5242886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'',0,3,1.0,1.0,0,0,0,0,0,0,0,0,1,0,0,0x82,''); /*!40000 ALTER TABLE `creature_template` ENABLE KEYS */; UNLOCK TABLES; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7f2acbc18..063790663 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 "8970" + #define REVISION_NR "8971" #endif // __REVISION_NR_H__