aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp1
-rw-r--r--src/server/game/Chat/Chat.cpp18
-rw-r--r--src/server/game/Chat/Chat.h2
-rw-r--r--src/server/game/DataStores/DBCStores.cpp2
-rw-r--r--src/server/game/DataStores/DBCStores.h1
-rw-r--r--src/server/game/DataStores/DBCStructure.h31
-rw-r--r--src/server/game/DataStores/DBCfmt.h7
-rw-r--r--src/server/game/Entities/Player/Player.cpp2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp32
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp2
-rw-r--r--src/server/game/Handlers/NPCHandler.h1
-rw-r--r--src/server/game/Scripting/ScriptMgr.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp2
-rw-r--r--src/server/game/Spells/SpellMgr.cpp61
-rw-r--r--src/server/game/Spells/SpellMgr.h2
-rw-r--r--src/server/scripts/Commands/cs_gobject.cpp11
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp4
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp10
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp4
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp6
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp84
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp194
-rw-r--r--src/server/scripts/Spells/spell_paladin.cpp50
-rw-r--r--src/server/scripts/Spells/spell_quest.cpp41
-rw-r--r--src/tools/mmaps_generator/MapBuilder.cpp4
-rw-r--r--src/tools/mmaps_generator/MapBuilder.h2
-rw-r--r--src/tools/mmaps_generator/PathGenerator.cpp2
27 files changed, 400 insertions, 178 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 3cfa79ed8d0..b82c77f029d 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -1147,6 +1147,7 @@ void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type,
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA: // This also behaves like ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA
+ case ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN:
SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
// std case: increment at miscValue1
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index 91f62c1a697..0686272f191 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -800,6 +800,24 @@ Creature* ChatHandler::getSelectedCreature()
return ObjectAccessor::GetCreatureOrPetOrVehicle(*m_session->GetPlayer(), m_session->GetPlayer()->GetTarget());
}
+Player* ChatHandler::getSelectedPlayerOrSelf()
+{
+ if (!m_session)
+ return NULL;
+
+ uint64 selected = m_session->GetPlayer()->GetTarget();
+ if (!selected)
+ return m_session->GetPlayer();
+
+ // first try with selected target
+ Player* targetPlayer = ObjectAccessor::FindPlayer(selected);
+ // if the target is not a player, then return self
+ if (!targetPlayer)
+ targetPlayer = m_session->GetPlayer();
+
+ return targetPlayer;
+}
+
char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** something1)
{
// skip empty
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index eb4c89bb8ea..5c541d07b5a 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -98,6 +98,8 @@ class ChatHandler
Creature* getSelectedCreature();
Unit* getSelectedUnit();
WorldObject* getSelectedObject();
+ // Returns either the selected player or self if there is no selected player
+ Player* getSelectedPlayerOrSelf();
char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL);
char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL);
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 5b96f8b8271..9a3e5dcf0fd 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -76,6 +76,7 @@ DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt);
DBCStorage <ChrPowerTypesEntry> sChrPowerTypesStore(ChrClassesXPowerTypesfmt);
DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequencesEntryfmt);
DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt);
+DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore(CreatureDisplayInfoExtrafmt);
DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt);
DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore(CreatureModelDatafmt);
DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt);
@@ -376,6 +377,7 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoExtraStore, dbcPath, "CreatureDisplayInfoExtra.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureModelDataStore, dbcPath, "CreatureModelData.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc");//15595
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index ca91f1da1f2..af7007a17ae 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -103,6 +103,7 @@ extern DBCStorage <ChrRacesEntry> sChrRacesStore;
extern DBCStorage <ChrPowerTypesEntry> sChrPowerTypesStore;
extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore;
extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
+extern DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore;
extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
extern DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore;
extern DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore;
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index 6a548615c3b..1e5c2093b53 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -726,7 +726,7 @@ struct ChrClassesEntry
struct ChrRacesEntry
{
uint32 RaceID; // 0
- // 1 unused
+ uint32 Flags; // 1
uint32 FactionID; // 2 facton template id
// 3 unused
uint32 model_m; // 4
@@ -780,7 +780,7 @@ struct CreatureDisplayInfoEntry
uint32 Displayid; // 0 m_ID
uint32 ModelId; // 1 m_modelID
// 2 m_soundID
- // 3 m_extendedDisplayInfoID
+ uint32 ExtraId; // 3 m_extendedDisplayInfoID
float scale; // 4 m_creatureModelScale
// 5 m_creatureModelAlpha
// 6-8 m_textureVariation[3]
@@ -794,6 +794,31 @@ struct CreatureDisplayInfoEntry
// 16
};
+struct CreatureDisplayInfoExtraEntry
+{
+ //uint32 Id; // 0
+ uint32 Race; // 1
+ uint32 Gender; // 2
+ //uint32 SkinColor; // 3
+ //uint32 FaceType; // 4
+ //uint32 HairType; // 5
+ //uint32 HairStyle; // 6
+ //uint32 FacialHair; // 7
+ //uint32 HelmDisplayId; // 8
+ //uint32 ShoulderDisplayId; // 9
+ //uint32 ShirtDisplayId; // 10
+ //uint32 ChestDisplayId; // 11
+ //uint32 BeltDisplayId; // 12
+ //uint32 LegsDisplayId; // 13
+ //uint32 BootsDisplayId; // 14
+ //uint32 WristDisplayId; // 15
+ //uint32 GlovesDisplayId; // 16
+ //uint32 TabardDisplayId; // 17
+ //uint32 CloakDisplayId; // 18
+ //uint32 CanEquip; // 19
+ //char const* Texture; // 20
+};
+
struct CreatureFamilyEntry
{
uint32 ID; // 0 m_ID
@@ -812,7 +837,7 @@ struct CreatureFamilyEntry
struct CreatureModelDataEntry
{
uint32 Id;
- //uint32 Flags;
+ uint32 Flags;
//char* ModelPath
//uint32 Unk1;
//float Scale; // Used in calculation of unit collision data
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index 4b7f59bf380..41dc6afd4f7 100644
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -40,11 +40,12 @@ char const CharStartOutfitEntryfmt[] = "dbbbXiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxx
char const CharTitlesEntryfmt[] = "nxssix";
char const ChatChannelsEntryfmt[] = "nixsx";
char const ChrClassesEntryfmt[] = "nixsxxxixiiiii";
-char const ChrRacesEntryfmt[] = "nxixiixixxxxixsxxxxxixxx";
+char const ChrRacesEntryfmt[] = "niixiixixxxxixsxxxxxixxx";
char const ChrClassesXPowerTypesfmt[] = "nii";
char const CinematicSequencesEntryfmt[] = "nxxxxxxxxx";
-char const CreatureDisplayInfofmt[] = "nixxfxxxxxxxxxxxx";
-char const CreatureModelDatafmt[] = "nxxxxxxxxxxxxxffxxxxxxxxxxxxxxx";
+char const CreatureDisplayInfofmt[] = "nixifxxxxxxxxxxxx";
+char const CreatureDisplayInfoExtrafmt[] = "diixxxxxxxxxxxxxxxxxx";
+char const CreatureModelDatafmt[] = "nixxxxxxxxxxxxffxxxxxxxxxxxxxxx";
char const CreatureFamilyfmt[] = "nfifiiiiixsx";
char const CreatureSpellDatafmt[] = "niiiixxxx";
char const CreatureTypefmt[] = "nxx";
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 3c29288f88a..9b54c1f104b 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -25704,7 +25704,7 @@ void Player::HandleFall(MovementInfo const& movementInfo)
if (damageperc > 0)
{
uint32 damage = (uint32)(damageperc * GetMaxHealth()*sWorld->getRate(RATE_DAMAGE_FALL));
-
+
if (GetCommandStatus(CHEAT_GOD))
damage = 0;
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 3e19a5f0420..a00a9596f91 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -11311,9 +11311,35 @@ bool Unit::IsInFeralForm() const
bool Unit::IsInDisallowedMountForm() const
{
- ShapeshiftForm form = GetShapeshiftForm();
- return form != FORM_NONE && form != FORM_BATTLESTANCE && form != FORM_BERSERKERSTANCE && form != FORM_DEFENSIVESTANCE &&
- form != FORM_SHADOW && form != FORM_STEALTH && form != FORM_UNDEAD;
+ if (ShapeshiftForm form = GetShapeshiftForm())
+ {
+ SpellShapeshiftFormEntry const* shapeshift = sSpellShapeshiftFormStore.LookupEntry(form);
+ if (!shapeshift)
+ return true;
+
+ if (!(shapeshift->flags1 & 0x1))
+ return true;
+ }
+
+ if (GetDisplayId() == GetNativeDisplayId())
+ return false;
+
+ CreatureDisplayInfoEntry const* display = sCreatureDisplayInfoStore.LookupEntry(GetDisplayId());
+ if (!display)
+ return true;
+
+ CreatureDisplayInfoExtraEntry const* displayExtra = sCreatureDisplayInfoExtraStore.LookupEntry(display->ExtraId);
+ if (!displayExtra)
+ return true;
+
+ CreatureModelDataEntry const* model = sCreatureModelDataStore.LookupEntry(display->ModelId);
+ ChrRacesEntry const* race = sChrRacesStore.LookupEntry(displayExtra->Race);
+
+ if (model && !(model->Flags & 0x80))
+ if (race && !(race->Flags & 0x4))
+ return true;
+
+ return false;
}
/*#######################################
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 47b9e840504..b49fc6a7b26 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -5219,6 +5219,8 @@ void ObjectMgr::LoadGossipText()
gText.Options[i].Text_0 = fields[cic++].GetString();
gText.Options[i].Text_1 = fields[cic++].GetString();
+ gText.Options[i].BroadcastTextID = fields[cic++].GetUInt32(); // Need for correct loading order
+
gText.Options[i].Language = fields[cic++].GetUInt8();
gText.Options[i].Probability = fields[cic++].GetFloat();
diff --git a/src/server/game/Handlers/NPCHandler.h b/src/server/game/Handlers/NPCHandler.h
index 8aa34eaafa7..7210d9a53b5 100644
--- a/src/server/game/Handlers/NPCHandler.h
+++ b/src/server/game/Handlers/NPCHandler.h
@@ -31,6 +31,7 @@ struct GossipTextOption
{
std::string Text_0;
std::string Text_1;
+ uint32 BroadcastTextID;
uint32 Language;
float Probability;
QEmote Emotes[MAX_GOSSIP_TEXT_EMOTES];
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index 6c79d66b9ca..c9e2a5acd7a 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -387,7 +387,7 @@ class ItemScript : public ScriptObject
// Called when the item expires (is destroyed).
virtual bool OnExpire(Player* /*player*/, ItemTemplate const* /*proto*/) { return false; }
-
+
// Called when the item is destroyed.
virtual bool OnRemove(Player* /*player*/, Item* /*item*/) { return false; }
};
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index a1339f73119..b958adb0d6d 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -6036,7 +6036,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
}
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
- uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC | PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS;
+ uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC;
uint32 procEx = (crit ? PROC_EX_CRITICAL_HIT : PROC_EX_NORMAL_HIT) | PROC_EX_INTERNAL_HOT;
// ignore item heals
if (!haveCastItem)
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index cbc245ba967..e4f8516839f 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -787,42 +787,61 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr
bool hasFamilyMask = false;
- /* Check Periodic Auras
+ /**
- *Dots can trigger if spell has no PROC_FLAG_SUCCESSFUL_NEGATIVE_MAGIC_SPELL
- nor PROC_FLAG_TAKEN_POSITIVE_MAGIC_SPELL
+ * @brief Check auras procced by periodics
- *Only Hots can trigger if spell has PROC_FLAG_TAKEN_POSITIVE_MAGIC_SPELL
+ *Only damaging Dots can proc auras with PROC_FLAG_TAKEN_DAMAGE
- *Only dots can trigger if spell has both positivity flags or PROC_FLAG_SUCCESSFUL_NEGATIVE_MAGIC_SPELL
+ *Both Dots and hots can proc if ONLY has PROC_FLAG_DONE_PERIODIC or PROC_FLAG_TAKEN_PERIODIC. Such auras need support in Unit::HandleAuraProc.
+
+ *Only Dots can proc auras with PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG or PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
+
+ *Only Hots can proc auras with PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS or PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
+
+ *Only Dots can proc auras with PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG or PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG
+
+ *Only Hots can proc auras with PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS or PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS
+
+ * @param procSpell the spell proccing the aura
+ * @param procFlags proc_flags of spellProc
+ * @param procExtra proc_EX of procSpell
+ * @param EventProcFlag proc_flags of aura to be procced
- *Aura has to have PROC_FLAG_TAKEN_POSITIVE_MAGIC_SPELL or spellfamily specified to trigger from Hot
*/
- if (procFlags & PROC_FLAG_DONE_PERIODIC)
+ /// Quick Check - If PROC_FLAG_TAKEN_DAMAGE is set for aura and procSpell dealt damage, proc no matter what kind of spell that deals the damage.
+ if (procFlags & PROC_FLAG_TAKEN_DAMAGE && EventProcFlag & PROC_FLAG_TAKEN_DAMAGE)
+ return true;
+
+ /// Any aura that has only PROC_FLAG_DONE_PERIODIC or PROC_FLAG_TAKEN_PERIODIC should always proc, if procSpell is correct or not is checked in Unit::HandleAuraProc
+ if (EventProcFlag == PROC_FLAG_DONE_PERIODIC || EventProcFlag == PROC_FLAG_TAKEN_PERIODIC)
+ return true;
+
+ if (procFlags & PROC_FLAG_DONE_PERIODIC && EventProcFlag & PROC_FLAG_DONE_PERIODIC)
{
- if (EventProcFlag & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG)
+ /// Aura must have positive procflags for a HOT to proc
+ if (procExtra & PROC_EX_INTERNAL_HOT)
{
- if (!(procExtra & PROC_EX_INTERNAL_DOT))
+ if (!(EventProcFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS)))
return false;
}
- else if (procExtra & PROC_EX_INTERNAL_HOT)
- procExtra |= PROC_EX_INTERNAL_REQ_FAMILY;
- else if (EventProcFlag & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS)
+ /// Aura must have negative procflags for a DOT to proc
+ else if (!(EventProcFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG)))
return false;
}
- if (procFlags & PROC_FLAG_TAKEN_PERIODIC)
+ if (procFlags & PROC_FLAG_TAKEN_PERIODIC && EventProcFlag & PROC_FLAG_TAKEN_PERIODIC)
{
- if (EventProcFlag & PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS)
+ /// Aura must have positive procflags for a HOT to proc
+ if (procExtra & PROC_EX_INTERNAL_HOT)
{
- if (!(procExtra & PROC_EX_INTERNAL_DOT))
+ if (!(EventProcFlag & (PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS)))
return false;
}
- else if (procExtra & PROC_EX_INTERNAL_HOT)
- procExtra |= PROC_EX_INTERNAL_REQ_FAMILY;
- else if (EventProcFlag & PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_POS)
+ /// Aura must have negative procflags for a DOT to proc
+ else if (!(EventProcFlag & (PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG | PROC_FLAG_TAKEN_SPELL_NONE_DMG_CLASS_NEG)))
return false;
}
// Trap casts are active by default
@@ -2989,15 +3008,9 @@ void SpellMgr::LoadSpellInfoCorrections()
switch (spellInfo->Id)
{
- case 42730: // Woe Strike
- spellInfo->Effects[EFFECT_1].TriggerSpell = 42739;
- break;
case 42436: // Drink! (Brewfest)
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
break;
- case 59735: // Woe Strike
- spellInfo->Effects[EFFECT_1].TriggerSpell = 59736;
- break;
case 52611: // Summon Skeletons
case 52612: // Summon Skeletons
spellInfo->Effects[EFFECT_0].MiscValueB = 64;
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index 1359b9f2002..b1a3d982409 100644
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -691,7 +691,7 @@ class SpellMgr
// SpellInfo object management
SpellInfo const* GetSpellInfo(uint32 spellId) const { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : NULL; }
// Use this only with 100% valid spellIds
- SpellInfo const* EnsureSpellInfo(uint32 spellId) const
+ SpellInfo const* EnsureSpellInfo(uint32 spellId) const
{
ASSERT(spellId < GetSpellInfoStoreSize());
SpellInfo const* spellInfo = mSpellInfoMap[spellId];
diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp
index 2aa78964ffd..e556854c2ab 100644
--- a/src/server/scripts/Commands/cs_gobject.cpp
+++ b/src/server/scripts/Commands/cs_gobject.cpp
@@ -166,7 +166,11 @@ public:
// fill the gameobject data and save to the db
object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMgr().GetPhaseMaskForSpawn());
+ // delete the old object and do a clean load from DB with a fresh new GameObject instance.
+ // this is required to avoid weird behavior and memory leaks
+ delete object;
+ object = new GameObject();
// this will generate a new guid if the object is in an instance
if (!object->LoadGameObjectFromDB(guidLow, map))
{
@@ -209,6 +213,13 @@ public:
uint32 objectId = atoi(id);
+ if (!sObjectMgr->GetGameObjectTemplate(objectId))
+ {
+ handler->PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST, objectId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
player->SummonGameObject(objectId, x, y, z, ang, 0, 0, rot2, rot3, spawntm);
return true;
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index 37e7177cbc6..e1821c69095 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -127,8 +127,8 @@ public:
int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS;
int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS;
- handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gy, gx);
- handler->PSendSysMessage("gridloc [%i, %i]", gx, gy);
+ handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gx, gy);
+ handler->PSendSysMessage("gridloc [%i, %i]", gy, gx);
// calculate navmesh tile location
dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId());
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index 98b1f688867..b099a8e21de 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -476,7 +476,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -524,7 +524,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -569,7 +569,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -614,7 +614,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -659,7 +659,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
index 31c565e5be2..3541ad0f1a3 100644
--- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_prince_taldaram.cpp
@@ -286,8 +286,8 @@ class npc_prince_taldaram_flame_sphere : public CreatureScript
struct npc_prince_taldaram_flame_sphereAI : public ScriptedAI
{
- npc_prince_taldaram_flame_sphereAI(Creature* creature) : ScriptedAI(creature)
- {
+ npc_prince_taldaram_flame_sphereAI(Creature* creature) : ScriptedAI(creature)
+ {
_flameSphereTargetGUID = 0;
}
diff --git a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp
index 1281d40fe5c..916f60bd78a 100644
--- a/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp
@@ -438,7 +438,7 @@ class npc_watcher_gashra : public CreatureScript
_events.ScheduleEvent(EVENT_WEB_WRAP_GASHRA, 11000);
_events.ScheduleEvent(EVENT_INFECTED_BITE_GASHRA, 4000);
}
-
+
void JustDied(Unit* /*killer*/) OVERRIDE
{
Creature* krikthir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KRIKTHIR_THE_GATEWATCHER));
@@ -511,7 +511,7 @@ class npc_watcher_narjil : public CreatureScript
_events.ScheduleEvent(EVENT_INFECTED_BITE_NARJIL, 4000);
_events.ScheduleEvent(EVENT_BINDING_WEBS, 17000);
}
-
+
void JustDied(Unit* /*killer*/) OVERRIDE
{
Creature* krikthir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_KRIKTHIR_THE_GATEWATCHER));
@@ -600,7 +600,7 @@ class npc_watcher_silthik : public CreatureScript
{
if (!UpdateVictim())
return;
-
+
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
index 2091b82e20c..762277ec4fa 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
@@ -70,15 +70,13 @@ enum Events
EVENT_TRIGGER,
EVENT_PHASE,
- EVENT_MORTAL_WOUND,
+ EVENT_MORTAL_WOUND
};
enum Spells
{
SPELL_FROST_BOLT = 28478,
- H_SPELL_FROST_BOLT = 55802,
SPELL_FROST_BOLT_AOE = 28479,
- H_SPELL_FROST_BOLT_AOE = 55807,
SPELL_SHADOW_FISURE = 27810,
SPELL_VOID_BLAST = 27812,
SPELL_MANA_DETONATION = 27819,
@@ -122,7 +120,7 @@ enum Spells
// Abomination spells
SPELL_FRENZY = 28468,
- SPELL_MORTAL_WOUND = 28467,
+ SPELL_MORTAL_WOUND = 28467
};
enum Creatures
@@ -133,7 +131,7 @@ enum Creatures
NPC_ICECROWN = 16441 // Guardians of Icecrown
};
-const Position Pos[12] =
+Position const Pos[12] =
{
{3783.272705f, -5062.697266f, 143.711203f, 3.617599f}, //LEFT_FAR
{3730.291260f, -5027.239258f, 143.956909f, 4.461900f}, //LEFT_MIDDLE
@@ -146,13 +144,13 @@ const Position Pos[12] =
{3732.02f, -5028.53f, 143.92f, 4.49f}, //WINDOW_PORTAL02
{3687.571777f, -5126.831055f, 142.017807f, 0.604023f}, //RIGHT_FAR
{3707.990733f, -5151.450195f, 142.032562f, 1.376855f}, //RIGHT_MIDDLE
- {3782.76f, -5062.97f, 143.79f, 3.82f}, //WINDOW_PORTAL03
+ {3782.76f, -5062.97f, 143.79f, 3.82f} //WINDOW_PORTAL03
};
//creatures in corners
//Unstoppable Abominations
#define MAX_ABOMINATIONS 21
-const Position PosAbominations[MAX_ABOMINATIONS] =
+Position const PosAbominations[MAX_ABOMINATIONS] =
{
{3755.52f, -5155.22f, 143.480f, 2.0f},
{3744.35f, -5164.03f, 143.590f, 2.00f},
@@ -174,12 +172,12 @@ const Position PosAbominations[MAX_ABOMINATIONS] =
{3669.74f, -5149.63f, 143.678f, 0.528643f},
{3695.53f, -5169.53f, 143.671f, 2.11908f},
{3701.98f, -5166.51f, 143.395f, 1.24257f},
- {3709.62f, -5169.15f, 143.576f, 5.97695f},
+ {3709.62f, -5169.15f, 143.576f, 5.97695f}
};
//Soldiers of the Frozen Wastes
#define MAX_WASTES 49
-const Position PosWastes[MAX_WASTES] =
+Position const PosWastes[MAX_WASTES] =
{
{3754.41f, -5147.24f, 143.204f, 2.0f},
{3754.68f, -5156.17f, 143.418f, 2.0f},
@@ -229,12 +227,12 @@ const Position PosWastes[MAX_WASTES] =
{3708.53f, -5172.19f, 143.573f, 3.26575f},
{3712.49f, -5167.62f, 143.657f, 5.63295f},
{3704.89f, -5161.84f, 143.239f, 5.63295f},
- {3695.66f, -5164.63f, 143.674f, 1.54416f},
+ {3695.66f, -5164.63f, 143.674f, 1.54416f}
};
//Soul Weavers
#define MAX_WEAVERS 7
-const Position PosWeavers[MAX_WEAVERS] =
+Position const PosWeavers[MAX_WEAVERS] =
{
{3752.45f, -5168.35f, 143.562f, 1.6094f},
{3772.2f, -5070.04f, 143.329f, 1.93686f},
@@ -242,7 +240,7 @@ const Position PosWeavers[MAX_WEAVERS] =
{3689.05f, -5055.7f, 143.172f, 6.09554f},
{3649.45f, -5093.17f, 143.299f, 2.51805f},
{3659.7f, -5144.49f, 143.363f, 4.08806f},
- {3704.71f, -5175.96f, 143.597f, 3.36549f},
+ {3704.71f, -5175.96f, 143.597f, 3.36549f}
};
// predicate function to select not charmed target
@@ -278,9 +276,6 @@ public:
std::map<uint64, float> chained;
- uint64 PortalsGUID[4];
- uint64 KTTriggerGUID;
-
SummonList spawns; // adds spawn by the trigger. kept in separated list (i.e. not in summons)
void ResetPlayerScale()
@@ -299,36 +294,29 @@ public:
{
_Reset();
- PortalsGUID[0] = PortalsGUID[1] = PortalsGUID[2] = PortalsGUID[3] = 0;
- KTTriggerGUID = 0;
-
me->setFaction(35);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
ResetPlayerScale();
spawns.DespawnAll();
- FindGameObjects();
-
instance->SetData(DATA_ABOMINATION_KILLED, 0);
- if (GameObject* pKTTrigger = me->GetMap()->GetGameObject(KTTriggerGUID))
+ if (GameObject* trigger = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_TRIGGER)))
{
- pKTTrigger->ResetDoorOrButton();
- pKTTrigger->SetPhaseMask(1, true);
+ trigger->ResetDoorOrButton();
+ trigger->SetPhaseMask(1, true);
}
for (uint8 i = 0; i <= 3; ++i)
{
- if (GameObject* pPortal = me->GetMap()->GetGameObject(PortalsGUID[i]))
- {
- if (!((pPortal->getLootState() == GO_READY) || (pPortal->getLootState() == GO_NOT_READY)))
- pPortal->ResetDoorOrButton();
- }
+ if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_PORTAL01 + i)))
+ if (!((portal->getLootState() == GO_READY) || (portal->getLootState() == GO_NOT_READY)))
+ portal->ResetDoorOrButton();
}
nGuardiansOfIcecrownCount = 0;
- uiGuardiansOfIcecrownTimer = 5000; //5 seconds for summoning each Guardian of Icecrown in phase 3
+ uiGuardiansOfIcecrownTimer = 5000; // 5 seconds for summoning each Guardian of Icecrown in phase 3
Phase = 0;
nAbomination = 0;
@@ -353,11 +341,10 @@ public:
me->setFaction(uiFaction);
_EnterCombat();
- FindGameObjects();
for (uint8 i = 0; i <= 3; ++i)
{
- if (GameObject* pPortal = me->GetMap()->GetGameObject(PortalsGUID[i]))
- pPortal->ResetDoorOrButton();
+ if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_PORTAL01 + i)))
+ portal->ResetDoorOrButton();
}
DoCast(me, SPELL_KELTHUZAD_CHANNEL, false);
Talk(SAY_SUMMON_MINIONS);
@@ -372,15 +359,6 @@ public:
events.ScheduleEvent(EVENT_PHASE, 228000);
}
- void FindGameObjects()
- {
- PortalsGUID[0] = instance->GetData64(DATA_KELTHUZAD_PORTAL01);
- PortalsGUID[1] = instance->GetData64(DATA_KELTHUZAD_PORTAL02);
- PortalsGUID[2] = instance->GetData64(DATA_KELTHUZAD_PORTAL03);
- PortalsGUID[3] = instance->GetData64(DATA_KELTHUZAD_PORTAL04);
- KTTriggerGUID = instance->GetData64(DATA_KELTHUZAD_TRIGGER);
- }
-
void UpdateAI(uint32 diff) OVERRIDE
{
if (!UpdateVictim())
@@ -419,8 +397,8 @@ public:
events.PopEvent();
break;
case EVENT_TRIGGER:
- if (GameObject* pKTTrigger = me->GetMap()->GetGameObject(KTTriggerGUID))
- pKTTrigger->SetPhaseMask(2, true);
+ if (GameObject* trigger = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_TRIGGER)))
+ trigger->SetPhaseMask(2, true);
events.PopEvent();
break;
case EVENT_PHASE:
@@ -461,11 +439,9 @@ public:
for (uint8 i = 0; i <= 3; ++i)
{
- if (GameObject* pPortal = me->GetMap()->GetGameObject(PortalsGUID[i]))
- {
- if (pPortal->getLootState() == GO_READY)
- pPortal->UseDoorOrButton();
- }
+ if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_PORTAL01 + i)))
+ if (portal->getLootState() == GO_READY)
+ portal->UseDoorOrButton();
}
}
}
@@ -474,8 +450,8 @@ public:
if (uiGuardiansOfIcecrownTimer <= diff)
{
/// @todo Add missing text
- if (Creature* pGuardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)]))
- pGuardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2);
+ if (Creature* guardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)]))
+ guardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2);
++nGuardiansOfIcecrownCount;
uiGuardiansOfIcecrownTimer = 5000;
}
@@ -490,11 +466,11 @@ public:
switch (eventId)
{
case EVENT_BOLT:
- DoCastVictim(RAID_MODE(SPELL_FROST_BOLT, H_SPELL_FROST_BOLT));
+ DoCastVictim(SPELL_FROST_BOLT);
events.RepeatEvent(urand(5000, 10000));
break;
case EVENT_NOVA:
- DoCastAOE(RAID_MODE(SPELL_FROST_BOLT_AOE, H_SPELL_FROST_BOLT_AOE));
+ DoCastAOE(SPELL_FROST_BOLT_AOE);
events.RepeatEvent(urand(15000, 30000));
break;
case EVENT_CHAIN:
@@ -666,7 +642,7 @@ public:
if (!instance || instance->IsEncounterInProgress() || instance->GetBossState(BOSS_KELTHUZAD) == DONE)
return false;
- Creature* pKelthuzad = Unit::GetCreature(*player, instance->GetData64(DATA_KELTHUZAD));
+ Creature* pKelthuzad = ObjectAccessor::GetCreature(*player, instance->GetData64(DATA_KELTHUZAD));
if (!pKelthuzad)
return false;
@@ -675,7 +651,7 @@ public:
return false;
pKelthuzadAI->AttackStart(player);
- if (GameObject* trigger = instance->instance->GetGameObject(instance->GetData64(DATA_KELTHUZAD_TRIGGER)))
+ if (GameObject* trigger = ObjectAccessor::GetGameObject(*player, instance->GetData64(DATA_KELTHUZAD_TRIGGER)))
{
if (trigger->getLootState() == GO_READY)
trigger->UseDoorOrButton();
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
index cc37dde57dd..fe29f4e9f7c 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
@@ -18,28 +18,25 @@
/* ScriptData
SDName: Boss_Ingvar_The_Plunderer
SD%Complete: 95
-SDComment: Some Problems with Annhylde Movement, Blizzlike Timers (just shadow axe summon needs a new timer)
-SDCategory: Udgarde Keep
+SDComment: Blizzlike Timers (just shadow axe summon needs a new timer)
+SDCategory: Utgarde Keep
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
#include "utgarde_keep.h"
enum Yells
{
- // Ingvar (Human)
- SAY_AGGRO_1 = 0,
- SAY_SLAY_1 = 1,
- SAY_DEATH_1 = 2,
-
- // Ingvar (Undead)
- SAY_AGGRO_2 = 3,
- SAY_SLAY_2 = 4,
- SAY_DEATH_2 = 5,
+ // Ingvar (Human/Undead)
+ SAY_AGGRO = 0,
+ SAY_SLAY = 1,
+ SAY_DEATH = 2,
// Annhylde The Caller
- YELL_RESURRECT = 0
+ YELL_RESURRECT = 0
};
enum Events
@@ -83,8 +80,10 @@ enum Spells
SPELL_DARK_SMASH = 42723,
SPELL_DREADFUL_ROAR = 42729,
SPELL_WOE_STRIKE = 42730,
+ SPELL_WOE_STRIKE_EFFECT = 42739,
SPELL_SHADOW_AXE_SUMMON = 42748,
+ SPELL_SHADOW_AXE_PERIODIC_DAMAGE = 42750,
// Spells for Annhylde
SPELL_SCOURG_RESURRECTION_HEAL = 42704, // Heal Max + DummyAura
@@ -105,16 +104,14 @@ class boss_ingvar_the_plunderer : public CreatureScript
struct boss_ingvar_the_plundererAI : public BossAI
{
- boss_ingvar_the_plundererAI(Creature* creature) : BossAI(creature, DATA_INGVAR)
- {
- _isUndead = false;
- }
+ boss_ingvar_the_plundererAI(Creature* creature) : BossAI(creature, DATA_INGVAR) { }
void Reset() OVERRIDE
{
- _isUndead = false;
+ if (me->GetEntry() != NPC_INGVAR)
+ me->UpdateEntry(NPC_INGVAR);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
_Reset();
events.SetPhase(PHASE_HUMAN);
@@ -132,12 +129,12 @@ class boss_ingvar_the_plunderer : public CreatureScript
me->RemoveAllAuras();
DoCast(me, SPELL_INGVAR_FEIGN_DEATH, true);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
events.SetPhase(PHASE_EVENT);
events.ScheduleEvent(EVENT_SUMMON_BANSHEE, 3 * IN_MILLISECONDS, 0, PHASE_EVENT);
- Talk(SAY_DEATH_1);
+ Talk(SAY_DEATH);
}
if (events.IsInPhase(PHASE_EVENT))
@@ -152,26 +149,22 @@ class boss_ingvar_the_plunderer : public CreatureScript
void StartZombiePhase()
{
- _isUndead = true;
me->RemoveAura(SPELL_INGVAR_FEIGN_DEATH);
- DoCast(me, SPELL_INGVAR_TRANSFORM, true); /// @todo: should be death persistent
+ DoCast(me, SPELL_INGVAR_TRANSFORM, true);
+ me->UpdateEntry(NPC_INGVAR_UNDEAD);
events.ScheduleEvent(EVENT_JUST_TRANSFORMED, 2 * IN_MILLISECONDS, 0, PHASE_EVENT);
-
- Talk(SAY_AGGRO_2);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
-
- if (!_isUndead)
- Talk(SAY_AGGRO_1);
+ Talk(SAY_AGGRO);
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
_JustDied();
- Talk(SAY_DEATH_2);
+ Talk(SAY_DEATH);
}
void ScheduleSecondPhase()
@@ -183,9 +176,10 @@ class boss_ingvar_the_plunderer : public CreatureScript
events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD);
}
- void KilledUnit(Unit* /*victim*/) OVERRIDE
+ void KilledUnit(Unit* who) OVERRIDE
{
- Talk(_isUndead ? SAY_SLAY_1 : SAY_SLAY_2);
+ if (who->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -220,7 +214,7 @@ class boss_ingvar_the_plunderer : public CreatureScript
events.ScheduleEvent(EVENT_SMASH, urand(12, 16)*IN_MILLISECONDS, 0, PHASE_HUMAN);
break;
case EVENT_JUST_TRANSFORMED:
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
DoZoneInCombat();
ScheduleSecondPhase();
return;
@@ -241,20 +235,18 @@ class boss_ingvar_the_plunderer : public CreatureScript
events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10, 14)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
break;
case EVENT_SHADOW_AXE:
- if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1))
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
DoCast(target, SPELL_SHADOW_AXE_SUMMON);
-
events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD);
break;
+ default:
+ break;
}
}
if (!events.IsInPhase(PHASE_EVENT))
DoMeleeAttackIfReady();
}
-
- private:
- bool _isUndead;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
@@ -279,12 +271,8 @@ class npc_annhylde_the_caller : public CreatureScript
{
_events.Reset();
- //! HACK: Creature's can't have MOVEMENTFLAG_FLYING
- me->SetHover(true);
-
me->GetPosition(x, y, z);
- DoTeleportTo(x+1, y, z+30);
- me->GetMotionMaster()->MovePoint(1, x, y, z+15);
+ me->GetMotionMaster()->MovePoint(1, x, y, z - 15.0f);
}
void MovementInform(uint32 type, uint32 id) OVERRIDE
@@ -339,7 +327,7 @@ class npc_annhylde_the_caller : public CreatureScript
ingvar->AI()->DoAction(ACTION_START_PHASE_2);
}
- me->GetMotionMaster()->MovePoint(2, x+1, y, z+30);
+ me->GetMotionMaster()->MovePoint(2, x, y, z + 15.0f);
break;
default:
break;
@@ -359,52 +347,112 @@ class npc_annhylde_the_caller : public CreatureScript
}
};
-enum ShadowAxe
-{
- SPELL_SHADOW_AXE_DAMAGE = 42750,
- H_SPELL_SHADOW_AXE_DAMAGE = 59719,
- POINT_TARGET = 28
-};
-
class npc_ingvar_throw_dummy : public CreatureScript
{
-public:
- npc_ingvar_throw_dummy() : CreatureScript("npc_ingvar_throw_dummy") { }
+ public:
+ npc_ingvar_throw_dummy() : CreatureScript("npc_ingvar_throw_dummy") { }
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_ingvar_throw_dummyAI(creature);
- }
+ struct npc_ingvar_throw_dummyAI : public ScriptedAI
+ {
+ npc_ingvar_throw_dummyAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset() OVERRIDE
+ {
+ me->SetReactState(REACT_PASSIVE);
+
+ if (Creature* target = me->FindNearestCreature(NPC_THROW_TARGET, 200.0f))
+ {
+ float x, y, z;
+ target->GetPosition(x, y, z);
+ me->GetMotionMaster()->MoveCharge(x, y, z);
+ target->DespawnOrUnsummon();
+ }
+ else
+ me->DespawnOrUnsummon();
+ }
+
+ void MovementInform(uint32 type, uint32 id) OVERRIDE
+ {
+ if (type == EFFECT_MOTION_TYPE && id == EVENT_CHARGE)
+ {
+ me->CastSpell(me, SPELL_SHADOW_AXE_PERIODIC_DAMAGE, true);
+ me->DespawnOrUnsummon(10000);
+ }
+ }
+ };
- struct npc_ingvar_throw_dummyAI : public ScriptedAI
- {
- npc_ingvar_throw_dummyAI(Creature* creature) : ScriptedAI(creature)
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
+ return new npc_ingvar_throw_dummyAI(creature);
}
+};
+
+// 42912 - Summon Banshee
+class spell_ingvar_summon_banshee : public SpellScriptLoader
+{
+ public:
+ spell_ingvar_summon_banshee() : SpellScriptLoader("spell_ingvar_summon_banshee") { }
- void Reset() OVERRIDE
+ class spell_ingvar_summon_banshee_SpellScript : public SpellScript
{
- if (Creature* target = me->FindNearestCreature(NPC_THROW_TARGET, 50.0f))
+ PrepareSpellScript(spell_ingvar_summon_banshee_SpellScript);
+
+ void SetDest(SpellDestination& dest)
{
- float x, y, z;
- target->GetPosition(x, y, z);
- me->GetMotionMaster()->MoveCharge(x, y, z, 42.0f, POINT_TARGET);
- target->DisappearAndDie();
+ dest.RelocateOffset({ 0.0f, 0.0f, 30.0f, 0.0f });
}
- else
- me->DisappearAndDie();
+
+ void Register() OVERRIDE
+ {
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_ingvar_summon_banshee_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_BACK);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_ingvar_summon_banshee_SpellScript();
}
+};
- void MovementInform(uint32 type, uint32 id) OVERRIDE
+// 42730, 59735 - Woe Strike
+class spell_ingvar_woe_strike : public SpellScriptLoader
+{
+ public:
+ spell_ingvar_woe_strike() : SpellScriptLoader("spell_ingvar_woe_strike") { }
+
+ class spell_ingvar_woe_strike_AuraScript : public AuraScript
{
- if (type == EFFECT_MOTION_TYPE && id == POINT_TARGET)
+ PrepareAuraScript(spell_ingvar_woe_strike_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WOE_STRIKE_EFFECT))
+ return false;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ return eventInfo.GetHealInfo()->GetHeal();
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastSpell(eventInfo.GetActor(), SPELL_WOE_STRIKE_EFFECT, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
{
- DoCast(me, SPELL_SHADOW_AXE_DAMAGE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
- me->DespawnOrUnsummon(10000);
+ DoCheckProc += AuraCheckProcFn(spell_ingvar_woe_strike_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_ingvar_woe_strike_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_PROC_TRIGGER_SPELL);
}
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_ingvar_woe_strike_AuraScript();
}
- };
};
void AddSC_boss_ingvar_the_plunderer()
@@ -412,4 +460,6 @@ void AddSC_boss_ingvar_the_plunderer()
new boss_ingvar_the_plunderer();
new npc_annhylde_the_caller();
new npc_ingvar_throw_dummy();
+ new spell_ingvar_summon_banshee();
+ new spell_ingvar_woe_strike();
}
diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp
index abb14a9cc5d..992f6fdbcfb 100644
--- a/src/server/scripts/Spells/spell_paladin.cpp
+++ b/src/server/scripts/Spells/spell_paladin.cpp
@@ -60,6 +60,8 @@ enum PaladinSpells
SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT = 31790,
SPELL_PALADIN_SANCTIFIED_RETRIBUTION_AURA = 63531,
SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1 = 31869,
+ SPELL_PALADIN_SANCTIFIED_WRATH = 57318,
+ SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1 = 53375,
SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS = 25742,
SPELL_PALADIN_SWIFT_RETRIBUTION_R1 = 53379
};
@@ -227,6 +229,52 @@ class spell_pal_aura_mastery_immune : public SpellScriptLoader
}
};
+// 31884 - Avenging Wrath
+class spell_pal_avenging_wrath : public SpellScriptLoader
+{
+ public:
+ spell_pal_avenging_wrath() : SpellScriptLoader("spell_pal_avenging_wrath") { }
+
+ class spell_pal_avenging_wrath_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_pal_avenging_wrath_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_SANCTIFIED_WRATH)
+ || !sSpellMgr->GetSpellInfo(SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1))
+ return false;
+ return true;
+ }
+
+ void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+ if (AuraEffect const* aurEff = target->GetAuraEffectOfRankedSpell(SPELL_PALADIN_SANCTIFIED_WRATH_TALENT_R1, EFFECT_2))
+ {
+ int32 basepoints = aurEff->GetAmount();
+ target->CastCustomSpell(target, SPELL_PALADIN_SANCTIFIED_WRATH, &basepoints, &basepoints, NULL, true, NULL, aurEff);
+ }
+ }
+
+ void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->RemoveAurasDueToSpell(SPELL_PALADIN_SANCTIFIED_WRATH);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_pal_avenging_wrath_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_pal_avenging_wrath_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_pal_avenging_wrath_AuraScript();
+ }
+};
+
// 53651 - Beacon of Light
class spell_pal_beacon_of_light : public SpellScriptLoader
{
@@ -288,6 +336,7 @@ class spell_pal_beacon_of_light : public SpellScriptLoader
}
};
+
// 37877 - Blessing of Faith
class spell_pal_blessing_of_faith : public SpellScriptLoader
{
@@ -1149,6 +1198,7 @@ void AddSC_paladin_spell_scripts()
//new spell_pal_ardent_defender();
new spell_pal_aura_mastery();
new spell_pal_aura_mastery_immune();
+ new spell_pal_avenging_wrath();
new spell_pal_beacon_of_light();
new spell_pal_blessing_of_faith();
new spell_pal_divine_sacrifice();
diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp
index d1b32570795..b9fd07293cd 100644
--- a/src/server/scripts/Spells/spell_quest.cpp
+++ b/src/server/scripts/Spells/spell_quest.cpp
@@ -2276,6 +2276,46 @@ class spell_q13400_illidan_kill_master : public SpellScriptLoader
}
};
+enum RelicOfTheEarthenRing
+{
+ SPELL_TOTEM_OF_THE_EARTHEN_RING = 66747
+};
+
+// 66744 - Make Player Destroy Totems
+class spell_q14100_q14111_make_player_destroy_totems : public SpellScriptLoader
+{
+ public:
+ spell_q14100_q14111_make_player_destroy_totems() : SpellScriptLoader("spell_q14100_q14111_make_player_destroy_totems") { }
+
+ class spell_q14100_q14111_make_player_destroy_totems_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q14100_q14111_make_player_destroy_totems_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_TOTEM_OF_THE_EARTHEN_RING))
+ return false;
+ return true;
+ }
+
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
+ {
+ if (Player* player = GetHitPlayer())
+ player->CastSpell(player, SPELL_TOTEM_OF_THE_EARTHEN_RING, TRIGGERED_FULL_MASK); // ignore reagent cost, consumed by quest
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q14100_q14111_make_player_destroy_totems_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_q14100_q14111_make_player_destroy_totems_SpellScript();
+ }
+};
+
void AddSC_quest_spell_scripts()
{
new spell_q55_sacred_cleansing();
@@ -2331,4 +2371,5 @@ void AddSC_quest_spell_scripts()
new spell_q12919_gymers_grab();
new spell_q12919_gymers_throw();
new spell_q13400_illidan_kill_master();
+ new spell_q14100_q14111_make_player_destroy_totems();
}
diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp
index d60924a83f9..cc24035b05e 100644
--- a/src/tools/mmaps_generator/MapBuilder.cpp
+++ b/src/tools/mmaps_generator/MapBuilder.cpp
@@ -553,7 +553,9 @@ namespace MMAP
config.borderSize = config.walkableRadius + 3;
config.maxEdgeLen = VERTEX_PER_TILE + 1; // anything bigger than tileSize
config.walkableHeight = m_bigBaseUnit ? 3 : 6;
- config.walkableClimb = m_bigBaseUnit ? 2 : 4; // keep less than walkableHeight
+ // a value >= 3|6 allows npcs to walk over some fences
+ // a value >= 4|8 allows npcs to walk over all fences
+ config.walkableClimb = m_bigBaseUnit ? 4 : 8;
config.minRegionArea = rcSqr(60);
config.mergeRegionArea = rcSqr(50);
config.maxSimplificationError = 1.8f; // eliminates most jagged edges (tiny polygons)
diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h
index 33f45a86549..86a6db2077c 100644
--- a/src/tools/mmaps_generator/MapBuilder.h
+++ b/src/tools/mmaps_generator/MapBuilder.h
@@ -61,7 +61,7 @@ namespace MMAP
class MapBuilder
{
public:
- MapBuilder(float maxWalkableAngle = 55.f,
+ MapBuilder(float maxWalkableAngle = 70.f,
bool skipLiquid = false,
bool skipContinents = false,
bool skipJunkMaps = true,
diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp
index 1df24cfa332..d88ab8ca16d 100644
--- a/src/tools/mmaps_generator/PathGenerator.cpp
+++ b/src/tools/mmaps_generator/PathGenerator.cpp
@@ -242,7 +242,7 @@ int finish(const char* message, int returnValue)
int main(int argc, char** argv)
{
int threads = 3, mapnum = -1;
- float maxAngle = 55.0f;
+ float maxAngle = 70.0f;
int tileX = -1, tileY = -1;
bool skipLiquid = false,
skipContinents = false,